華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

華為雲開發者社群發表於2021-04-14
摘要:在KV資料庫領域,“強一致性”不僅是一個技術名詞,它更是業務與運維的重要需求。

清明剛過,五一假期就要來了。大好春光,不如去婺源看油菜花吧!小云迅速開啟APP刷出餘票2張,趕緊下單!唉,怎麼又沒搶到!轉念一想倒也能理解:從勾選乘車人到正式下單,起碼要10秒,真若是“見者有份”,恐怕這兩個座位大家要擠擠共用了!每逢節假日,全國幾百萬小夥伴同時查票訂票,12306是如何保證餘票顯示準、車票不超賣的?

於是,按捺不住好奇心,筆者進行了一番深入研究。原來,問題背後隱藏著一個分散式資料庫領域極其關鍵的技術——資料強一致性保障。

1. 什麼是強一致?

在介紹概念之前,我們不妨先來模擬一場球賽直播。

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

假設筆者做了一款APP,後臺使用上圖的主從資料庫。比分寫入主節點,從節點分擔使用者查詢。比賽中,Alice驚呼比賽結束,Bob聞聲重新整理APP,卻顯示比賽仍在繼續!Bob體驗到了明顯的資料不一致,於是默默給APP打了個差評……

那麼,產生不一致的原因究竟是什麼?

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

非同步複製時,主節點不等待從節點寫入就直接返回了。由於網路延遲等原因,從節點無法保證更新時間。Alice和Bob明明在同時同地查詢同一系統,得到正確結果卻有先有後。其實這就是典型的弱一致性。

實際上,為解決單點故障、增強吞吐效能,分散式資料庫內部都會對同一份資料進行復制,把冗餘副本分散儲存到不同節點上。簡單的非同步複製只能構建出弱一致系統,很難滿足業務要求。

那麼,究竟什麼樣的一致性才靠譜?有哪些類別?下面我們就來認識這個神祕家族!

1.1 強一致性/線性一致性(Linearizability)

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

一致性的最高標準,實現難度最高。核心要求是:一旦寫操作完成,隨後任意客戶端的查詢都必須返回這一新值。以下圖為例,一旦“寫入b”完成,必須保證讀到b。而寫入過程中,認為值的跳變可能發生在某一瞬間,因此讀到a或b都是可能的。

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

從業務角度來說,強一致性帶來的體驗簡直可以用絲滑來形容!因為它內部的資料“彷彿”只有一份,即使併發訪問不同節點,每個操作也都能原子有序。正因如此,強一致資料庫在業務架構中往往被用在關鍵位置。

etcd是強一致俱樂部裡的元老。它基於Raft共識演算法,真正實現了強一致,也因此在Leader選舉、服務發現等場景起到重要作用。GaussDB(for Redis)作為一款分散式雲資料庫,憑藉多年潛心打磨,也是強一致的代言人。

1.2 順序一致性(Sequential Consistency)

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

弱於線性一致,不保證操作的全域性時序,但保證每個客戶端操作能按順序被執行。下圖中,A先寫x=10,後寫x=20;B先寫x=99,後寫x=999。當C讀取時,順序一致性保證了10先於20被讀到、99先於999被讀到。

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

Zookeeper基於ZAB協議,所有寫操作都經由主節點協調,實現了順序一致性。

1.3 因果一致性(Causal Consistency)

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

進一步放寬要求,只對併發訪問中具有因果關係的操作保序。例如:

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

A寫入3,B讀到後乘以100再更新它。在這個場景下,由於“A寫入3”與“B寫入300”有著明確因果關係,因果一致性保證300晚於3被讀到。

因果一致性多用於各種部落格的評論系統、社交軟體等。自然,我們回覆某條評論的內容,不應早於評論本身被顯示出來。

1.4 最終一致性(Eventual Consistency)

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

停止寫入並等待一段時間,最終所有客戶端都能讀到相同的新資料,但具體時限不作保證。許多分散式資料庫滿足最終一致性,如MySQL主從叢集等。

然而,這其實是一個非常弱的保證。由於不確定系統內部過多久才能收斂一致,在此之前,使用者隨時可能體驗到資料不一致。因此最終一致性有天然的侷限性,經常會給業務邏輯帶來混亂。

1.5 弱一致性(Weak Consistency)

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

說它最為“厚臉皮”也不為過,因為它連資料寫入後將來被讀到都不能保證!弱一致性實現技術門檻低,應用場景也不多。嚴格來說,單純的開源Redis主從叢集就屬於這一類別。

OK,一致性家族的各位成員已經跟大家打過照面。顯然,一致性越強的資料庫系統,能夠支撐的業務場景越多。有的業務同學小聲說,強一致技術再牛,可我業務簡單,不用也沒關係吧。實際上恰恰相反:

強一致不僅僅是技術問題,它更是一個不可忽視的業務需求、運維需求!

接下來我們就先來聊一聊:業務上那些只有強一致才能搞定的事兒!

2 強一致是業務剛需

2.1 計數器/限流器

計數服務是典型的強一致應用場景。電商在秒殺活動中,往往會搭建Redis主從叢集給下層MySQL做快取。因為要抗住超大流量,需要Redis的計數器功能做限流。簡單講,我們初始化counter=5000。隨後每次業務訪問都執行DECR命令,當counter歸零就阻塞後續請求。此外,每隔一個時間段重置counter=5000,通過這樣的手段來實現“細水長流”。

然而,完美的假設還不夠!

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

開源Redis採用非同步複製,如遇網路不暢,經常發生主節點複製buffer堆積。這將導致從節點counter偏大很多。此時,一旦主節點當機,切換到從節點繼續執行DECR命令,壓力很容易超出閾值,全部落到下層脆弱的MySQL,隨時可能引起系統雪崩!

