生成全局唯一ID


方法一:基於數據庫生成

A庫、B庫、C庫支持同時寫入
A庫初始值為1,自增為3,獲取的值一次是1、4、7
B庫初始值為2,自增為3,獲取的值一次是2、5、8
C庫初始值為3,自增為3,獲取的值一次是6、6、9
獲取ID時可從三庫輪詢獲取

優點

此方法使用數據庫原有的功能,所以相對簡單
能夠保證唯一性
能夠保證遞增性
id 之間的步長是固定且可自定義的

缺點

數據庫的寫壓力依然很大,每次生成ID都要訪問數據庫
喪失了ID生成的“絕對遞增性”:先訪問DB 01生成0,3,再訪問DB 02生成1,可能導致在非常短的時間內,ID生成不是絕對遞增的

方法二:單點批量ID生成服務

數據庫使用雙master保證可用性,數據庫中只存儲當前ID的最大值
ID生成服務假設每次從數據庫批量拉取5個ID,並將當前ID的最大值修改為5,這樣應用訪問ID生成服務索要ID,ID生成服務不需要每次訪問數據庫,就能依次派發1,2,3,4,5這些ID了;當ID生成服務用完了已拉取的ID之后,再去數據庫拉取5個ID,然后將數據庫中存儲的最大值改為10,這樣數據庫的壓力就降低到原來的1/6。
ID生成服務做成集群,從數據庫獲取來的id可放入緩存(redis),當需要從數據庫獲取新的ID時,使用分布式鎖來控制,只需要其中一台服務去數據庫獲取

優點:

保證了ID生成的絕對遞增有序
大大的降低了數據庫的壓力,ID生成可以做到每秒生成幾萬幾十萬個

缺點:

ID生成服務如果掛了,服務重啟起來之后,繼續生成ID可能會不連續
雖然每秒可以生成幾萬幾十萬個ID,但畢竟還是有性能上限,無法進行水平擴展

方法三:UUID

優點

本地生成ID,不需要進行遠程調用,時延低
擴展性好,基本可以認為沒有性能上限

缺點

無法保證趨勢遞增
UUID過長,往往用字符串表示,作為主鍵建立索引查詢效率低,常見優化方案為轉化為兩個uint64整數存儲或者折半存儲

方法四:取當前毫秒數

優點

本地生成ID,不需要進行遠程調用,時延低
生成的ID趨勢遞增
生成的ID是整數,建立索引后查詢效率高

缺點

如果並發量超過1000,會生成重復的ID

方法五:使用 Redis 來生成 id

當使用數據庫來生成ID性能不夠要求的時候,我們可以嘗試使用Redis來生成ID。這主要依賴於Redis是單線程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR 和 INCRBY 來實現。

優點

依賴於數據庫,靈活方便,且性能優於數據庫。
數字ID天然排序,對分頁或者需要排序的結果很有幫助。

缺點

需要編碼和配置的工作量比較大。

方法六:Twitter 開源的 Snowflake 算法

snowflake的結構如下(每部分用-分開)
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位為未使用,接下來的41位為毫秒級時間(41位的長度可以使用69年),然后是5位datacenterId和5位workerId(10位的長度最多支持部署1024個節點) ,最后12位是毫秒內的計數(12位的計數順序號支持每個節點每毫秒產生4096個ID序號)
一共加起來剛好64位,為一個Long型。(轉換成字符串后長度最多19)
snowflake生成的ID整體上按照時間自增排序,並且整個分布式系統內不會產生ID碰撞(由datacenter和workerId作區分),並且效率較高。經測試snowflake每秒能夠產生26萬個ID。

方法七:基於分布式集群協調器生成

以強一致性為目標的:ZooKeeper為代表
以最終一致性為目標的:Consul為代表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM