ID 生成器在微博我們一直叫發號器,微博就是用這樣的號來儲存,而我微博裡討論的時候也都是以發號器為標籤。它的主要目的確如平常大家理解的“為一個分散式系統的資料object產生一個唯一的標識”,但其實在一個真實的系統裡可能也可以承擔更多的作用。概括起來主要有以下幾點:
- 唯一性
- 時間相關
- 粗略有序
- 可反解
- 可製造
- 要唯一性,是否需要全域性唯一?
說起全域性唯一,通常大家都會在想到發號器服務,分散式的通常需要更大空間,中心式的則需要在一個合適的地方在會聚。這就可能涉及到鎖,而鎖意味著成本和效能的下降。所以當前的系統是否需要全域性的唯一性,就是一個需要考慮的問題。
比如在通訊系統裡,聊天訊息可能就未必需要全域性,因為一條訊息只是某一個人發出,系統只要保證一個人維度的唯一性即可。本質上而言,這裡利用了使用者 ID 的唯一性,因為唯一性是可以依賴的,通常我們設計系統也都是基於類似的性質,比如後面降到的使用時間唯一性的方式。 - 用時間來做什麼?千萬年太久,只爭朝夕?
前面說到唯一性可以依賴,我們需要選擇的是依賴什麼。通常的做法可以選擇資料庫自增,這在很多資料庫裡都是可以滿足ACID 的操作。但是用資料庫有個缺點,就是資料庫有效能問題,在多機房情況下也很難處理。當然,你可以通過調整自增的步長來設計,但對於一個發號器而言,操作和維護都略重了。
而時間是天然唯一的,因此也是很多設計的選擇。但對於一個8Byte的 ID 而言,時間並沒有那麼多。你如果精確到秒級別,三十年都要使用30bit,到毫秒級則要再增加10bit,你也只剩下20bit 可以做其他事情了。之所以在8Byte 上搗鼓,因為8Byte 是一個Long,不管在處理器和編譯器還是語言層面,都是可以更好地被處理。
然而三十年夠麼?對於一個人來說,可能不夠,但對一個系統而言,可能足夠。我們經常開玩笑,網際網路裡能活三十年的系統有多少呢?三十年過去,你的系統可能都被重寫 N 遍了。這樣的信心同樣來自於摩爾定律,三十年後,計算效能早就提高了上千倍,到時候更多Byte 都不會是問題了。 - 粗略有多粗略,秒還是毫秒? 餘下全文請點選這裡檢視