91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ID生成策略——SnowFlake

發布時間:2020-08-11 05:04:28 來源:ITPUB博客 閱讀:226 作者:普通程序員 欄目:數據庫

一、遇到問題


某個項目采用了數據庫(MySQL)自增ID作為主要業務數據的主鍵。數據庫自增ID使用簡單,自動編號,速度快,而且是增量增長,按順序存放,對于檢索非常有利。


單庫環境下,數據庫自增ID問題不大。但在分布式環境或分庫分表環境下,數據庫自增ID逐漸暴露出一些問題。例如,分庫分表的情況下保證ID唯一變得困難;訂單號等業務數據如果用數據庫自增ID,競對很容易算出大概的業務量


二、常見的ID生成策略


1、數據庫自增ID(前面提到了)


2、UUID

算法的核心思想是結合機器的網卡、當地時間、一個隨記數來生成UUID。

優點:本地生成,生成簡單,性能好,沒有高可用風險

缺點:長度過長,存儲冗余,且無序不可讀,查詢效率低


3、Redis生成ID

Redis生成ID可以看做數據庫自增ID的升級版。Redis的所有命令操作都是單線程的,本身提供像 incr 和 increby 這樣的自增原子命令,所以能保證生成的 ID 肯定是唯一有序的。


優點:不依賴于數據庫,靈活方便,且性能優于數據庫;數字ID天然排序,對分頁或者需要排序的結果很有幫助。

缺點:如果系統中沒有Redis,還需要引入新的組件,增加系統復雜度;需要編碼和配置的工作量比較大。


考慮到單節點的性能瓶頸,可以使用 Redis 集群來獲取更高的吞吐量。假如一個集群中有5臺 Redis。可以初始化每臺 Redis 的值分別是1, 2, 3, 4, 5,然后步長都是 5。各個 Redis 生成的 ID 為

ID生成策略——SnowFlake


4、Twitter的snowflake算法。


三、snowflake算法


snowflake算法,采用64位二進制整數。二進制具體位數含義如下圖。

ID生成策略——SnowFlake


1位,不用。二進制中最高位為1的都是負數,但是我們生成的id都使用正數,所以這個最高位固定是0


41位,用來記錄時間戳(毫秒)。

如果只用來表示正整數(計算機中正數包含0),可以表示的數值范圍是:0 至 241?1,減1是因為可表示的數值范圍是從0開始算的,而不是1。

也就是說41位可以表示241?1個毫秒的值,轉化成單位年則是(241?1)/(1000?60?60?24?365)=69年


10位,用來記錄工作機器id。

可以部署在1024個節點,包括5位datacenterId和5位workerId


12位,序列號,用來記錄同毫秒內產生的不同id。

12位(bit)可以表示的最大正整數是4095,即可以用0、1、2、3、....4095這4096個數字,來表示同一機器同一時間截(毫秒)內產生的4096個ID序號

大多數人都知道這個算法,但Twitter 利用 zookeeper 還做了很多工程上的實現,感興趣可以看https://github.com/twitter/snowflake

截取git上該工程的主要文件目錄, 

ID生成策略——SnowFlake


git工程README.md文件中有這么一段話

We have retired the initial release of Snowflake and working on open sourcing the next version based on Twitter-server, in a form that can run anywhere without requiring Twitter's own infrastructure services.


Twitter幾年前就停止了對這個項目的維護,新的版本也沒見著放出來。好在現有版本的核心算法已經能夠滿足常規的需求。


當然,snowflake有眾多優點的同時也是有缺點的。


優點:

毫秒數在高位,自增序列在低位,整個ID都是趨勢遞增的。

不依賴數據庫等第三方系統,以服務的方式部署,穩定性更高,生成ID的性能也是非常高的。

可以根據自身業務特性分配bit位,非常靈活。


缺點:

強依賴機器時鐘,如果機器上時鐘回撥,會導致發號重復或者服務會處于不可用狀態。

強依賴時鐘在有些情況下很致命,我個人就遇到過服務器剛重啟的短時間內時間沒有同步,造成生成ID出問題的情況!


四、一些改進策略


1、美團Leaf比較完美的方案


美團Leaf比較好的解決了這些問題,參看《Leaf——來自美團點評的分布式ID生成系統》

美團Leaf的方案核心有兩點

(1)依靠zookeeper實現workerId的自動化租用

(2)通過算法解決了時鐘回撥問題

美團Leaf目前是開源軟件,可以在https://github.com/weizhenyi/leaf-snowflake下載


2、一個候選人不嚴謹但成本很低的實現


我在面試中,一個候選人提出的方法也比較有意思(盡管這個方法不嚴謹)。

在redis中設置一個整數變量workerNum,初始值為0,snowflake id生成客戶端每次啟動時讀取redis中的變量,用workerNum%1024作為worker的值,然后把redis中的workerNum+1。

在idworker數量不多的情況下,這個方案一般不會出現workerId重復(因為隨著業務的迭代,一般情況下idworker過一段時間都會因為業務部署而重啟)。如果研發資源特別有限,又想使用snowflake可以考慮一下這個辦法。 

ID生成策略——SnowFlake


3、個人項目中hash分庫的解決辦法


實際使用中,有時候ID需要支持分庫分表,snowflake的默認實現對這塊支持得不夠。在業務量不大的情況下,snowflake生成的id序列號部分大多都是0,轉換為十進制會是偶數。用這個id通過取模hash分庫,顯然不平均


萬一有這樣的需求怎么辦呢?可以考慮借助ID時間戳部分實現均勻分布

(1)分庫分表邏輯使用ID中時間戳部分做取模。這個方法需要把10進制ID轉成2進制,然后移位,再進行計算。比較麻煩

(2)生成ID的時候把序列號部分尾數用時間戳對應的位置覆蓋。截段代碼,這段代碼的取值能保證ID除以128的余數均勻分布。 

ID生成策略——SnowFlake


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

孟津县| 怀化市| 象州县| 苗栗县| 光泽县| 梨树县| 胶州市| 田林县| 济源市| 盘山县| 成安县| 庄浪县| 望谟县| 灵璧县| 墨竹工卡县| 青神县| 罗源县| 陆河县| 英超| 岱山县| 榆社县| 莱阳市| 武清区| 平南县| 石泉县| 安仁县| 吴旗县| 崇左市| 石台县| 乡宁县| SHOW| 天台县| 西城区| 邛崃市| 桐庐县| 商南县| 平潭县| 锡林郭勒盟| 凤山市| 新乡市| 金堂县|