論文:TreadMarks
本節(jié)我們以 TreadMarks 為模型聊一聊釋放一致性的是使用場景。
所謂釋放一致性,是指在對資源操作前,先進(jìn)行 acquire 操作即獲取鎖,其實(shí)是對某個(gè)標(biāo)示位的值進(jìn)行讀取,若該資源正在被其他進(jìn)程操作,該標(biāo)示位為 0,當(dāng)資源操作完成時(shí)會(huì)向所有副本發(fā)出更新通知,所有副本更新成功后將改標(biāo)示位改成1,即釋放鎖(release),而在此之前,后面的進(jìn)程只能輪詢該標(biāo)示位以獲取鎖狀態(tài)??梢娺@種一致性模型每次只將修改的部分通知大家更新一下,分散了一致性的壓力,數(shù)據(jù)競爭較小的地方會(huì)有比較理想的性能提升。
但是,每次通知大家更新的時(shí)候是需要等所有人都回復(fù)OK后才能釋放鎖。如果 A 修改后不通知 B 和 C,BC 在每次 acquire 之前先把自己的數(shù)據(jù)更新一下,這樣可以將 A 修改同步的負(fù)載延遲到各個(gè)副本上,這種策略叫 Lazy Release Consistency(LRC)。
TreadMarks 為分布式共享式內(nèi)存而設(shè)計(jì),采用 LRC 策略保證一致性,比 RC 提高了性能,但需要將資源的操作分成一個(gè)個(gè) interval:acquire 和 release 之間,可理解為邏輯上的時(shí)鐘,稱為 vector clock,它維護(hù)了各個(gè)進(jìn)程的資源競爭的因果關(guān)系,通過合并操作可以得出每個(gè) interval 結(jié)束時(shí)的資源狀態(tài),保證數(shù)據(jù)的一致性。
在分布式共享內(nèi)存中還有一個(gè)性能殺手,F(xiàn)alse Sharing。由于內(nèi)存的管理單位是頁,進(jìn)程 A 修改的頁1的部分1,而進(jìn)程 B 讀取頁1的部分2,傳統(tǒng)的方式會(huì)先把進(jìn)程B頁1副本更新后再進(jìn)行讀取,而進(jìn)程 A 的修改對進(jìn)程 B 的讀取沒有影響,這顯然是可以優(yōu)化的。TreadMarks 的優(yōu)化策略是在每個(gè) interval 中創(chuàng)建 diff,也就是說,進(jìn)程 A 寫入頁1部分1之前先創(chuàng)建頁1的復(fù)制 twin,然后再去頁1中修改,當(dāng)進(jìn)程B讀取頁1時(shí),比較要讀的部分在頁1和twin有沒有區(qū)別,若沒有則直接讀本地頁1副本,如有區(qū)別則創(chuàng)建創(chuàng)建 diff。根據(jù) vector clock 在時(shí)間上因果關(guān)系推算出當(dāng)前進(jìn)程應(yīng)該讀到那個(gè)版本的diff,如此一來,將單一的數(shù)據(jù)頁同步轉(zhuǎn)化成狀態(tài)的疊加,可以有效降低 False Sharing 的性能損耗,當(dāng)然需要更多的空間存 diff,用空間換時(shí)間。
沒有十全十美的解決方案,只有適合不同場景的平衡取舍,由于分布式內(nèi)存資源競爭概率遠(yuǎn)小于非競爭的情況,所以在在競爭同步,創(chuàng)建 diff 的策略上采取 lazy 的方式。反過來說,如果內(nèi)存競爭的情況高于非競爭的情況,這種處理方式反而會(huì)使內(nèi)存的使用效率降低,比如單機(jī)。