隨筆-35  評論-33  文章-0  trackbacks-0

                  在當前的互聯網類產品中,如何高效可用的生成的一個全局自增ID,是一個比較有挑戰性的工作。我見過的一般的做法其實就是時間戳再加固定長度的隨機 字符串。這個方案其實有兩個問題,一個是生成的自增ID的可讀性,另外就是隨機,并不是真正的唯一,它是一個碰撞概率的。其它方案,如依賴數據的自增 ID,如果多個庫,可以通過不同的步長來實現可讀的序列。不過,這其實性能上肯定不可能很高。另外,會有單點的問題。所以,果斷放棄。在查看了目前比較成 熟的snowfake方案之后,感覺不錯。下圖是它的算法核心


          分3段進行詳細說明:

          Snowflake – 時間戳

          這里時間戳的細度是毫秒級。

          Snowflake – 工作機器id

          嚴格意義上來說這個bit段的使用可以是進程級,機器級的話你可以使用MAC地址來唯一標示工作機器工作進程級可以使用IP+Path來區分工作進程。如果工作機器比較少,可以使用配置文件來設置這個id是一個不錯的選擇,如果機器過多配置文件的維護是一個災難性的事情。

          Snowflake – 序列號

          序列號就是一系列的自增id(多線程建議使用atomic),為了處理在同一毫秒內需要給多條消息分配id,若同一毫秒把序列號用完了,則“等待至下一毫秒”。

          原理其實不復雜,下面我們結合Hazelcast(高可用的分布式內存框架)來進行實現。

           snowcase,基于hazelcast的自增實現。GITHUB地址https://github.com/noctarius/snowcast

          為什么選用hazelcast

          1 基于內存計算,速度得到了保證

          2 數據可以持久化,服務重啟之后,數據還可以讀取。

          3 每秒的并發可以支持W級別

          代碼示例

          1 首先需要添加依賴

          目前hazelcast的版本是3.5.5

          2 在容器里面注入服務

          這個是例用hazelcast的spi接口,封裝了自增的一個服務類

          3 簡單使用例子

          snowcase客戶端:

          自增ID服務:

          參照前面的原理說明,這里只傳遞了一個參數,就是時間戳。工作機器與序列號是使用的默認值 。其中工作機器的最大值是8129,最小值是128,序列號是hazelcast依據分布式自動生成的.至于seqName只是給這個自增ID取了別名。


          CASE測試:

          報告輸出:


          唯的一點缺陷就是因為它的長度是41BIT,這個方法的使用年限差不多是69年。

          具體是這樣算的:默認情況下有41個bit可以供使用,那么一共有T(1llu << 41)毫秒供你使用分配,年份 = T / (3600 * 24 * 365 * 1000) = 69.7年。

          其中有一段,我還沒有弄明白,T(1llu << 41),希望知道的同學提示,多謝。



          我的微信公眾號,歡迎溝通學習。
          posted on 2016-04-26 09:22 alexcai 閱讀(2147) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 教育| 汾阳市| 天峻县| 云阳县| 资兴市| 松阳县| 北碚区| 茌平县| 清原| 霸州市| 安徽省| 安吉县| 桐柏县| 韶山市| 屏山县| 云阳县| 贵州省| 双桥区| 赤水市| 定陶县| 介休市| 皮山县| 阿克苏市| 韩城市| 蓬溪县| 闽侯县| 隆林| 剑河县| 合肥市| 思南县| 浮山县| 峨眉山市| 来凤县| 晋中市| 金溪县| 新津县| 都匀市| 军事| 旅游| 乐清市| 饶河县|