目录
更多技术交流:https://github.com/singgel
java伪装的slave从master获取的数据是redis protocol下的二进制数据,分为
1.RDB数据
2.PSYNC增量数据
Jedis单点有socket的预留接口方法sendCommand,问题,JedisCluster没有这个接口
解决:
1.将二进制数据直接用过CRC16获取到slot
2.根据slot对应的node
3.根据node在获取到Jedis的单点Client
以上同时要兼顾到整个cluster的连接池,不能反复的去创建connection
在做压测的时候,1WOPS时出现slave,只接收了一部分数据,然后掉线
1.java的slave在dump到本地之后的数据,even处理阻塞
2.master的slave的alive时间设置太短
解决:
replicator参数里面有一个选线(Replicator)r.getConfiguration().setDiscardRdbEvent(true);
设置后rdb文件的解析过程将被忽略,更新offset标志位拉取同步最新的command
https://github.com/smartxing/redis-replicator
1 当启动一个slave node的时候,它会发送一个PSYNC命令给master node
2 如果这是slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization
3 开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。
4 slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。
什么时候发生全量同步,什么时候发生增量同步。 比如做数据迁移的时候需要考虑一下,如果在数据迁移中发生了重连,全量rdb重新会同步一份
1.redis什么时候会发生全量复制
a) redis slave首启动或者重启后,连接到master时
b) redis slave进程没重启,但是掉线了,重连后不满足部分复制条件
2.部分复制需要的条件
a) 主从的redis版本>=2.8
b) redis slave进程没有重启,但是掉线了,重连了master(因为slave进程重启的话,run id就没有了)
c) redis slave保存的run id与master当前run id一致 (注:run id并不是pid,slave把它保存在内存中,重启就消失)
d) redis slave掉线期间,master保存在内存的offset可用,也就是master变化不大,被更改的指令都保存在内存
实践
读写分离,redis通常用来做缓存,所以通过redis 复制策略,可以写主读从,减少master压力
主数据库禁止备份,从数据库备份,提升master性能, master挂掉后从slave提升为主
注意 不要直接操作master,不然master会把空的文件同步到slave,那样可能会造成数据全部丢失