问题
ShardingSphere 3.1.0水平分成8张表,分表策略为id%8,这样便有0,1,2,3,4,5,6,7这8张表。
使用的算法:雪花算法
预期结果:每个表中分布的数据接近。
实际结果:数据总是落在0表和1表中。
分析
编写测试代码发现:如果同一毫秒内并发多的情况下,才会有0-7表产生。如果并发很少,则基本落在0-1表。
最后12位是同一毫秒内的自增值,这个可以参考DefaultKeyGenerator(雪花算法)源码:
import io.shardingsphere.core.keygen.DefaultKeyGenerator;
import io.shardingsphere.core.keygen.KeyGenerator;
import org.apache.commons.lang3.RandomUtils;
import java.math.BigInteger;
import java.util.Properties;
public class TestKeyGenerator {
public static void main(String[] args) throws InterruptedException {
KeyGenerator keyGenerator = new DefaultKeyGenerator();
DefaultKeyGenerator.setWorkerId(532L);
// SnowflakeKeyGenerateAlgorithm keyGenerator = new SnowflakeKeyGenerateAlgorithm();
// Properties properties = new Properties();
// properties.setProperty("worker-id", "532");
// keyGenerator.setProps(properties);
// keyGenerator.init();
int i = 0;
while (i++ < 100) {
// sleep some ms to simulate the http request
Thread.sleep(RandomUtils.nextInt(10, 1000));
BigInteger bigInteger = new BigInteger(String.valueOf(keyGenerator.generateKey()));
long currentTimeMs = System.currentTimeMillis();
// to simulate the expression {id % 8}
BigInteger[] result = bigInteger.divideAndRemainder(BigInteger.valueOf(8L));
// the result[1] seems always be 0 or 1
System.out.println(currentTimeMs + ":" + bigInteger + ":" + result[1]);
}
}
}
更近一步的测试发现,如果是对2的n次方(n > 1,比如n=2,3,4,即对4、8163264取余)进行取余时,得到的结果一定是0/1,根本无法进入到剩余的表中。目前还没找到根源在哪里。。。
试了下,最新版本4.1.1中的雪花算法,也有这个问题....
参考
FAQ :: ShardingSphere
ZooKeeper 未授权访问漏洞_微信公众号Bypass-CSDN博客_zookeeper未授权



