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。分佈式

相關文章
相關標籤/搜索