携程持久化KV存储挑战Redis,狂省90%成本( 四 )


携程持久化KV存储挑战Redis,狂省90%成本
文章图片

文章图片
图7
而冲突区与同步开始之间的区域是补足区(图7) , 我们通过插入空白数据来进行填补 , 所以对于A和B来说 , 他们之间不一致区域是冲突区和补足区的总和 。而对于冲突的部分 , 我们会记录下两边的差异 , 真有差异发生时 , 参考git解决冲突的思路 , 将数据的选择权交给用户 。
上线该feature后 , 版本的升级就变得比较轻松 , 大部分情况下版本升级只是一次实例的拉出重启拉入 , 实例也是秒级up , 升级过程也基本上对业务做到了透明 。
在解决此问题的同时 , 我们也注意到master/slave数据是对齐的某些情况下也会发生全量同步 , 检查下来发现是pub/sub命令的问题 。
这个命令是哨兵用于订阅服务消息的 , 但Kvrocks的pub/sub是一个写操作 , 这样就会造成持续性的数据写入从而累加rocksdb的Sequence , 这样如果一个slave宕机后恢复 , 还没来得及与master同步却被哨兵写入了一条无关紧要的pub消息 , 累加了Seq从而触发了不必要的全量同步 , 但实际上该功能并非必须 , 所以我们修改Kvrocks处理哨兵pubsub消息的规则 , 不去写之后这个命令只工作在内存中 , 自然不会累加rocksdb的Sequence , 杜绝这种情况全量同步的可能性 。
3、运维治理能力增强水平扩缩容
携程持久化KV存储挑战Redis,狂省90%成本
文章图片

文章图片
图8
在之前的Redis治理演进之路文章中 , 我们介绍了一种新的扩缩容方案来解决Redis集群版本升级和扩缩容的问题(图8) , 参考同样的思路 , 我们继续改造BinlogServer来实现TRocks的集群的水平扩缩容 , 这套方案实际上不仅解决了扩缩容的问题 , 同时也解决了Redis到Redis的数据迁移 , TRocks到TRocks的数据迁移 , Redis与TRocks之间的互相迁移 , 也可以帮助用户平滑的从Redis的访问过渡到TRocks的访问 。
然而相比Redis扩缩容基本不需要考虑内存带宽 , 硬盘带宽太窄 , 而数据迁移的时候流量太大 。由于所有数据最终都需要在新集群上刷盘 , 导致迁移过程中目标集群的磁盘读写会非常大 , 又由于我们都是容器化部署 , 大量的磁盘读写也可能会影响到统一宿主机上的其他无关的应用 , 所以我们调整了TRocks的写入限流设置 , 以避免大量写入影响磁盘性能 , 同时修改了BinlogServer加入了限流功能 , 平缓数据传输的速率 。哨兵多机房部署
为了保证TRocks集群可以跨机房容灾 , 哨兵需要部署在多个机房中 , 目前我们是三机房部署 。如下图(图9):
携程持久化KV存储挑战Redis,狂省90%成本
文章图片

文章图片
图9
在部署的时候 , 遇到了一个问题 , 我们发现哨兵之间经常无法选出leader , 需要等下一个选举周期(6分钟)才能重新选出 , 导致长时间无法确定TRocksmaster 。这个问题本身跟TRocks没有太大关系 , 只是实际使用中对我们故障处理带来了不小麻烦 。
出现无法选出leader的原因是多个哨兵同时发起选举希望成为leader , 导致最终每个哨兵都选择了自己 , 无法达成共识 。查看源码发现官方已经为发起选举前设置了随机的间隔时间(50~100ms) , 但实际操作中发现这个随机间隔反而增加了发生选角失败的可能 , 考虑应该是随机时间太短导致 , 所以我们将随件间隔修改为100~200ms , 同时在哨兵发现master宕机之后就立即发起选举来尽可能规避无法选主的问题 。
五、一些数据
1、性能数据