日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

『SnowFlake』雪花算法的详解及时间回拨解决方案

發布時間:2023/12/18 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 『SnowFlake』雪花算法的详解及时间回拨解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


📣讀完這篇文章里你能收獲到

  • 圖文形式為你講解原生雪花算法的特征及原理
  • 了解時間回撥的概念以及可能引起發此現象的操作
  • 掌握時間回撥的解決方案—基于時鐘序列的雪花算法
  • 關于雪花算法的常見問題解答

文章目錄

  • 一、原生的雪花算法
    • 1. 簡介
    • 2. 特征
    • 3. 原理
      • 3.1 格式(64bit)
      • 3.2 字節分配
  • 二、雪花算法的時間回撥問題
    • 1. 問題描述
    • 2. 現象引發
    • 3. 常見的處理方式
      • 3.1 直接拋出異常
      • 3.2 延遲等待
  • 三、基于時鐘序列解決時間回撥的方案
    • 1. 簡介
    • 2. 設計思路
    • 3. 算法支持
    • 4. 關鍵實現代碼
  • 四、關于雪花算法的常見問題解答
    • 1. 雪花算法支持的并發數最大多少?
    • 2. 雪花算法支持最多支持系統運行多少年?
    • 3. 用了雪花Id,出現負閏秒為什么會導致系統大量拋異常?

一、原生的雪花算法

1. 簡介

  • 分布式 ID 生成算法用于在分布式系統中生成全局唯一的 ID 標識
  • Twitter 提出的雪花算法便是其中一種知名的算法,也是一種發號器方案
  • 百度(uid-generator)、美團(Leaf)及滴滴(Tinyid)等開源分布式ID都是基于雪花算法實現的,如果有人問你有關唯一 ID 生成的問題,你應該立即想到雪花!
  • 雪花是二進制的 64位(只有 63 位用于填充有符號整數),最終數字一般以十進制序列化

2. 特征

  • 全局唯一性:雪花算法可以保證集群系統的ID全局唯一
  • 趨勢遞增:由于強依賴時間戳,所以整體趨勢會隨著時間遞增
  • 單調遞增(×):不滿足單調遞增,在不考慮時間回撥的情況下,雖然在單機中可以保持單調遞增,但在分布式集群中無法做到單調遞增,只能保證總體趨勢遞增
  • 信息安全指的是ID生成不規則,無法猜測下一個

3. 原理

3.1 格式(64bit)

二進制64位長整型數字:1bit保留 + 41bit時間戳 + 10bit機器 + 12bit序列號

3.2 字節分配

  • 1bit不用:因為二進制中最高位是符號位,1表示負數,0表示正數,生成的id一般都是用整數,所以最高位固定為0
  • 41bit時間戳:這里采用的就是當前系統的具體時間,單位為毫秒
  • 10bit工作機器ID(workerId):每臺機器分配一個id,這樣可以標示不同的機器,但是上限為1024,標示一個集群某個業務最多部署的機器個數上限
  • 12bit序列號(自增域):表示在某一毫秒下,這個自增域最大可以分配的bit個數,在當前這種配置下,每一毫秒可以分配2^12 = 4096個數據

二、雪花算法的時間回撥問題

1. 問題描述

簡單說就是時間被調整回到了之前的時間,由于雪花算法重度依賴機器的當前時間,所以一旦發生時間回撥,將有可能導致生成的 ID 可能與此前已經生成的某個 ID 重復(前提是剛好在同一毫秒生成 ID 時序列號也剛好一致),這就是雪花算法最經常討論的問題——時間回撥

2. 現象引發

  • 網絡時間校準
  • 人工設置
  • 出現負閏秒(關于閏秒的介紹會在后面講到)

3. 常見的處理方式

3.1 直接拋出異常

在雪花算法原本的實現中,針對這種問題,算法本身只是返回錯誤,由應用另行決定處理邏輯,如果是在一個并發不高或者請求量不大的業務系統中,錯誤等待或者重試的策略問題不大,但是如果是在一個高并發的系統中,這種策略顯得過于粗暴

3.2 延遲等待

將當前線程阻塞3ms,之后再獲取時間,看時間是否比上一次請求的時間大,如果大了,說明恢復正常了,則不用管如果還小,說明真出問題了,則拋出異常,缺點仍然如3.1所描述

當使用雪花算法出現時間回撥時,不想拋異常,又希望能繼續保持全局唯一性、趨勢遞增、信息安全,可以了解第四點,基于時間序列的方案

