前言
LightDB分布式数据库通过citus插件实现,插件的使用,让我们操作分布式数据库就如同操作单机数据库一样。它可以帮助实现路由规则,通过分片键的分片值计算hash来绝对数据具体路由到哪张分片表中。但是citus对于我们来说作为一个黑盒产品,就像ShardingProxy。那如何快速路由了,如何将citus路由规则在jdbc中实现了,将jdbc打造成sharding-jdbc那种了?
citus路由原理
简单点:通过一条数据的分片键的分片值去计算hash,最后根据hash来选择分片
1.计算hash值
private static long getHash(String shardValue, List<ShardNode> shardNodeList, String urlKey) {
long hash;
ShardNode shardNode = shardNodeList.get(0);
switch (shardNode.getShardColumnType()) {
case "numeric":
hash = hash_numeric(shardValue);
break;
case "character":
hash = hash_character(shardValue);
break;
case "smallint":
hash = hash_smallint(shardValue);
break;
case "integer":
hash = hash_integer(shardValue);
break;
case "bigint":
hash = hash_bigint(shardValue);
break;
case "text":
hash = hash_text(shardValue);
break;
case "character varying":
hash = hash_character_varying(shardValue);
break;
case "date":
hash = hash_date(shardValue);
break;
default:
throw new IllegalArgumentException("unexpected shardColumnType passed to getShard: " + shardNode.getShardColumnType());
}
return hash;
}
可以看出还要考虑分片键的类型
2.选择shardNode
long hash_uint32 = getHash(shardValue, shardNodeList, urlKey);
long hash = (int) hash_uint32;
int size = shardNodeList.size();
long index = (hash + UINT32_INT) / (UINT32_MAX / size);
boolean _var = getShardNode(shardNodeList, size);
if (_var) {
return shardNodeList.get((int) index);
} else {
for (ShardNode shardNode : shardNodeList) {
if (Math.max(shardNode.getShardMinValue(), hash) == Math.min(hash, shardNode.getShardMaxValue())) {
return shardNode;
}
}
}
之后选择shardeNode(分片键)
3.shardNode之后获取connection
根据shardNode之后,可以获取到dn节点的信息,就像操作单机数据库一样,这样我们可以分片数据来直接连接dn节点。