1. 程式人生 > >基於Snowflake的分散式唯一ID生成器

基於Snowflake的分散式唯一ID生成器

專案地址

常見的UID優缺點

資料庫自增ID

簡單可靠,有序,可讀性好,效能也不錯。缺點是要鎖表,效能會有瓶頸,分庫特別是已分庫的情況再擴容時會比較麻煩。

UUID

全球唯一,效能好,缺點是太長了,儲存空間大,索引效能不好,長度太長使用起來也不方便。另外部分UUID演算法生成的不是趨勢遞增的。

Redis生成

效能好,有序,可讀性好。缺點是為了防單點故障,需要引入Redis叢集,增加了額外編碼和配置的工作量。

Snowflake生成ID

twitter開發的一套全域性唯一ID生成演算法,要點如下:

41位的時間序列(精確到毫秒,41位的長度可以使用69年)
10位的機器標識(10位的長度最多支援部署1024個節點)
12位的計數順序號(12位的計數順序號支援每個節點每毫秒產生4096個ID序號)
最高位是符號位,始終為0。
簡單可靠,效能好,趨勢有序,不引入第三方系統。缺點是有使用時間限制,8-100年不等,序列不是連續有序。

如何選擇

在分散式下,考慮到效能,儲存效率和使用方便性,一般不會直接用UUID來做表唯一欄位的ID的。另外UUID有可能洩露MAC地址。

如果沒有分庫的話,用資料庫自增ID是不錯的選擇。

如果有分庫可以使用不同步長的自增ID來避免衝突,如果還有繼續擴容的可能的話,建議直接使用Redis或Snowflake的方案。

如果對連續性有要求的話,建議使用Redis生成方案,如果對連續性沒有要求或者要求乾淨輕爽的方式的話,建議使用Snowflake方案。

另外連續ID有可能洩露業務資訊,根據早晚的ID號,很容易推算出一天的業務量。

Snowflake的改進實現

各開源專案都基於原始演算法做了點改進,比如:處理時間回撥問題,調整各段的位數,使用快取增強併發效能。在虛擬環境下,如k8s下,如何避免多個例項出現相同的worker id等。

比較好的實現有:

我的實現主要是參考了百度的實現。所不同的是,進一步做了簡化,百度使用一個數據庫表來儲存worker id的資訊,每次例項啟動的時候給一個新號,可以支援幾百萬次重啟。我的實現是去掉了資料庫依賴,直接根據機器的IP後24位做worker id。在k8s環境下,網路CIDR預設是-/24,也就是最後24位是不同的,所以用24位IP來做worker id是可以完全避免衝突。相應的,單例每秒的序列號數量有所減少,只有2048個,不過對大部分應用也是夠用的。

另外補充解釋下,為啥要用這麼多位數用於避免worker id重複,實際部署的系統一般也就幾百幾千臺機器/虛擬機器,直接為不同的應用指定不同的id不就完了嗎?這主要是考慮在Spring Cloud或者k8s這樣的環境裡,每個應用是有可能同時開好幾個例項的,如果worker id是硬編碼或者固定配置的,那所有相同應用的例項都會是相同的worker id,肯定會造成UID衝突的。所以就需要有一個渠道能得到唯一的id。那這個渠道在類似k8s這樣的虛擬環境下,無非是資料庫儲存,或者pod ip了。我嫌用資料庫又多引進了一個依賴,希望一個儘可能獨立乾淨的實現,所以我使用ip後24位的方式來做worker id。如果將k8s POD網路的CIDR設成-/16的,那就更完美了,用ip的後16位做唯一worker id,同時把時間位和序列位各加4個,那就可以支援單例每秒32768個序列,連續使用128年了。

相關推薦

基於Snowflake分散式唯一ID生成器

專案地址 常見的UID優缺點 資料庫自增ID 簡單可靠,有序,可讀性好,效能也不錯。缺點是要鎖表,效能會有瓶頸,分庫特別是已分庫的情況再擴容時會比較麻煩。 UUID 全球唯一,效能好,缺點是太長了,儲存空間大,索引效能不好,長度太長使用起來

分散式唯一ID生成器Twitter 的 Snowflake idworker java版本

import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.NetworkInterface; /** * <p>名稱:IdWorker.java</p&

分散式唯一ID生成器Twitter

分散式系統中,有一些需要使用全域性唯一ID的場景,這種時候為了防止ID衝突可以使用36位的UUID,但是UUID有一些缺點,首先他相對比較長,另外UUID一般是無序的。 有些時候我們希望能使用一種簡單一些的ID,並且希望ID能夠按照時間有序生成。 /** * Twitter_Sno

Spring-boot+分散式下高效能全域性物件唯一ID生成器程式碼+例項演示

     最近做起了資料優化的工作,主要是針對物件模型資料的匯入,這裡透漏下成效:利用mybatis的批量插入,1000條資料的匯入(insert)只用了52ms甚至根據機子的效能可以更快,當然這只是針對insert層的優化,還有一個更要命更耗時的就是,物件主鍵ID的獲取,

分散式唯一ID:雪花ID Snowflake .Net版

先抄個雪花ID介紹,雪花演算法: 雪花演算法的原始版本是scala版,用於生成分散式ID(純數字,時間順序),訂單編號等。 自增ID:對於資料敏感場景不宜使用,且不適合於分散式場景。GUID:採用無意義字串,資料量增大時造成訪問過慢,且不宜排序。 演算法描述: 最高位是符號位,始終為0,不

分布式唯一id生成器的想法

alt 順序 class logs 版本號 id號 一半 其中 分析 0x01 起因 前端時間遇到一個問題,怎麽快速生成唯一的id,後來采用了hashid的方法。最近在網上讀到了美團關於分布式唯一id生成器的解決方案, 其中提到了三種生成法:(建議看一下這篇文章,寫得很詳細

生成分散式唯一ID的幾種解決方案

分散式ID的特性 唯一性:確保生成的ID是全網唯一的。 有序遞增性:確保生成的ID是對於某個使用者或者業務是按一定的數字有序遞增的。 高可用性:確保任何時候都能正確的生成ID。 帶時間:ID裡面包含時間,一眼掃過去就知道哪天的交易。 1. UUID UUID

Spring Boot 工程整合全域性唯一ID生成器 Vesta

本文內容腦圖如下: 文章共 760字,閱讀大約需要 2分鐘 ! 概 述 在前一篇文章 《Spring Boot工程整合全域性唯一ID生成器 UidGenerator》 中給大家推薦了一款由百度開發的基於 Snowflake演算法實現的全域性唯一ID生成器 Uid

SnowFlake全域性唯一ID及工具類

正經學徒,佛系記錄,不搞事情 一、什麼是SnowFlake twitter 用於生成id的演算法 真面目:64位的二進位制 1位,不用。二進位制中最高位為1的都是負數,但是我們生成的id一般都使用整數,所以這個最高位固定是0 41位,用來記錄時間戳(毫秒)。 4

從零到日誌採集索引視覺化、監控報警、rpc trace跟蹤-分散式唯一ID生成

public class UniqueIdGen implements IdGen {    // 開始使用該演算法的時間為: 2017-01-01 00:00:00private static final long START_TIME = 1483200000000L;// 時間戳bit數,最多能支援到2

分散式唯一ID生成服務

      SNService是一款基於分散式的唯一ID生成服務,主要用於提供大數量業務資料建立唯一ID的需要;服務提供最低10K/s的唯一ID請求處理.如果你部署服務的CPU資源達到4核的情況下那該服務最低可以提供100K/s的請求處理能力.服務支援部署到Linux mono 3.2.3和Windows .

分布式唯一ID生成器Twitter

計數 中心 裏的 部署 如果 exti 需要 param epo 分布式系統中,有一些需要使用全局唯一ID的場景,這種時候為了防止ID沖突可以使用36位的UUID,但是UUID有一些缺點,首先他相對比較長,另外UUID一般是無序的。 有些時候我們希望能使用一種簡單一些的I

全域性唯一ID生成器(SnowFlakeId演算法JAVA實現)

import org.apache.commons.lang3.RandomUtils; import java.util.Random; /** * @Description: 全域性唯一Id生成器 * @Author: guanfengliang * @Ema

Java工具類-基於SnowFlake的短地址生成器

Twitter的SnowFlake演算法,使用SnowFlake演算法生成一個整數,然後轉化為62進制變成一個短地址URL /** * Twitter的SnowFlake演算法,使用SnowFlake演算法生成一個整數,然後轉化為62進制變成一個短地址URL * @author

黑馬十次方專案day01-10之分散式id生成器

文章目錄 為什麼要用分散式的id生成器 寫IdWorker分散式id生成器的類 為什麼要用分散式的id生成器 因為微服務的專案中,每個專案都是一個容器,每個容器都可能操作同一張表. 如果採用傳

全域性唯一ID生成器淺析IdGen (1)

轉載出處。http://www.blogjava.net/bolo 局唯一ID生成器淺析 我們在開發中,有時非常需要一個全域性唯一的ID值,不管是業務需求,還是為了以後可能的分表需求,全域性唯一值都非常有用,本篇大象就來講講這個實現並對ID生成器效能

研究分散式唯一ID生成,看完這篇就夠

  很多大的網際網路公司資料量很大,都採用分庫分表,那麼分庫後就需要統一的唯一ID進行儲存。這個ID可以是數字遞增的,也可以是UUID型別的。   如果是遞增的話,那麼拆分了資料庫後,可以按照id的hash,均勻的分配到資料庫中,並且mysql資料庫如果將遞增的欄位作為主鍵儲存的話會大大提高儲存速度。但是如

分散式唯一ID生成演算法-雪花演算法

在我們的工作中,資料庫某些表的欄位會用到唯一的,趨勢遞增的訂單編號,我們將介紹兩種方法,一種是傳統的採用隨機數生成的方式,另外一種是採用當前比較流行的“分散式唯一ID生成演算法-雪花演算法”來實現。   一、時間戳隨機數生成唯一ID 我們寫一個for迴圈,用RandomUtil.generateOr

【系統設計】分散式唯一ID生成方案總結

目錄 分散式系統中唯一ID生成方案 1. 唯一ID簡介 2. 全域性ID常見生成方案 2.1 UUID生成 2.2 資料庫生成 2.3 Redis生成 2.4

基於Spring Boot的可直接執行的分散式ID生成器的實現以及SnowFlake演算法詳解

背景 最近對snowflake比較感興趣,就看了一些分散式唯一ID生成器(發號器)的開源專案的原始碼,例如百度的uid-generator,美團的leaf。大致看了一遍後感覺uid-generator程式碼寫的要更好一些,十分的精煉,短小精悍。 正好手頭有個任務要搞個發號器,百度的這個原始碼是不能直接執行