三、基于時鐘序列解決時間回撥的方案

1. 簡介

我這里介紹的是一種基于修改擴展位的思路,基于時鐘序列的雪花算法
二進制64位長整型數字:1bit保留 + 41bit時間戳 + 3位時鐘序列 + 7bit機器 + 12bit序列號

2. 設計思路

  • 如上圖,將原本10位的機器碼拆分成3位時鐘序列及7位機器碼
  • 發生時間回撥的時候,時間已經發生了變化,那么這時將時鐘序列新增1位,重新定義整個雪花Id
  • 為了避免實例重啟引起時間序列丟失,因此時鐘序列最好通過DB/緩存等方式存儲起來

3. 算法支持

  • 還是支持最長 69 年多的運行時間
  • 分布式實例規模由210(1024)降至27(128)
  • 單實例每毫秒仍然支持 4096次請求
  • 每個分布式實例支持最多 2^3(8) 次時間回撥

4. 關鍵實現代碼

.Net Demo 其他語言參考流程自行改造

/// <summary> /// 獲取下一個ID /// </summary> /// <returns></returns> public long NextId() {lock (_lock){//當前系統時間戳var currentTimestamp = TimeGen();//出現時間回撥 當前系統時間小于最后更新時間if (currentTimestamp < _lastTimestamp){// _clockSequence自增,和CLOCK_SEQUENCE_MASK相與一下,去掉高位_clockSequence = (_clockSequence + 1) & CLOCK_SEQUENCE_MASK;}// 如果上次生成時間和當前時間相同,在同一毫秒內if (_lastTimestamp == currentTimestamp){// sequence自增,和SEQUENCE_MASK相與一下,去掉高位_sequence = (_sequence + 1) & SEQUENCE_MASK;//判斷是否溢出,也就是每毫秒內超過1024,當為1024時,與sequenceMask相與,sequence就等于0if (_sequence == 0){//等待到下一毫秒currentTimestamp = TilNextMillis(_lastTimestamp);}}else{//如果和上次生成時間不同,重置sequence,就是下一毫秒開始,sequence計數重新從0開始累加,_sequence = 0;}_lastTimestamp = currentTimestamp;return ((currentTimestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | _clockSequence << CLOCK_SEQUENCE_SHIFT | (WorkerId << WORKER_ID_SHIFT) | _sequence;} }

四、關于雪花算法的常見問題解答

1. 雪花算法支持的并發數最大多少?

  • 這個是由序列號的位數決定的,原生雪花算法序列號12位,也就是1毫秒最大可生成2^12(4096),相當于1秒可生成 4096 * 1000 個ID,也就是QPS可以到 409.6 w/s

2. 雪花算法支持最多支持系統運行多少年?

  • 這個是由時間戳位數決定的,原生雪花算法時間戳占41位,也就是支持最大的時間戳為2^41(2199023255552),而1年的總毫秒數為3600 * 1000 * 24 * 365 = 31,536,000,000,因此2^41 / 1年的總毫秒數≈69.7年

  • 其實衍生出另一個問題,41位能表示的最大的時間戳為2^41(2199023255552)對應的時間應該是2039-09-07 23:47:35,距離現在只有不到20年的時間,為什么算出來的是69年呢?

  • 其實時間戳的算法是1970年1月1日到指點時間所經過的毫秒或秒數,那咱們把開始時間從2021年開始,就可以延長41位時間戳能表達的最大時間,所以這里實際指的是相對自定義開始時間的時間戳

3. 用了雪花Id,出現負閏秒為什么會導致系統大量拋異常?

  • 閏秒是偶爾運用于協調世界時(UTC)的調整,經由增加或減少一秒,以消彌精確的時間(使用原子鐘測量)和不精確的觀測太陽時(稱為UT1),之間的差異
  • 這種做法已被證明具有破壞性,特別是在二十一世紀,尤其是在依賴精確時間戳或時間關鍵程序控制的服務中
  • 而雪花算法嚴重依賴時間戳,當出現負閏秒也就是時間減少一秒時(時間往前回撥1秒),雪花Id就可能出現重復,而原生的雪花算法出現時間回撥的處理方式是直接拋異常
  • 2022年11月,在第27屆國際計量大會上,科學家和政府代表投票決定到2035年取消閏秒

總結

以上是生活随笔為你收集整理的『SnowFlake』雪花算法的详解及时间回拨解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。