有哪些問題?
時鐘回撥問題;
趨勢遞增,而不是絕對遞增;
不能在一臺服務(wù)器上部署多個分布式ID服務(wù);
如何解決時鐘回撥?
以百度的UidGenerator為例,CachedUidGenerator方式主要通過采取如下一些措施和方案規(guī)避了時鐘回撥問題和增強唯一性:
自增列:UidGenerator的workerId在實例每次重啟時初始化,且就是數(shù)據(jù)庫的自增ID,從而完美的實現(xiàn)每個實例獲取到的workerId不會有任何沖突。
RingBuffer:UidGenerator不再在每次取ID時都實時計算分布式ID,而是利用RingBuffer數(shù)據(jù)結(jié)構(gòu)預先生成若干個分布式ID并保存。
時間遞增:傳統(tǒng)的雪花算法實現(xiàn)都是通過System.currentTimeMillis()來獲取時間并與上一次時間進行比較,這樣的實現(xiàn)嚴重依賴服務(wù)器的時間。而UidGenerator的時間類型是AtomicLong,且通過incrementAndGet()方法獲取下一次的時間,從而脫離了對服務(wù)器時間的依賴,也就不會有時鐘回撥的問題
(這種做法也有一個小問題,即分布式ID中的時間信息可能并不是這個ID真正產(chǎn)生的時間點,例如:獲取的某分布式ID的值為3200169789968523265,它的反解析結(jié)果為{"timestamp":"2019-05-02 23:26:39","workerId":"21","sequence":"1"},但是這個ID可能并不是在"2019-05-02 23:26:39"這個時間產(chǎn)生的)。