上篇講到這
在單點系統的場景下, 要生成全局唯一ID很容易.
但分庫分表後, 就是分布式環境, 要考慮的是唯一性
, 其次是連續性
.
參考Day9的幾種方式來生成, 或是用中間件提供的方式, 像是Shark有提供SequenceID.
放棄吧, 讓程式端來保證!
也能減少部份IO開銷, 但文件跟ER就要寫的完整了.
ACID在單機環境很容易實現, 但分布式環境很難實現且效率跟性能會大幅下降.
就需要透過一些分散式事務方法來完成事務處理.
主要概念是CAP理論和BASE理論, 來實踐下面幾種分散式事務方法
2PC
能讓所有節點在進行事務提交時保持一致性, 但卻會同步阻塞造成效率低下, 協調者本身就是個單點問題、3PC
能解決2PC的同步阻塞問題, 就可能造成資料的不一致、TCC
把Lock交給後端業務應用解決, 每個子業務都要實做Try-Confirm/Cancel的實作接口, 缺點就是Cancel程式頗難寫、Paxos
解決單點問題, 多數決算法Raft
多數決算法、MQ事務
最大努力Commit, 但架構很複雜且不好Debug,Saga Choreography
把事務拆成很多小事務依序執行, 錯誤就反向依序回滾.Saga Orchestration
在協調器內採用狀態機模型, 決定觸發哪個Saga角色的事務.
基本上做了分庫/分表
後, 對於SQL命令的設計就有一條聖旨
, 就是簡單化
.
盡可能避免用多表JOIN查詢命令, 改成拆分為多條單表查詢命令
.
有人會問? 單次多表JOIN查詢難道性能跟速度不如多條單表查詢命令嘛?
其實這是一種Trade Off, 單次多表JOIN查詢以單次查詢來看一定快過後者的.
當然單表查詢, 別傻傻的一個Id就查一次, 盡量多個Id一次單表查回來, 在後端對多個Result sets做合併.
資料結構、演算法跟LeetCode刷題的基本概念這時就好用了.
但以微服務的宏觀角度還有高併發場景下. 為了擴展性
、易讀性
(我相信幾百行的SQL總是不好閱讀吧XD)、可維護性
, 犧牲一點點單次效能, 讓服務能服務更多用戶, 也是必要的策略.
且單表查詢命列有些好處
能用Solr同步MySQL資料然後做查詢.
又或者是透過阿里巴巴的Canal來同步MySQL到便於讀取模型的搜尋引擎內(記得CQRS的精神跟讀8寫2法則).
參考自Solr和MySQL数据同步方案
ps. 能在寫入到Master或是資料庫之前, 把資料先寫入Cache(Redis)內, 這樣讀取時就能從Cache嘗試讀取, 避免當下同步抄寫還沒完成.
雙倍擴容
策略, 現在有一台資料庫A、B, 2個節點, 想變成4個節點.
先準備好A'和B'兩個新節點, 各自設定成A和B的從庫, 開始同步抄寫過來.
並且改寫分片規則變成4個節點.
等都同步完成, 解除同步關係, 各自變成主庫(A、B、C、D). 開始提供服務.
這時就等維護或是服務低峰時, 來清理各自冗餘資料(不應該屬於自己分片規則內的資料).
今年的鐵人賽挑戰到此完成了.
其實也沒設想什麼主題@@", 只是自己是後端開發, 挑一些熟悉的寫, 所以叫雜談
.
目錄連結
Day 1-3, 30 : 都講微服務、架構, 開發原則
Day 4-10 : 分布式系統的一些東西和原理
Day 11-20 : etcd
Day 21-25 : MQ+nats
Day 26-29 : Distributed tracing
Day 31-33 : 分庫分表介紹
感謝各位的閱讀.
最該感謝的是自己XD, 終於撐完了.
今年沒屯文, 都當晚寫半夜發, 太硬了, 品質也不好.
明年應該會先屯點文章了.
再次感謝. 自己希望能慢慢學習成長成Dev/Ops的角色
也求一份後端開發工作QQ
数据分片架构的下一次进化
The Next Evolution of the Database Sharding Architecture