回覆列表
-
1 # 此生唯一
-
2 # 會點程式碼的大叔
關於這個問題,有幾個方案和大家分享一下。
利用資料庫生成先說最笨的方法,利用資料庫的自增長序列生成,資料庫內唯一。
優點:理解起來最容易,用起來也最容易。
缺點:也非常明顯了,每種資料庫的實現不同,如果資料庫需要遷移的話比較麻煩;最大的問題是效能問題,不太好擴充套件,如果併發大的時候,資料庫很可能扛不住。
利用Redis/MongoDB/zookeeper生成Redis的單執行緒的,利用incr和increby;MongoDB的ObjectId;ZK透過znode資料版本;都可以生成全域性的唯一標識碼。
優點:效能高於資料庫;可以使用叢集部署。
缺點:需要引入對應的元件,增加系統的複雜度。
UUID這個是分散式架構中,生成唯一標識碼最常用的演算法。
UUID有基於MAC地址的,加上時間和時鐘序列的,也有基於偽隨機數的,基於加密雜湊的。
優點:本地生成,不需要第三方元件,生成比較簡單,效能好。
缺點:長度長,不利於儲存,並且沒有排序,是個字串,不利於查詢。解決無序問題,可參考Comb演算法(combined guid/timestamp)。
SnowflakeTwitter開源,基於zk,41位時間戳(毫秒數)+10位機器的ID+12位毫秒內的流水號+1位符號位(永遠是0)。
優點:效能不錯,單機內遞增。
缺點:依賴zk;依賴於機器時鐘,分散式環境內可能會不是全域性遞增。
UidGenerator百度開源,基於snowflake演算法。
Leaf美團開源。
優點:能保證全域性唯一性、高可用、趨勢遞增(不太安全,比如洩露公司訂單數量)、單調遞增等。
缺點:依然會依賴第三方元件,zk或資料庫。
現在分散式大行其道,由於資料庫分佈在不同的伺服器上,如果用傳統的自增等方式生成ID,不同的資料庫上的ID難以保證不重複,而有業務影響風險!
可以說唯一標識碼是分散式資料庫所要面臨的第一道關!
我接觸分散式多年,對於唯一標識碼的生成遇見過這麼幾種方式!
1,UUID:演算法有很多種,使用同一臺機器上的時間生成位元組來區分同一臺機器上的不同ID,使用IEEE機器識別號或者IP地址等來區分不同機器上的ID,這樣不同的機器間和同一個機器都進行了區分,保證生成的UUID是全域性唯一的!
JAVA有自帶的UUID.randomUUID()演算法來實現!
侷限性:生成的ID沒有順序性!
2,snowflake:twitter自己開發的唯一ID演算法,使用41位時間序列,10位機器號的標誌,12位的順序的計數,每毫秒可以生成4096個唯一序列號!
3,基於redis的原子函式incr或者incrby方法:因為redis是單執行緒的工作模式,利用自增方法可以得到全域性唯一的ID,不過如果是沒有引入redis元件的,可能需要額外的成本!
4,mongodb的objectid:因為mongodb一開始就是為了分散式而生,所以生成objectID演算法也保證全域性唯一性!生成的objectID也是由時間戳+機器唯一標誌+程序ID+計數器!每秒鐘可以生成2563個不一樣的objectID!
以上是我用過的唯一ID生成演算法,有問題隨時找我交流!更多的技術分享,敬請關注。。