生成全域性唯一ID

2022-07-18 01:42:13 字數 1671 閱讀 9684

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生成不是絕對遞增的

資料庫使用雙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,但畢竟還是有效能上限,無法進行水平擴充套件

本地生成id,不需要進行遠端呼叫,時延低

擴充套件性好,基本可以認為沒有效能上限

無法保證趨勢遞增

uuid過長,往往用字串表示,作為主鍵建立索引查詢效率低,常見優化方案為轉化為兩個uint64整數儲存或者折半儲存

本地生成id,不需要進行遠端呼叫,時延低

生成的id趨勢遞增

生成的id是整數,建立索引後查詢效率高

如果併發量超過1000,會生成重複的id

當使用資料庫來生成id效能不夠要求的時候,我們可以嘗試使用redis來生成id。這主要依賴於redis是單執行緒的,所以也可以用生成全域性唯一的id。可以用redis的原子操作 incr 和 incrby 來實現。

依賴於資料庫,靈活方便,且效能優於資料庫。

數字id天然排序,對分頁或者需要排序的結果很有幫助。

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

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為代表

SnowFlake 生成全域性唯一id

public class snowflakeutil 外部呼叫獲取snowflakeutil的例項物件,確保不可變 return public static snowflakeutil get 初始化構造,無參構造有參函式,預設節點都是0 public snowflakeutil 設定機器節點和資料...

使用redis生成全域性唯一id

生成唯一客戶編碼 需求 1.id生成有一定規則,可識別 2.全域性保持唯一,支援分布式 思路 1.年月日 每日自增數 2.每天23 59 59秒把自增數清0 優勢 1.通過年月日可以看出使用者註冊時間 2.通過自增數可以看出每日註冊量 使用redis原因 redis本身單執行緒,不會出現併發問題 r...

(備忘)c 中生成全域性唯一id

c 在要生成唯一標示的id,不用自己去設計演算法,直接用boost中的boost uuids random generator 隨機生成器即可。生成隨機數 guid 即globally unique identifier 全球唯一識別符號 也稱作 uuid universally unique id...