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