避免使用鎖提供一致性
避免複製日誌提供一致性
快速故障恢復
自由集群擴容或縮容
缺點:無法提供高併發,需要使用其它機制提供高負載能力。
基於版本一致性演算法是乙個類paxos演算法,file store是由該演算法實現的分布式檔案管理系統(以下簡稱系統),本文以該系統為例說明該演算法。
該演算法定義了三個階段:選舉期,平穩期和故障期。系統大部分時間是在平穩期,就算是發生故障時,系統也不會立刻進入選舉期,只有在有讀寫操作失敗後才會由外部觸發新的選舉。選舉成功後,系統會立刻恢復到平穩期。
該系統中所有服務節點都是平等的citizen,但他們會在不同時期擔任以下三種角色中的一種:
leader - 負責寫操作,通知到所有節點備份和節點狀態管理
follower - 負責任何節點發起的選舉,負責資料的備份和讀取
candidate - 負責選舉
理論上任何乙個節點都可以隨時將自己設定為候選人從而發起選舉。但通常只有外部訪問失敗時才需要通知集群中某個節點發起選舉。
public bool startelection()每次選舉最多只能產生乙個leader。為了實現這個要求,每個節點都持有乙個線性增長的選舉號。節點發起選舉時首先將自己的選舉號增加1個點,然後發起選舉給到所有節點。只有得到大多數節點的同意後選舉才算成功,否則選舉失敗。return false;
}
所有節點在接收到選舉請求時都需要立刻執行選舉操作:
public bool dovote(int election_no, citizen citizen)接收到選舉號後比較自己已經投出的選舉號,如果是新選舉號則同意這次選舉。return false;
}
如果同一時間有多個節點發起選舉,選民會第一時間更新自己投出的選舉號(原子操作)因此不會同時同意兩個候選人發起的選舉。就算毫秒間先後同意了兩個候選人,然後候選人做後續的寫操作時也會失敗,從而修改自身的錯誤資訊。
只有leader才有資料的寫入權,當乙個leader接受到client的寫請求時:
public bool write(int index, bucket bucket)leader首先會把資料加上自己當選的選舉號和資料的版本號,然後通知所有節點寫入備份,只有得到大多數節點的認可才更新本地資訊,否則修正自己的角色。this.type = citizentype.citizen;
return false;
}
所有節點在接收到備份請求時都需要立刻執行備份操作:
public bool dowrite(bucket bucket, citizen citizen)首先比較資料的建立者是否為自己投的leader,只有自己認可的或高於自己認可的leader的請求才處理,否則不執行任何操作。另外高於自己認可的leader的請求時,需要同步自己的leader資訊。if (bucket.leaderno> this.votedno)
//s**e bucket to local disk
return true;
}
因為leader隨時都可能更改,但為了提高併發能力,資料一致性的確認只能在讀取時處理,所以資料讀取時,首先要確保本地資料是最新的,如果不是最新需要通知其它節點讀取最新的。
首先判斷資料建立者是否為自己認可的leader,如果不是自己認可的leader建立,則立刻通知節點同步資料。需要注意的是,就算是自己認可的leader建立的資料也不能說明本地的資料已經最新,可能該節點已經失聯,也可能該節點在選舉和寫資料時失聯。因此還需要向所有節點傳送讀資料確認資料已經最新,然後才能返回資料。public bucket read(int index)
if (sendmessage("read", index))
else}
public bool ensurerecovery(int index)
if (sendmessage("read", index))
return false;}
所有節點在接收到讀取請求時都需要立刻執行讀取操作:
public tuple doread(int index, int versionno, citizen citizen)讀取本地資料並與要讀取資料的版本號比較,如果本地版本比較高則返回本地資料。如果版本相同只返回true,否則證明自己的資料已經無效。注意發現資料不同步後,並不需要及時解決資料一致性,直到有讀取操作時才去確保資料一致性。if (versionno == bucket.leaderno)
return new tuple(false, null);
}
因此寫入和讀取都需要得到大多數節點的確認,因此不存在資料一致性問題。最差的情況是,多數節點在讀取時失聯,從而會導致讀取失敗,這種情況只能由客戶端重試。
為了防止不一致性,該系統的節點擴/縮容需要緩慢進行。
擴容時,首先新節點的加入必須得到所有節點的確認,即所有節點都已經成功更新本地配置。然後確保只有乙個節點加入成功後才能增加新的節點。
縮容時,首先是停掉乙個節點,然後再通知所有節點移除該節點,並得到所有節點確認。
該系統理論上是強資料一致性的,由上面流程也能看出,所有的讀取都需要得到大多數節點的確認,這需要消耗多次的網路連線。因此建議:
系統需要盡量保證節點間的通訊穩定和高速
系統儲存的資料應該盡量少,比較適合儲存元資料
應對讀多寫少,而且對資料一致性要求不高的情況下,可以修改大多數讀確認的定義
強一致性 弱一致性 最終一致性
這種方式在es等分布式系統中也有體現,可以設定主shard提交即返回成功,或者需要replica shard提交成功再返回。提到分布式架構就一定繞不開 一致性 問題,而 一致性 其實又包含了資料一致性和事務一致性兩種情況,本文主要討論資料一致性 事務一致性指acid 複製是導致出現資料一致性問題的唯...
一致性hash演算法 面試必備 一致性hash演算法
最近公司在招人,我們準備的問題中有一道是關於一致性hash演算法的問題,只有一些面試者能夠回答上來,而且答的也不是很全面,有的面試者只是聽說過,有的連聽都沒聽過,下面我把一致性hash演算法整理一下分享給大家 一致性雜湊演算法在1997年由麻省理工學院的karger等人在解決分布式cache中提出的...
一致性hash演算法虛擬節點 一致性hash演算法
hash 演算法也叫做雜湊演算法,他可以讓任意長度的資料m對映成為長度固定的值h。hash演算法的第乙個作用就是資料的快速儲存與查詢。寫過程式的人都知道,基本上主流的程式語言裡面都有個資料結構叫做map dictionary或者 hash table 它是根據key來直接訪問結果的資料結構。key的...