利用一個(gè)只能append的數(shù)據(jù)庫(kù)(hive這種) 來(lái)存儲(chǔ)所有的action, 認(rèn)為這些action是按照時(shí)間序列進(jìn)來(lái)的, 并且不會(huì)改變. 通過(guò)這些日志來(lái)維護(hù)整個(gè)服務(wù)的一致性
問(wèn)題
很多服務(wù)如不開(kāi)啟bin-log的mysql實(shí)際上是只維護(hù)系統(tǒng)的當(dāng)前狀態(tài), 一致性也局限在一個(gè)action這一步上.
解決
ext系列日志文件系統(tǒng), mysql的bin-log了解一下.
日志系統(tǒng)都是非常類似的, 以ext系列為例, 對(duì)文件的增刪改查都會(huì)首先計(jì)入到磁盤(pán)的一個(gè)日志區(qū). 因?yàn)檫@些操作是不會(huì)改變且嚴(yán)格到達(dá)時(shí)間發(fā)生的, 所以可以順序的寫(xiě)入到一個(gè)頭部扇區(qū)里并不需要去考慮改寫(xiě)問(wèn)題.
積累到一定程度的時(shí)候就可以把根據(jù)日志, 把操作刷到真正的數(shù)據(jù)持久化里去. 回滾時(shí)也可以按照日志來(lái)進(jìn)行回滾操作保證了數(shù)據(jù)的一致性. 甚至玩意數(shù)據(jù)丟失了, 還可以通過(guò)重播這一段日志進(jìn)行找回.
決策
- 從action達(dá)到, 到實(shí)際數(shù)據(jù)刷新有一個(gè)時(shí)間窗口. 這個(gè)時(shí)候讀操作是否需要讀一個(gè)已經(jīng)跑了所有的action的一個(gè)snapshot? 又或者更簡(jiǎn)單一點(diǎn), 幻讀是允許的?
- 在多線程情況下, 操作的先后順序?qū)Y(jié)果可能產(chǎn)生影響. 由于一般認(rèn)為所有的action是保序刷到一個(gè)臨時(shí)存儲(chǔ)里的, 那么action的順序應(yīng)該如何來(lái)控制? 這里樂(lè)觀鎖了解一下, snowflake也是經(jīng)典方案, 還有先把數(shù)據(jù)切成多個(gè)segment, segment內(nèi)部有序, 相互之間無(wú)序等等好多種解決思路
- 日志系統(tǒng)可以在產(chǎn)生conflict前檢查到conflict, 但是只有應(yīng)該執(zhí)行什么操作? 這里需要有一個(gè)執(zhí)行策略
- 如果日志有可能被play好多次, 那么action必須冪等以保證最終一致性. 或者通過(guò)某種策略保證日志play only once