關於分布式id生成器生成單調遞增id的思考


目錄

 

如何保證獲取到的id單調遞增?

約束條件:

1)集群中一台機器為Master,僅Master提供id生成服務

2)當獲取id的請求路由到Master機器時,直接返回響應(一輪RPC)

當獲取id的請求路由到非Master機器時,轉發至Master機器(兩輪RPC)

 

方案評估

 

評估

性能

1)請求最終由Master機器進行響應。單機能支持的最大QPS即為集群最大QPS。

2)請求路由到非Master機器時,需兩輪RPC,會增加耗時。

3)請求最終由Master機器進行響應,導致同機房優先路由策略不適用,某些情況下,請求耗時較長。

擴展性

集群總QPS無法隨集群機器數量的增加而線性擴展。

可用性

1)當發生Master切換時,會損失一定可用性

2)某些情況下,請求耗時較長,會導致可用性降低。

 

評估詳情

性能

(1)當獲取id的請求最終由Master進行響應。單機能支持的最大QPS即為集群最大QPS。

(2)由於僅Master能夠提供id生成服務,同機房優先等路由規則不再適用

情況1:當獲取id的請求路由到Master

當獲取id的請求路由到Master,直接返回響應,一輪RPC

case1:

client和Master同城市,比如都在Beijing

client(Beijing)----->server(Master,Beijing)

 

case2:

client和Master不同城市,比如一個Beijing,一個Shanghai

client(Beijing)--(25ms+)--->server(Master,Shanghai)

跨城市調用,獲取id的耗時將達到25ms+。

 

情況2:當獲取id的請求路由到非Master

當獲取id的請求路由到非Master,轉發至Master,兩輪RPC

case 1:

當client和Master同城市,比如都在Beijing

client(Beijing)----->server(非Master,Beijing)----->server(Master,Beijing)

 

case2:

當client和Master不同城市,比如一個Beijing,一個Shanghai

client(Beijing)----->server(非Master,Beijing)--(25ms+)--->server(Master,Shanghai)

跨城市調用,獲取id的耗時將達到25ms+。

 

極端情況:第一次獲取id,Master從DB加載號段,跨城市

client(Beijing)----->server(非Master,Beijing)--(25ms+)--->server(Master,Shanghai)--(25ms+)--->DB(Beijing)

 

總結

當client和Master機器在不同城市時,獲取id耗時較長。

 

擴展性

集群總QPS無法隨集群機器數量的增加而線性擴展。

無論集群中機器有多少台,集群QPS為單機最大QPS

 

可用性

1)由於同機房優先等路由規則不再適用,耗時明顯增加,超時概率大大提高。

2)切換Master期間,id生成服務會短暫不可用,且不可避免

 

可導致Master切換的情況

1)禁用Master機器

2)重啟Master

3)機器宕機

 

Master切換

1)探測到需要切換Master

當禁用Master機器的時候,怎么探測到需要切換Master?

2)選舉新的Master

3)新Master提供服務

新Master從DB獲取新號段,對於路由到非Master的請求將轉發到新Master

 

如何處理Master切換時的id分發問題,保證在Master切換時的可用性?

Master切換期間,id生成服務短暫不可用,且不可避免,只能夠盡量做到client端無明顯感知

此處無明顯感知是指

1)Master切換時,client端獲取id的耗時無明顯增加,否則導致超時增多

2)Master切換時,獲取id服務短暫不可用,應保證獲取到異常的id的數量無明顯增加

 

附錄

微信序列號生成器如何實現唯一、遞增的

https://www.infoq.cn/article/wechat-serial-number-generator-architecture/

實現唯一、遞增的約束條件:有且僅有一台server提供服務

 

 

 

圖 5. 兩台 AllocSvr 服務同個 uid 造成 sequence 回退。Client 讀取到的 sequence 序列為 101、201、102

解決方法:僅有一台Master提供服務,Master不可用時,切換新Master

總結就是:

1)單台Master提供id生成服務。

2)引入仲裁服務,仲裁服務探測Master可用性,當Master不可用時,指定新的Master

3)其他機器定時檢測配置,判斷新Master是不是自己,是的話,作為新Master提供服務

 

為了避免Master切換過程中,舊的Master產生臟數據,引入了租約機制。

但是租約機制會導致id生成服務一段時間內不可用,此時,微信通過重試解決這段時間的不可用問題。

圖 6. 號段遷移示意。通過更新加載配置把 0~2 號段從 AllocSvrA 遷移到 AllocSvrB

同時,為了避免失聯 AllocSvr 提供錯誤的服務,返回臟數據,AllocSvr 需要跟 StoreSvr 保持租約。這個租約機制由以下兩個條件組成:

  1. 租約失效:AllocSvr N 秒內無法從 StoreSvr 讀取加載配置時,AllocSvr 停止服務

  2. 租約生效:AllocSvr 讀取到新的加載配置后,立即卸載需要卸載的號段,需要加載的新號段等待 N 秒后提供服務

 

圖 7. 租約機制。AllocSvrB 嚴格保證在 AllocSvrA 停止服務后提供服務

這兩個條件保證了切換時,新 AllocSvr 肯定在舊 AllocSvr 下線后才開始提供服務。但這種租約機制也會造成切換的號段存在小段時間的不可服務,不過由於微信后台邏輯層存在重試機制及異步重試隊列,小段時間的不可服務是用戶無感知的,而且出現租約失效、切換是小概率事件,整體上是可以接受的。

(由於微信序列號生成器的使用場景的特殊性,對於短時間內id生成服務的不可用是可以容忍的)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM