<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          聽說:分布式ID不能全局遞增?

          共 2022字,需瀏覽 5分鐘

           ·

          2022-03-03 19:44

          點擊上方藍(lán)字“設(shè)為星標(biāo)”





          大家好,我是【架構(gòu)擺渡人】,一只十年的程序猿。這是實踐經(jīng)驗系列的第十一篇文章,這個系列會給大家分享很多在實際工作中有用的經(jīng)驗,如果有收獲,還請分享給更多的朋友。

          ?

          前面有篇文章我們講到用時間來代替自增ID進(jìn)行分頁排序,原因是因為接入了分布式ID,但是分布式ID不能夠保證有序,只能保證全局唯一。

          ?

          那么今天我們一起來探討下,究竟能不能實現(xiàn)有序的分布式ID呢?

          ?

          ?

          分布式ID的實現(xiàn)方式







          號段模式


          號段模式是目前用的比較多的實現(xiàn)分布式ID的方式,號段模式通過預(yù)先獲取一段范圍,然后全部在內(nèi)存中進(jìn)行ID的分發(fā),性能極高。

          ?

          采用號段模式實現(xiàn)的開源框架也有很多,比如美團(tuán)的Leaf,滴滴的Tinyid。對號段模式實現(xiàn)原理不了解的小伙伴可以查看下面的地址進(jìn)行深入學(xué)習(xí)。號段模式想要實現(xiàn)遞增比較難,文章后面我們一起聊聊有沒有什么方式能夠?qū)崿F(xiàn)。

          ?

          Leaf: https://github.com/Meituan-Dianping/Leaf

          Tinyid: https://github.com/didi/tinyid

          ?




          Snowflake


          Snowflake 是 Twitter 開源的分布式ID生成算法,在國內(nèi)用的也比較多。比如百度開源的uid-generator就是基于Snowflake算法進(jìn)行改進(jìn)。

          ?

          uid-generator:https://github.com/baidu/uid-generator

          ?

          Snowflake生成ID性能很好,而且也滿足遞增的要求。不過依賴機(jī)器上的時間,如果時間不一致就會有重復(fù)的問題。

          ?




          Redis Incr


          Redis 可以直接使用Incr命令進(jìn)行數(shù)字的遞增,從而實現(xiàn)自增的ID。如果使用Redis實現(xiàn)分布式ID需要進(jìn)行ID的持久化,否則重啟后就沒了會出現(xiàn)重復(fù)的問題。

          ?

          既然要持久化,那就避免不了使用AOF或者RDB實現(xiàn)持久化。使用RDB可能會丟失數(shù)據(jù),導(dǎo)致ID重復(fù)發(fā)生。使用AOF肯定要配置刷數(shù)據(jù)的模式為always,每次操作記錄都同步到硬盤上,這樣才能保證數(shù)據(jù)不丟失,但是性能較差。當(dāng)然Redis 4.0還有混合模式(AOF+RDB)可以用也是一種不錯的選擇。

          ?

          無論是單機(jī)還是集群環(huán)境下,某個key必定會路由到某一個節(jié)點。雖然Redis單機(jī)也能支持10萬基本的QPS,假設(shè)你的ID需求超過了這個量級,這塊就會成為瓶頸,因為你要保證自增,沒辦法水平擴(kuò)容。


          ?

          號段模式想有序怎么辦?




          號段模式數(shù)據(jù)不會丟失,性能高,是一個很優(yōu)秀的方案。但是號段模式?jīng)]辦法實現(xiàn)全局的遞增ID,如果要實現(xiàn)全局遞增,那么就不能拆分,得有一個固定的節(jié)點,所有請求都從這個節(jié)點獲取ID才行。但是號段模式就是分段的特性,通過分段可以實現(xiàn)水平擴(kuò)展,提升性能。

          ?

          號段模式只能實現(xiàn)局部遞增,比如我訂單表接入了分布式ID,如果用號段模式,那么就會出現(xiàn)我下第一單的ID是20001,接著下第二單,ID可能就是10003。如果此時用的是ID降序排序,就會出現(xiàn)順序錯亂的問題,這也是之前文章里面為什么要用高精度的時間來排序。

          ?

          這種情況下,是否只要保證同一個用戶下的數(shù)據(jù)是遞增的就可以,這就是局部遞增。如果要想實現(xiàn)局部遞增需要考慮下面幾個問題:

          ?

          • 固定路由
          ?
          用戶維度的遞增,就需要將用戶的請求路由到固定的ID服務(wù)節(jié)點,這樣取出來的ID就是局部遞增。
          ?

          ?

          • ID服務(wù)某個節(jié)點掛掉或者重啟

          ?

          假設(shè)用戶A一直是路由到 id-service-b 上面,此時 id-service-b 掛掉了,那就需要重新找個新的節(jié)點進(jìn)行路由,問題來了,路由到新的節(jié)點,假設(shè)是 id-service-c。

          ?

          而此時 id-service-c 上面的ID 段可能比 id-service-b大,如果大的話就沒問題,還是遞增。如果小的話就有問題了呀,所以這個問題要解決。

          ?

          ?

          如何解決上面的問題呢?

          ?

          個人感覺這個問題不太好解決,因為路由到某一個節(jié)點的用戶是N,也不可能對這些用戶現(xiàn)有的ID進(jìn)行查詢,判斷是否大于即將路由的服務(wù)的ID段。整個邏輯太復(fù)雜了。

          ?

          有一個簡單的方式,就是當(dāng)有固定路由需求的ID要進(jìn)行路由切換的時候,全局加鎖(此時并發(fā)量大的話會影響使用方的RT),將這個ID對應(yīng)的所有段都清除,這樣重新路由的時候就又申請了新的段,新的段肯定大于之前的段,也就是遞增。

          ?


          總結(jié)



          其實要想實現(xiàn)某個需求,背后的方式有很多。如何去選擇適合,最優(yōu)的方案這個是比較考驗大家平時的積累和技術(shù)的廣度。你得知道每種方案的原理是什么,差異點在哪,哪種成本更低,哪種能夠完全符合業(yè)務(wù)需求。

          ?

          原創(chuàng):架構(gòu)擺渡人(公眾號ID:jiagoubaiduren),歡迎分享,轉(zhuǎn)載請保留出處。

          瀏覽 39
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产亚洲在线 | 污污在线无码 | 先锋成人资源 | 成人黄A片免费 | AAAAAA免费视频 |