隨筆-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)  編輯  收藏

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


          網站導航:
           
          主站蜘蛛池模板: 宝坻区| 西峡县| 汨罗市| 衢州市| 郑州市| 永吉县| 泽州县| 嵩明县| 涟水县| 株洲县| 博乐市| 崇仁县| 黔东| 焦作市| 静宁县| 泰州市| 象州县| 井陉县| 鄯善县| 科技| 内乡县| 巢湖市| 鄂伦春自治旗| 黔南| 东光县| 元江| 秀山| 卓尼县| 北京市| 霍林郭勒市| 丹棱县| 读书| 宜州市| 江西省| 台湾省| 胶州市| 峨边| 临安市| 清新县| 门源| 玉环县|