-
Notifications
You must be signed in to change notification settings - Fork 81
Zeppelin 迁移扩容设计(一)
Zeppelin以分片的方式将数据存储在不同的Data节点上,每个机器上部署一个或多个Data节点。随着业务数量及容量的变化,不可避免的需要改变集群规模。扩容指有新的Data节点加入集群并分担原有机器的存储任务。对应的,缩容指已有Data节点退出集群,并将其存储压力分摊到其他Data节点上。
无论扩容还是缩容,最终问题都变成分片Partition在Data节点间的迁移。由于Zeppelin的副本方式采取主从模式,Partiton的迁移区分为Master Partition的迁移和Slave Partiton的迁移,两种Partition的迁移应该均衡。
Slave Partition迁移比较简单,目前的实现已经能够支持,所以主要考虑的是Master Partition的迁移。
Master Partition的迁移又可以转化为Slave Partition的迁移和切主两个阶段,所以扩容缩容问题变为切主问题。切主问题指的是原来的主Partition变成从Partition,某个从Partition变成主Parition。为了保证数据正确,新主需要首先将数据与旧主追齐,所以我们又将切主过程分为两个阶段:
- 旧主仍然作为主;新主作为旧主的从同步数据;
- 数据追齐后,旧主停写,切主,新旧主分片角色交换。
这个过程中最大的问题是如何判断数据是否追齐从而进行两个阶段的切换。
- Manager向Meta发送setmaster命令指定Partition的主分片
- Meta收到命令,将指定Partition置为STUCK状态并增加epoch
- Node收到新的元信息,指定Partition状态修改为STUCK并进入阻写状态,等待从的Binlog位置追齐
- Meta一段时间后,将该Parition切主,状态恢复ACTIVE,并增加epoch
- Node进行切主操作
扩容缩容功能,由setmaster命令配合增加slave命令addslave及删除slave命令removeslave完成 迁移主分片:
- add new slave
- set new slave as master
- remove old salve
将判断数据是否追齐的判断的职责分别交给Manager, Meta Server和Data Server,从而得到三种不同的迁移方方案。
- 用户通过Manager执行指定Partition切主的操作
- Meta Server收到命令,到该Partition对应的Data Server上收集binlog offset,如果一致更新元信息切主,并返回Manager成功,同时更新元信息切主。否则返回失败。
- Manager收到失败可以之后重试
- 对应的Data Server收到新的元信息,阻写并切主
- Meta提供切主命令
- Meta向Data收集Offset
- Data提供查询Partition Offset命令
- 实现简单
- Meta Server增加的负担较少
- 切主时机不准确
- 但人工介入较多
- 用户通过Manager执行指定Partition切主的操作
- Meta对所有需要切主操作的Data Server记录并定时检查其Offset(或者通过ping pong)
- 新主Offset追齐旧主Offset后,更新元信息切主
- 对应的Data Server收到新的元信息,阻写并切主
- Meta提供切主命令
- Data提供查询Partition Offset命令
- Meta维护需要收集Offset的节点,定时收集。并且这个信息可能需要维护在Floyd
- 人工接入较少
- 切主时机不准确
- Meta Server负担较重
- 用户通过Manager执行指定Partition切主的操作
- Meta收到命令后直接更新元信息切主
- Data Server收到新的元信息,如果是由主变从,继续充当主,直到新主对应的binlog send task和binlog write的offset一致后,停写并通知新主(增加交互命令或想binlog压入特殊标记)
- Data Server如果是由从变主,继续充当从,知道收到旧主的通知(交互命令或binlog特殊标记)后,变为新主
- 中间过程中,所有的Client访问,需要重定向
- Data之间需要能够通知对方的机制
- Data需要实现重定向反馈
- Client需要处理重定向
- 人工介入较少
- 旧主等待offset时很方便进行写限速
- Meta Server压力最小
- 切主时机精确
- 需要引入Client和Data的重定向机制
经过讨论,目前采用由Manager决定切主时机的方案。并且引入阻写阶段来解决切主时机不精确的问题,切主过程如下:
- Manager在适当时候发起切主操作
- Meta Server更新元信息,用新的Node状态标识阻写开始
- Data Server获取最新元信息,旧主阻写,新旧主通过Ping向Meta汇报binlog位置
- Meta Server发现binlog追齐,修改元信息标记为正式的切主状态
- Data Server更新元信息后完成切主
Manager:
- 实现Slave Partition迁移命令
- 实现切主命令
- 处理Data阻写后的场景
Meta Server
- 元信息增加Node的阻写状态
- 阻写和切主相对应的元信息改变逻辑
- 接受并统计阻写后对新旧主从Binlog offset的收集
Data Server
- 阻写及切主的元信息处理逻辑
- Ping信息可以带Offset逻辑
- 阻写状态的命令处理