分布式ID生成之雪花算法
唯一ID可以標(biāo)識(shí)數(shù)據(jù)的唯一性,在分布式系統(tǒng)中生成唯一ID的方案有很多,常見(jiàn)的方式大概有以下三種:
- 依賴(lài)數(shù)據(jù)庫(kù),使用如MySQL自增列或Oracle序列等。
- UUID隨機(jī)數(shù)
- snowflake雪花算法(本文將要討論)
一、數(shù)據(jù)庫(kù)和UUID方案的不足之處
采用數(shù)據(jù)庫(kù)自增序列:
- 讀寫(xiě)分離時(shí),只有主節(jié)點(diǎn)可以進(jìn)行寫(xiě)操作,可能有單點(diǎn)故障的風(fēng)險(xiǎn)
- 分表分庫(kù),數(shù)據(jù)遷移合并等比較麻煩
UUID隨機(jī)數(shù):
- 采用無(wú)意義字符串,沒(méi)有排序
- UUID使用字符串形式存儲(chǔ),數(shù)據(jù)量大時(shí)查詢(xún)效率比較低
二、關(guān)于雪花算法
有這么一種說(shuō)法,自然界中并不存在兩片完全一樣的雪花的。每一片雪花都擁有自己漂亮獨(dú)特的形狀、獨(dú)一無(wú)二。雪花算法也表示生成的ID如雪花般獨(dú)一無(wú)二。
1. 雪花算法概述
雪花算法生成的ID是純數(shù)字且具有時(shí)間順序的。其原始版本是scala版,后面出現(xiàn)了許多其他語(yǔ)言的版本如Java、C++等。
2. 組成結(jié)構(gòu)
大致由:首位無(wú)效符、時(shí)間戳差值,機(jī)器(進(jìn)程)編碼,序列號(hào)四部分組成。
3. 特點(diǎn)(自增、有序、適合分布式場(chǎng)景)
- 時(shí)間位:可以根據(jù)時(shí)間進(jìn)行排序,有助于提高查詢(xún)速度。
- 機(jī)器id位:適用于分布式環(huán)境下對(duì)多節(jié)點(diǎn)的各個(gè)節(jié)點(diǎn)進(jìn)行標(biāo)識(shí),可以具體根據(jù)節(jié)點(diǎn)數(shù)和部署情況設(shè)計(jì)劃分機(jī)器位10位長(zhǎng)度,如劃分5位表示進(jìn)程位等。
- 序列號(hào)位:是一系列的自增id,可以支持同一節(jié)點(diǎn)同一毫秒生成多個(gè)ID序號(hào),12位的計(jì)數(shù)序列號(hào)支持每個(gè)節(jié)點(diǎn)每毫秒產(chǎn)生4096個(gè)ID序號(hào)
snowflake算法可以根據(jù)項(xiàng)目情況以及自身需要進(jìn)行一定的修改。
三、雪花算法的缺點(diǎn)
雪花算法在單機(jī)系統(tǒng)上ID是遞增的,但是在分布式系統(tǒng)多節(jié)點(diǎn)的情況下,所有節(jié)點(diǎn)的時(shí)鐘并不能保證不完全同步,所以有可能會(huì)出現(xiàn)不是全局遞增的情況。
四、總結(jié)
分布式唯一ID的方案有很多,本文主要討論了雪花算法,組成結(jié)構(gòu)大致分為了無(wú)效位、時(shí)間位、機(jī)器位和序列號(hào)位。其特點(diǎn)是自增、有序、純數(shù)字組成查詢(xún)效率高且不依賴(lài)于數(shù)據(jù)庫(kù)。適合在分布式的場(chǎng)景中應(yīng)用,可根據(jù)需求調(diào)整具體實(shí)現(xiàn)細(xì)節(jié)。