AppBoxFuture(四). 随需而变-Online Schema Change

  需求变动是信息化过程当中的屡见不鲜,而在变动过程当中如何尽量小的影响在线业务是比较头疼的事情。举个车联网监控的例子:原终端设备上传车辆的经纬度数据,新的终端设备支持同时上传速度数据,而旧的车辆状态表数据量超过亿级,此时若是Alter table add column将会形成数据表上锁,致使上传或查询车辆状态数据等待。AppBoxFuture的存储引擎在设计之初也是采用锁表的方案,后来考虑到上述应用场景决定支持online schema change,但带来了另外一个难题是如何保证分布式环境下的一致性。git

  在权衡了利弊后,做者决定采用以下草图所示的变动方案,主要是考虑工程实现上的便利性。实现的关键点是实体模型内有SchemaVersion标记,在添加删除列、索引、EntityRef引用外键时,SchemaVersion+1, 同时全部表分区的状态机内也有SchemaVersion标记当前的版本,若是变动过程当中有旧版本的Insert\Update\Delete命令,则抛出SchemaChanged错误,由上层逻辑加载新的模型后重试。该方案的优势是实现简单,且变动过程对在线业务的影响较小,缺点是变动任务不支持回滚,如遇到网络或磁盘错误则任务会稍候重试(幂等),添加唯一索引例外,遇到主键冲突任务不会重试,改成通知上层删除该索引。github

  做者在虚拟机(I74C8G)内作了个单分区80万行记录添加列变动性能测试,以下动图所示:网络

测试结果以下约0.8秒就处理完一个分区80万行记录:app

#01/17/2019 11:17:07 [Debug] [StoreService.UpdateModelAsync]: Entity[VehicleState] schema changed, 2 -> 3
MetaAlterTable::TryRunAsTask: 开始提议分区变动任务至68719476742
MetaAlterTable::TryRunAsTask: 分区提议成功68719476742
KVAlterPartion::TryRunAsTask: 分区批次处理完成
MetaAlterTable::TryRunAsTask: all partition done, elapsed time:0.847791s
MetaAlterTableDone::Apply: 移除变动任务, 剩余任务:0
KVAlterPartionDone::Apply: 移除分区变动任务, 剩余任务:0

  若是您有问题或Bug报告,请留言或在Github提交Issue。分布式

相关文章
相关标签/搜索