生成全局唯一id的幾種方式:
1、uuid生成全球唯一id,生成方式簡單粗暴,本地生成,沒有網絡開銷,效率高;缺點長度較長,沒有遞增趨勢性,不易維護,常用於生成token令牌。
2、mysql自帶自增生成id,oracle可以用序列生成id,但在數據庫集群環境下,擴展性不好。
3、基於redis單線程的特點生成全局唯一id,redis性能高。
生成id為當前日期(yyMMddHHmmss)+6位(從000000開始不足位數補0)
20200206164329000001
4、基於雪花算法snowflake 生成全局id,本地生成,沒有網絡開銷,效率高
原理
Twitter的雪花算法SnowFlake。
SnowFlake算法產生的ID是一個64位的整型,結構如下(每一部分用“-”符號分隔):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
1位標識部分,在java中由於long的最高位是符號位,正數是0,負數是1,一般生成的ID為正數,所以為0;
41位時間戳部分,這個是毫秒級的時間,一般實現上不會存儲當前的時間戳,而是時間戳的差值(當前時間-固定的開始時間),
這樣可以使產生的ID從更小值開始;41位的時間戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年;
10位節點部分,Twitter實現中使用前5位作為數據中心標識,后5位作為機器標識,可以部署1024個節點;
12位序列號部分,支持同一毫秒內同一個節點可以生成4096個ID;
SnowFlake算法生成的ID大致上是按照時間遞增的,用在分布式系統中時,需要注意數據中心標識和機器標識必須唯一,
這樣就能保證每個節點生成的ID都是唯一的。或許我們不一定都需要像上面那樣使用5位作為數據中心標識,5位作為機器標識,可以根據我們業務的需要,靈活分配節點部分,如:若不需要數據中心,完全可以使用全部10位作為機器標識;若數據中心不多,也可以只使用3位作為數據中心,7位作為機器標識。
snowflake生成的ID整體上按照時間自增排序,並且整個分布式系統內不會產生ID碰撞(由datacenter和workerId作區分),並且效率較高。
5、 zookeeper通過創建順序節點生成全局id,在高並發場景下,性能不能很好。(暫時未研究)
redis請參考
https://github.com/sentianhui/idglobal.git