id是惟一標識一條數據的,它通常沒有什麼業務含義,是系統內部的標識,那麼它每每有這樣一些特性。 mysql
總結一下,大概有下面這幾種。 redis
這種放方案是這樣的,仍是利用MySQL數據庫自身的autoincrement特性實現的,只不過每一個分庫(或者分表)的起始值不一樣,增加步長等於分庫數量,這樣各分庫的ID就不會出現重複的。這種實現方案的特色是這樣。 算法
優勢: sql
缺點: 數據庫
客戶端實現,就是在應用程序中經過一種算法來生成一個全局惟一的ID,這個算法的選擇很是關鍵。好比 snowflake 算法。 安全
優勢: 網絡
缺點: 併發
經過一個微服務來實現全局id生成服務,這個微服務的實現要作到不能生成重複值,盡肯能保持有序,生成的值儘量簡單。這種方案的特色是。 運維
優勢: 微服務
缺點:
咱們最終選擇了「獨立服務實現」方案來生成全局惟一id,下面詳細介紹這種方案的設計和實現。
該方案是這樣的。
該服務由三級ID隊列組成,分別是MySQL數據庫,H2嵌入式數據庫,內存隊列。下面分別介紹着三級的詳細設計。
該便是由一張sequence表組成,這個表就三個字段,分別是:
seqName:序列名,經過這個來獲取ID值。
currentValue:當前值,這個是一直增加的。這個值的安全增加才能保障不生成重複的值。
increment:增加步長。
該表的表引擎必須是innodb,以支持行鎖。
該表實際上模擬實現了Oracle數據的sequence特性。
這個表自己也能夠支持分庫分表,以提高它的擴展性,不過我以爲多數場景是不須要的,可是若是是大規模集中部署則須要支持該特性。
支持單個或者批量獲取ID,得到到對應的id以後就將currentValue值日後增長。
爲了作到徹底不依賴於MySQL數據庫,咱們引入了h2內存數據庫,它的表結構很是簡單,就是每一個sequence是一張表,表中就一個字段ID,而且它是主鍵。
當服務啓動的時候若數據庫中沒有足夠的ID,則會從mysql數據中補充大量的id插入到表中。這樣h2數據庫就可以支持長時間的提供服務。而且有後臺線程不斷的向h2的id隊列中補充id,避免沒有讀取的時候纔去補充id,下降性能。
內存id隊列纔是正式提供id獲取服務的,由於它直接從內存隊列中返回隊首的id值,則能夠保障極高的性能。它也會在須要補充的時候從H2內存數據庫隊列中補充必定數量的ID,也有後臺線程定時補充。它的實現是基於BlockingDeque的。
經過多級隊列咱們發現有不少邏輯是通用的,咱們是能夠抽象出一個實現自動補全隊列和範圍限定的全能隊列的,咱們命名爲AutoSuppliedAndBoundedQueue。它將一些實現了一些公共特性。包括這些內容。
這樣就有很是強的可擴展性,咱們能夠用redis實現,也能夠再增長几級隊列,增長的級數越多,整體可靠性增長,可是複雜度也就越高。須要根據實際狀況來設計。
該id生成服務具備這樣的特色。