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生成