js生成唯一id_【融云分析】如何实现分布式场景下唯一 ID 生成?
?背景?
對于一套分布式部署的 IM 系統,要求每條消息的 ID 要保證在集群中全局唯一且按生成時間有序排列。如何快速高效的生成消息數據的唯一 ID ,是影響系統吞吐量的關鍵因素。那么,融云是如何做到生成全局唯一消息 ID 的呢?
首先需要明確下 ID 生成的核心需求:
1. 全局唯一
2. 有序
?設計?
融云消息數據的唯一 ID 長度采用 80 Bit 。每 5 個 Bit ,進行一次 32 進制編碼,轉換為一個字符,字符取值范圍是,( 2 ~ 9 ) 和 ( A ~ B ),其中,已經去掉容易造成肉眼混淆的,數字 0 和 1 ,及字母 O 和 I 。這樣,80 Bit 可以轉換為 16 個字符,再加上 3 個分隔符( - ),將 16 個字符分為 4 組,最終得到一個 19 字符的唯一 ID 。 這樣設計,即可以保證生成的 ID 是有序的,也能方便閱讀。
如上圖所示,80 Bit 被分為 4 段:
1. 第一段 42 Bit ,用于存放時間戳,最長可表示到 2109 年,足夠開發者當前使用了。時間戳數據放在高位,可以保證生成的唯一 ID 是按時間有序的,這個是消息 ID 必須要滿足的條件。
2. 第二段 12 Bit ,用于存放自旋轉 ID 。我們知道,時間戳的精度是到毫秒的,對于一套億級 IM 系統來說,同一毫秒內產生多條消息太正常不過了,這個自旋 ID 就是在給落到同一毫秒內的消息進行自增編號。12 Bit 則意味著,同一毫秒內,單臺主機中最多可以標識 4096( 2 的 12 次方)條消息。
3. 第三段 4 Bit ,用于標識會話類型。4 Bit ,最多可以標識 16 中會話,足夠涵蓋單聊、群聊、系統消息、聊天室、客服及公眾號等常用會話類型。
4. 第四段 22 Bit ,會話 ID 。如群聊中的群 ID ,聊天室中的聊天室 ID 等。與第三段會話類型組合在一起,可以唯一標識一個會話。其他的一些 ID 生成算法,會預留兩段,分別用來標識數據中心編號和主機編號(如 SnowFlake 算法),我們并沒有這樣做,而是將這兩段用來標識會話。這樣,ID 生成可以直接融入到業務服務中,且不必關心服務所在的主機,做到無狀態擴縮容。
?實現過程?
消息 ID 共占 80 Bit ,計算時我們分為兩部分,高 64 Bit (記為 highBits )和低 16 Bit (記為 lowBits )。
1. 獲取當前系統的時間戳,并賦值給消息 ID 的高 64 Bit ;
2. 獲取一個自旋 ID , highBits 左移 12 位,并將自旋 ID 拼接到低 12 位中;
其中,自旋 ID 是一個從 0 到 4095 范圍內,順序遞增的數,生成規則如下:
3. 上步的 highBits 左移 4 位,將會話類型拼接到低 4 位;
4. 取會話 ID 哈希值的低 22 位,記為 sessionIdInt ;
5. highBits 左移 6 位,并將 sessionIdInt 的高 6 位拼接到 highBits 的低 6 位中;
6. 取會話 ID 的低 16 位作為 lowBits ;
7. highBits 與 lowBits 拼接,得到 80 Bit 的消息 ID 。對其進行 32 進制編碼,即可得到唯一消息 ID 。編碼規則如下:從左至右,每 5 個 Bit 轉換為一個整數,以這個整數作為下標,即可在下表中找到對應的字符。
總結:
這種 ID 生成的方式,需要注意保證自旋 ID 的生成是線程安全的。避免在并發情況下,生成出同樣的 ID 。另外,此 ID 生成算法,強烈依賴系統時間,如果系統時間被改小,也可能造成 ID 生成重復。
總結
以上是生活随笔為你收集整理的js生成唯一id_【融云分析】如何实现分布式场景下唯一 ID 生成?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 长安追尾特斯拉Model X 驾驶员反怪
- 下一篇: 机械制图符号_《机械制图》试卷