天天看點

基于redis的分布式ID生成器

https://github.com/hengyunabc/redis-id-generator

基于redis的分布式id生成器。

首先,要知道redis的eval,evalsha指令:

http://redis.readthedocs.org/en/latest/script/eval.html

http://redis.readthedocs.org/en/latest/script/evalsha.html

利用redis的lua腳本執行功能,在每個節點上通過lua腳本生成唯一id。

生成的id是64位的:

使用41 bit來存放時間,精确到毫秒,可以使用41年。

使用12 bit來存放邏輯分片id,最大分片id是4095

使用10 bit來存放自增長id,意味着每個節點,每毫秒最多可以生成1024個id

比如gtm時間 <code>fri mar 13 10:00:00 cst 2015</code> ,它的距1970年的毫秒數是 <code>1426212000000</code>,假定分片id是53,自增長序列是4,則生成的id是:

redis提供了time指令,可以取得redis伺服器上的秒數和微秒數。因些lua腳本傳回的是一個四元組。

用戶端要自己處理,生成最終id。

假定叢集裡有3個節點,則節點1傳回的seq是:

節點2傳回的seq是

節點3傳回的seq是

這樣每個節點傳回的資料都是唯一的。

下載下傳redis-script-node1.lua,并把它load到redis上。

擷取lua腳本的sha1值,可能是:

在代碼裡,通過evalsha指令,傳遞這個sha1值,就可以得到生成的id。

比如,通過指令行執行:

結果可能是:

假定叢集是3個節點,則分别對三個節點執行:

redis預設配置。

結論:

- 單節點,qps約3w

- 可以線性擴充,3個結點足以滿足絕大部分的應用

在redis-id-generator-java目錄下,有example和benchmark代碼。

在調用時,要傳入兩個參數

- tag,即為哪一類服務生成id

- shardid,即分片由哪個id生成,比如一個使用者的訂單,則分片id應該由userid來生成

隻要支援redis evalsha指令就可以了。

之前寫的一個blog:分片(sharding)的全局id生成