共計 2227 個字符,預計需要花費 6 分鐘才能閱讀完成。
本篇內容介紹了“關于主鍵的知識點有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓丸趣 TV 小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
1. UUID 模式
通用唯一識別碼 (Universally Unique Identifier),根據標準方法生成,不依賴中央機構的注冊和分配,UUID 具有唯一性重復 UUID 碼概率接近零,可以忽略不計。UUID 具有多個版本:基于時間的 UUID、DCE 安全的 UUID、基于名字的 UUID(MD5)(UUID.nameUUIDFromBytes())、隨機 UUID(UUID.randomUUID().toString())、基于名字的 UUID(SHA1),Version 1/ 2 適合應用于分布式計算環境下,具有高度的唯一性;Version 3/ 5 適合于需要相同內容生成相同 UUID 的業務場景下;Version 4 建議不要使用 (隨機數有可能出現重復,但是重復的概率極低,在設計時需要考慮到這一點)。
UUID 雖然解決了依賴于數據庫生成主鍵的策略,但是也存在一些不足:占用存儲空間大; 隨機生成,不具有連續性,作為主鍵時性能較差; 無法根據主鍵進行排序,確定記錄插入的先后順序; 對于開發人員不友好; 如果生成過程中使用了機器 MAC 地址,存在一定安全隱患。
2. 步長模式
即 Flickr 的 sharding 主鍵生成方案。使用多臺數據庫服務器,通過設置不同的起始值、一致自增步長,讓每個數據庫中各表主鍵保持唯一。如圖所示:
步長方式在一定程度上解決了高并發的問題,但是也存在一些問題如:擴展困難,設置好步長后,再進行擴展將會比較困難;ID 并不是按順序嚴格單調遞增的特性,只是趨勢遞增; 每次獲取 ID 仍然需要讀寫一次數據庫,仍然存在瓶頸。
3. 號段模式
即每次從數據庫獲取 id 時,從數據庫取到當前 id 最大值,然后返回 max+step,當應用程序用完這個號段后,再從數據庫獲取下一個長度為 step 的號段。為此需要專門設計一張用以記錄 id 的表,在應用服務為集群,而主鍵服務器為單點時,多個應用服務節點同時獲取 id 時,會產生沖突,可以增加 version 字段從而使用樂觀鎖進行并發訪問控制。
號段模式將主鍵緩存在應用服務端,從而減少對數據庫的訪問頻率; 在數據庫數據庫不可用時,應用服務仍然可以持續運行一段時間直到當前號段用完; 但是在應用服務重啟時有可能丟失部分 id,導致 id 增長不連續。
基于號段模式有一些成熟方案,且經過實踐驗證:美團的 Leaf-segment 對號段發放方式進行了雙 buffer 緩存及高可用容災優化。采用雙 buffer 模式,在當前號段消費到某個點時就異步的把下一個號段加載到內存中。而不需要等到號段用盡的時候才去更新號段,不會在應用服務器向數據庫請求 id 時,因為 id 號段沒有取回來,導致線程阻塞。
滴滴的 TinyId 參照了美團 Leaf 的實現方式,并對其做了擴展,增加了多 db 支持和 tinyid-client。
4. snowflake 模式 (雪花算法)
Twitter 實現的分布式 ID 生成算法。結構如下:0-00000000000000000000000000000000000000000-00000-00000-000000000000
1 bit:保留位,為符號位,全部為 0,表示生成的 id 都是正數。
41bit:時間戳,單位為毫秒,41 位可以表示 69 年的時間。
10bit:機器 id,10bit 里面 5 位代表機房 id,5 位代表機器 id,可以表示 32 個機房,每個機房里面可以用 32 臺機器。
12bit:12 位序列號,按順序遞增,記錄每個節點 1 毫秒內產生的 id,每毫秒可以產生 4096 個 id。
snowflake 的優點:
主鍵在單個節點上是按序列遞增的,能夠按照時間趨勢進行遞增。
主鍵的生成不依賴于數據庫,可以由應用程序生成。
在分布式集群內不會產生重復 id。
可以根據業務需求對 bit 位進行調整。
snowflake 的缺點:
對于時間依賴較高,如果時間回撥,則會產生主鍵重復情況。
當集群規模較大時,workid 配置會增加一定成本。
美團的 Leaf-snowflake,使用 zk 解決了 snowflake 依賴于時鐘,時間回撥產生重復主鍵問題; 百度的 UidGenerator,支持自定義時間戳、workerId、序列號等。
5. Redis 模式
利用 Redis 原子操作 INCR 和 INCRBY 來實現,使用 Redis 集群提高并發量,與步長模式類似,只不過將 id 生成器由傳統數據庫換成效率更高的 Redis 數據庫。但是當 Redis 重啟或者宕機,記錄主鍵值會丟失,所以利用 Redis 進行主鍵生成時需要對當前主鍵值進行持久化。Redis 支持 RDB 和 AOF 兩種持久化機制。RDB 模式下,可能會丟失部分未打鏡像的數據,根據快照恢復后會產生部分重復 ID,故 RDB 不適合實施持久化 Redis 數據場景。AOF 以獨立日志記錄每次寫命令,重啟時執行日志中的命令進行數據恢復,不會出現 ID 重復現象,但是會由于備份命令過多,導致 Redis 恢復數據時間較長。
以上介紹了五種數據庫主鍵的生成策略,大家可以根據具體業務場景和系統實際情況選擇一款最適合自己的主鍵策略,提升數據庫性能,保證在高并發情況下系統運行穩定性。
“關于主鍵的知識點有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注丸趣 TV 網站,丸趣 TV 小編將為大家輸出更多高質量的實用文章!