因此,在限流場景下,只有真正的強一致才能提供可靠的計數器。

2.2 Leader選舉

當業務部署的節點較多、可用性要求高時,往往要用到Leader選舉。etcd作為強一致KV儲存,能完美cover這一場景。etcd依賴兩大功能實現Leader選舉:

1)TTL:給key設定有效期,到期後key自動刪除。

2)CAS:對key的原子操作。(這一功能只有強一致資料庫才能實現)

使用etcd搭建Leader選舉服務的設計如下:

1)約定key,用於選舉時搶佔。其value用於儲存Leader節點名稱。

2)約定TTL,用於給key設定有效期。

3)啟動時:每個參與節點嘗試cas create key&設定TTL。在etcd叢集強一致CAS機制保障下,只有一個節點能執行成功。該節點成為Leader並將名稱寫入value;其餘節點成為Follower。

4)執行中:每個節點定期TTL/2嘗試get key,將value與自身名稱對比:

  • 如相同,說明已是Leader,此後只需每隔TTL/2重新整理key的TTL即可。
  • 如不同,說明是Follower,接下來要每隔TTL/2執行cas create key&設定TTL。

5)當Leader節點異常退出,無法重新整理TTL,key會很快過期。此時,其餘Follow之中便會有新的Leader產生。

從原理上能看出,強一致能力是Leader選舉的根基。類似的“剛需”業務場景還有很多,強一致不可或缺。

好了,業務上的事兒就聊到這裡,接下來讓我們聽聽運維怎麼說。

3. 強一致為運維減負

3.1 輔助元件架構複雜、問題難定位

後臺架構中,MySQL主從熱備也是常見的部署方式。由於資料儲存在本地磁碟中,當主庫發生嚴重故障,僅僅依靠MySQL自身同步機制,主從切換後無法保證所提供資料與之前狀態完全一致。於是出現了“重量級”的輔助元件——MHA(Master High Availability)。我們來看一下它的部署方式:

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

MHA負責在故障轉移過程中,幫助從庫儘量追平主庫最新狀態,提供近似一致的資料。但這一能力需要額外的Manager節點,同時還要在每一個MySQL節點上部署Node服務。故障切換時,Manager先為從庫補充落後的資料,再通過切換VIP恢復使用者訪問,過程可能長達數十秒。

這樣的HA系統部署和後期維護都很複雜。如未能順利執行故障切換或發生資料丟失,運維面臨的場面都將很棘手。其實運維同學何嘗不希望手中的系統穩定執行呢?要是資料庫自身能提供強一致保障,何苦再依賴複雜的輔助元件!

讀到這裡,對強一致的看法,相信各位讀者心裡已經有了自己的一杆秤。讓我們再一次劃重點:強一致不僅僅是技術問題,它更是一個不可忽視的業務需求、運維需求!

從產品選型角度出發,開源Redis提供的一致性保證很弱。而etcd雖有強一致能力,但它單點寫入效能不足,也未能提供hash、sorted set、stream等誘人的資料結構……糾結!

此時,有追求的讀者會說——我全都要!

GaussDB(for Redis)應聲而起——我,可以。

4. GaussDB(for Redis)與強一致

自設計之初,GaussDB(for Redis)(後文簡稱高斯Redis)給自己的定位就是“強一致KV資料庫”,因此徹底摒棄了開源Redis的非同步複製機制。藉助華為雲GaussDB系列先進的“存算分離”架構,將全量資料下沉到強一致儲存層(DFV Pool),從核心技術上超越了傳統開源產品的極限。

讓我們來一起認識一下高斯Redis的強悍:

華為雲PB級資料庫GaussDB(for Redis)揭祕第七期:高斯Redis與強一致

· 使用者購買的例項作為一個整體,提供強一致KV儲存。

使用者業務統一通過Proxy叢集接入高斯Redis,不用考慮內部複雜邏輯。多點併發訪問例項,讀寫操作滿足強一致性,再也不必擔心開源Redis非同步複製的不一致隱患。

· 計算層智慧處理資料分片、動態故障轉移,將資料全量下沉到共享儲存池。

cfgsvr叢集統一管理ShardServer節點,自動對海量資料進行分片。並能夠在故障場景實現秒級接管,嚴格防止任何中間態下的資料不一致。

· 儲存層通過RDMA高速網路實現高效能分散式資料持久化,三副本冗餘保證強一致、零丟失。

DFV Pool是強一致、高效能的分散式儲存系統。這是華為內部自研的公司級Data Lake,它能夠穩定支撐各類全棧資料服務。高斯Redis突破了開源Redis“小格局”的記憶體架構,將資料全量下沉,基於DFV Pool強大的一致性保障能力,給使用者業務帶來更廣闊的擴充空間。

5. 結語

試想,當處在關鍵位置的資料庫“不給力”,業務層就要忙於為系統新增複雜、易出錯的一致性保障邏輯。與此同時,運維還要時刻擔心故障引發的資料落後問題......這樣的系統真的“香”嗎?

專業的事情交給專業的團隊來做!

華為雲NoSQL航道旗艦——GaussDB(for Redis)自研發初期就持續關注資料強一致性設計。藉助GaussDB系列先進的強一致儲存池DFV Pool,GaussDB(for Redis)始終如一,為使用者提供真正強一致的海量KV儲存解決方案。

6. 附錄

本文作者:華為雲高斯Redis團隊

杭州西安深圳簡歷投遞:yuwenlong4@huawei.com

更多技術文章,關注高斯Redis官方部落格:https://bbs.huaweicloud.com/community/usersnew/id_1614151726110813

 

點選關注,第一時間瞭解華為雲新鮮技術~

相關文章