簡單轉下snowflak的介紹

2021-08-03 12:09:18 字數 1754 閱讀 5855

2015/04/06

·25 comments

twitter-snowflake演算法產生的背景相當簡單,為了滿足twitter每秒上萬條訊息的請求,每條訊息都必須分配一條唯一的id,這些id還需要一些大致的順序(方便客戶端排序),並且在分布式系統中不同機器產生的id必須不同。

把時間戳,工作機器id,序列號組合在一起。

除了最高位bit標記為不可用以外,其餘三組bit佔位均可浮動,看具體的業務需求而定。預設情況下41bit的時間戳可以支援該演算法使用到2023年,10bit的工作機器id可以支援1023臺機器,序列號支援1毫秒產生4095個自增序列id。下文會具體分析。

這裡時間戳的細度是毫秒級,具體**如下,建議使用64位linux系統機器,因為有vdso,gettimeofday()在使用者態就可以完成操作,減少了進入核心態的損耗。

1

2

3

4

5

6

uint64_t generatestamp()

預設情況下有41個bit可以供使用,那麼一共有t(1llu << 41)毫秒供你使用分配,年份 = t / (3600 * 24 * 365 * 1000) = 69.7年。如果你只給時間戳分配39個bit使用,那麼根據同樣的演算法最後年份 = 17.4年。

嚴格意義上來說這個bit段的使用可以是程序級,機器級的話你可以使用mac位址來唯一標示工作機器,工作程序級可以使用ip+path來區分工作程序。如果工作機器比較少,可以使用配置檔案來設定這個id是乙個不錯的選擇,如果機器過多配置檔案的維護是乙個災難性的事情。

這裡的解決方案是需要乙個工作id分配的程序,可以使用自己編寫乙個簡單程序來記錄分配id,或者利用mysql auto_increment機制也可以達到效果。

工作程序與工作id分配器只是在工作程序啟動的時候互動一次,然後工作程序可以自行將分配的id資料落檔案,下一次啟動直接讀取檔案裡的id使用。

ps:這個工作機器id的bit段也可以進一步拆分,比如用前5個bit標記程序id,後5個bit標記執行緒id之類:d

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

1

2

3

4

5

6

7

8

uint64_t waitnextms(uint64_t laststamp)

while(cur <= laststamp);

returncur;

}

總體來說,是乙個很高效很方便的guid產生演算法,乙個int64_t欄位就可以勝任,不像現在主流128bit的guid演算法,即使無法保證嚴格的id序列性,但是對於特定的業務,比如用做遊戲伺服器端的guid產生會很方便。另外,在多執行緒的環境下,序列號使用atomic可以在**實現上有效減少鎖的密度。

參考資料:

(全文結束)

mysql的簡單介紹 mysql的簡單介紹

mysql的簡單介紹 資料庫的內部鏈結 1 連線管理器 使用者或應用程式連線 2 分析器 3 快取區4 優化器 優化器執行的結果交由儲存引擎,再轉向物理層 表空間 myisam每個表有三個檔案 frm 表結構 myd 表資料 myi 表索引 innodb 所有表空間再乙個檔案 資料庫失敗的原因 1 ...

簡單的 介紹 樹形DP介紹

給定一棵有n個節點的樹 通常是無根樹,也就是有n 1條無向邊 我們可以任選乙個節點為根節點,從而定義出每個節點的深度和每棵子樹的根。在樹上設計動態規劃演算法時,一般就以節點從深到淺 子樹從小到大 的順序作為dp的 階段 dp的狀態表示中,第一維通常是節點編號 代表以該節點為根的子樹 大多數時候,我們...

ORACLE SEQUENCE的簡單介紹

在oracle中sequence就是所謂的序列號,每次取的時候它會自動增加,一般用在需要按序列號排序的地方。1 create sequence 你首先要有create sequence或者create any sequence許可權,create sequence emp sequence incr...