welcome to xlongwei.com

欢迎大家一起学习、交流、分享


QQ群:162333776 邮箱:admin@xlongwei.com

jedis sharded 数据复制


分类 Java   关键字 分享   标签 java   linux   spring   redis   发布 hongwei  1471850185609
注意 转载须保留原文链接,译文链接,作者译者等信息。  
redis 分片模式,出现单点故障时需要重新分片,而扩展节点时则需要复制数据,然后再替换节点。这里的复制数据不同于主从复制,而是将redis的某些db的数据复制到另一个redis实例的某些db之中。

复制数据的命令
#复制单个节点数据
mvn exec:java -Dexec.mainClass=com.itecheast.ite.domain.util.MyShardedRedisCacheManager -Dexec.args="127.0.0.1:6379:0 127.0.0.1:6379:1"
#需要提供访问密码
mvn exec:java -Dexec.mainClass=com.itecheast.ite.domain.util.MyShardedRedisCacheManager -Dexec.args="127.0.0.1:6379:0:pwd 127.0.0.1:6379:1:pwd"
#复制多个节点
mvn exec:java -Dexec.mainClass=com.itecheast.ite.domain.util.MyShardedRedisCacheManager -Dexec.args="127.0.0.1:6379:0 127.0.0.1:6379:8" -Dspan=8
#复制多个节点
mvn exec:java -Dexec.mainClass=com.itecheast.ite.domain.util.MyShardedRedisCacheManager -Dexec.args="127.0.0.1:6379:0-7 127.0.0.1:6379:8-15"

按字节方式复制数据
private static void copy(Jedis from, Jedis to) {
byte[] all = new byte[] {42};
Set<byte[]> keys = from.keys(all);
for(byte[] bk : keys) {
try {
byte[] bv = to.get(bk);
if(bv!=null && bv.length>0) continue;
bv = from.get(bk);
Long ttl = from.ttl(bk);
to.set(bk, bv);
if(ttl!=null&&ttl>0) to.expire(bk, ttl.intValue());
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
System.out.println("redis.db copy finished, from="+desc(from)+", to="+desc(to)+", keys="+keys.size());
}

分片模式的实用划分方式:
节点数:N=1*2*3*4*5……,取连续数的相乘
例如:24=2*3*4
如果有两个redis,则每个redis提供12个db。此时就算其中一个redis挂掉,reshard机制也会自动切换至另一个redis
如果需要扩展至3个节点,则每个节点复制4个db的数据到新节点,然后更新节点配置(原有节点顺序保持不变,新节点原位置替换)
如果再扩展至4个节点,则每个节点复制2个db的数据到新节点即可。
24=1*24=2*12=3*8=4*6=6*4=8*3=12*2=24*1,可以支持redis实例数为:1、2、3、4、6、8、12、24,扩展能力还是非常强的

有时需要计算键key所在的分片
mvn exec:java -Dexec.mainClass=com.itecheast.ite.domain.util.MyShardedRedisCacheTester -Dexec.classpathScope=test -Dexec.args="host:port:1-4"
mvn exec:java -Dexec.mainClass=com.itecheast.ite.domain.util.MyShardedRedisCacheTester -Dexec.classpathScope=test -Dexec.args="host:port:1-4 key-string" -Ddebug