-
Notifications
You must be signed in to change notification settings - Fork 77
集群实现原理

架构释义:
- 整个部署形态遵从Redis Cluster集群拓扑并引入Predixy作为集群的代理层
- Redis Cluster的group对应一个statfulset,比如XX-0,那么group中的主备将名为XX-0-0和XX-0-1,而在CR对象中的status会动态记录对应group对应的槽位
- Redis实例的底层存储是可选的,结合storageclass可以接入本地盘(empty dir)或者ceph(pvc)等
- 每个Redis Pod具备sidecar exporter镜像,可以流畅接入prometheus
Redis Cluster CRD定义示例

集群的组织过程完全有Operator负责,整个流程是将运维部署过程编码化
以下是几个关键步骤:
- 前台服务通过用户键入的存储大小计算group数量以及单节点的maxmemroy
- 根据group数量创建sts的过程中,会等待所有(group数量*2)的Redis Pod正常提供服务后,此时Pod均是独立且不存在角色,此时调用cluster创建API命令组织X-N-0成为集群
- X-N-1作为slave分别加入集群中对应的group中
集群扩容是个复杂的过程一方面扩容分为横向扩容和纵向扩容,另一方面作为在线扩容如何对线上的影响最小化也是需要考虑的
1. 纵向扩容
- 纵向扩容对在线服务影响是最小的,只有存储需求大小未超过当前group数量*32G(单节点存储上限)
- timestamp,基于数据的修改时间戳,修改时间新的覆盖旧的数据
- 数据类型merge, 比如针对库存信息,A地库存减一,B地库存减二,两边同步之后A地和B地的数据应该是减三,合并两者减一和减二的操作
针对trusted source/timestamp模型,一定需要建立一个冲突数据kv表,(比如trusted source场景,如果B地修改了记录,而A地没修改此记录,那B地可以覆盖A地,即使A地是trusted source) ,对应冲突数据KV表的插入和删除,如果插入和删除不及时,就会有各种各样的误判,导致数据不一致。
举个插入不及时的case: 比如A地和B地进行双向同步,同时修改了同一记录,但A地的binlog解析器因为异常挂起了,导致构建冲突数据KV表数据延迟了,而此时B地的数据就会认为无冲突,直接覆盖了A,即使A地是trusted source,然后A地数据解析恢复后,同步到B地时,因为A是trusted source,就会覆盖B地的数据,最后就是A和B两地各为两边之前的版本,导致数据不一致。
因为goldengate外部文档针对双A机房同步,数据一致性处理描述的比较少,我只能推测到这,基本结论是风险太大,所以otter需要有一种完全可靠的数据一致性方案,这也是本文讨论的重点。
思路:最终一致性
适用场景: A地和B地数据不对等,比如A地为主,写入量比较高,B地有少量的数据写入
单向回环流程:(比如图中以HZ为trusted source站点)
- us->hz同步的数据,会再次进入hz->us队列,形成一次单向回环
- hz->us同步的数据,不会进入us->hz队列(回环终止,保证不进入死循环)
存在的问题:存在同步延迟时,会出现版本丢失高/数据交替性变化
- 比如US同一条记录变更了10个版本,而且很快同步到了HZ,而HZ因为同步数据大,同步延迟,后续单向回环中将10个版本又在US进行了一次重放,导致出现数据交替
- 比如HZ同一条记录变更了10个版本,而且很快同步到了US,而US因为同步延迟,将一个比较早的版本同步到了HZ,后续通过单向回环,将此记录重放到了US,导致之前HZ到US的10个版本丢失.
解决方案:
- 反查数据库同步 (以数据库最新版本同步,解决交替性,比如设置一致性反查数据库延迟阀值为60秒,即当同步过程中发现数据延迟超过了60秒,就会基于PK反查一次数据库,拿到当前最新值进行同步,减少交替性的问题)
- 字段同步 (降低冲突概率)
- 同步效率 (同步越快越好,降低双写导致版本丢失概率,不需要构建冲突数据KV表)
- 同步全局控制 (比如HZ->US和US->HZ一定要一起启动,一起关闭,保证不会出现一边数据一直覆盖另一边,造成比较多的版本丢失)
同步全局控制方案:(分布式Permit)
注意:A,B,C三点状态都正常才允许进行同步(解决数据单向覆盖)。 任何一边的canal不正常工作,都应该停掉整个双向同步,及时性越高越好。
算法描述:
1. 首先定义两个时间概念
- 数据变更时间A :代表业务数据在A地数据库中产生的时间,即图中的时间A
- 数据同步时间B:代表数据变更载入到B地数据库的时间,即图中的时间B
2. 针对每条或者一批数据都记录变更时间A和同步时间B,同时保留历史同步过的数据记录
3. 图中纵轴为时间轴,Aa代表从数据库A同步到数据库B的一个同步过程,Ba代表从数据库B到同步到的数据库A的一个同步过程,每个同步过程在纵轴上会有两个点,分别代表变更时间A和同步时间B.
4. 根据同一时间的定义,在两边数据库的各自同步过程中,以数据库A为例,在数据库B的同步过程找到与Aa有时间交集的批次,比如这里就是Aa 与 (Ba , Bb , Bc)有时间交集
5. 针对步骤4中的批次,根据同一数据的定义,在交集的每个批次中,比如首先拿Aa和Ba的历史同步数据记录,根据同一数据定义进行查找,然后再是Aa和Bb,依次类推。
6. 针对步骤5中找到的同一数据,最后确定为需要进行单向回环的一致性算法的数据。
此方案相比于单向回环方案:减少单向回环同步的数据量,解决A和B地数据对等的case,不过目前开源版本暂未实现。


