雪花算法的原理和实现

鐐瑰嚮涓婃柟鈥滆彍楦熺闈粹€濓紝閫夋嫨鈥滃叧娉ㄢ€?/p>

鎴戜滑涓€璧峰紑鍚疨ython杩涢樁涔嬫梾锛?/p>

                                 author锛?nbsp; Monday  

                          ~  (鍛ㄤ竴锛屽懆鑰屽濮嬶紝濮嬬粓濡備竴)

hello 澶у濂芥垜鏄疢onday锛屼粖澶╁拰澶у鑱婅亰鍏充簬闆姳绠楁硶鐨勫師鐞嗗拰瀹炵幇锛?/p>

<!--more-->

涓€銆侀洩鑺辩畻娉曠殑璧锋簮锛歴nowflake涓枃鐨勬剰鎬濇槸 闆姳锛岄洩鐗囷紝鎵€浠ョ炕璇戞垚闆姳绠楁硶銆傚畠鏈€鏃╂槸twitter鍐呴儴浣跨敤鐨勫垎甯冨紡鐜涓嬬殑鍞竴ID鐢熸垚绠楁硶銆傚湪2014骞村紑婧愩€傚紑婧愮殑鐗堟湰鐢眘cala缂栧啓锛屽ぇ瀹跺彲浠ュ啀鎵句釜鍦板潃鎵惧埌杩欑増鏈€?/p>

https://github.com/twitter-archive/snowflake/tags

snowflake/IdWorker.scala at snowflake-2010 路 twitter-archive/snowflake (github.com)

浜屻€侀洩鑺辩畻娉曚骇鐢熺殑鑳屾櫙锛?/p>

闆姳绠楁硶浜х敓鐨勮儗鏅綋鐒舵槸twitter楂樺苟鍙戠幆澧冧笅瀵瑰敮涓€ID鐢熸垚鐨勯渶姹傦紝寰楃泭浜巘witter鍐呴儴鐗涢€肩殑鎶€鏈紝闆姳绠楁硶娴佷紶鑷充粖骞惰骞挎硾浣跨敤銆傚畠鑷冲皯鏈夊涓嬪嚑涓壒鐐癸細

1銆佽兘婊¤冻楂樺苟鍙戝垎甯冨紡绯荤粺鐜涓婭D涓嶉噸澶?銆佸熀浜庢椂闂存埑锛屽彲浠ヤ繚璇佸熀鏈湁搴忛€掑锛堟湁浜涗笟鍔″満鏅杩欎釜鍙堣姹傦級3銆佷笉渚濊禆绗笁鏂圭殑搴撴垨鑰呬腑闂翠欢4銆佺敓鎴愭晥鐜囨瀬楂?p>涓夈€侀洩鑺辩畻娉曞師鐞嗭細

闆姳绠楁硶鐨勫師鐞嗗氨鏄敓鎴愪竴涓殑64浣嶆瘮鐗逛綅鐨?long 绫诲瀷鐨勫敮涓€ id銆?/p>

鏈€楂?浣嶅浐瀹氬€?锛屽洜涓虹敓鎴愮殑 id 鏄鏁存暟锛屽鏋滄槸1灏辨槸璐熸暟浜?鏈娇鐢?銆?/p>

鎺ヤ笅鏉?1浣嶅瓨鍌ㄦ绉掔骇鏃堕棿鎴筹紝2^41/(1000*60*60*24*365)=69锛屽ぇ姒傚彲浠ヤ娇鐢?9骞淬€?/p>

鍐嶆帴涓?0浣嶅瓨鍌ㄦ満鍣ㄧ爜锛屽寘鎷?浣?datacenterId 鍜?浣?workerId銆傛渶澶氬彲浠ラ儴缃?^10=1024鍙版満鍣ㄣ€?/p>

鏈€鍚?2浣嶅瓨鍌ㄥ簭鍒楀彿銆傚悓涓€姣鏃堕棿鎴虫椂锛岄€氳繃杩欎釜閫掑鐨勫簭鍒楀彿鏉ュ尯鍒嗐€傚嵆瀵逛簬鍚屼竴鍙版満鍣ㄨ€岃█锛屽悓涓€姣鏃堕棿鎴充笅锛屽彲浠ョ敓鎴?^12=4096涓笉閲嶅 id锛屾墍浠ユ渶澶у彲浠ユ敮鎸佸崟鑺傜偣宸笉澶氬洓鐧句竾鐨勫苟鍙戦噺锛岃繖涓Ε濡ョ殑澶熺敤浜嗐€?/p>

鎴戜滑琛ュ厖璇﹁В涓€涓?1浣嶇殑姣鍗曚綅鐨勬椂闂存埑锛屾垜浠彲浠ヨ绠椾笅锛?/p>2^41/1000锛堟绉掞級*60锛堢锛?60锛堝垎閽燂級*24锛堝皬鏃讹級*365锛堝ぉ锛?= 69

涔熷氨鏄繖涓椂闂存埑鍙互浣跨敤69骞翠笉閲嶅锛岃繖涓浜庡ぇ閮ㄥ垎绯荤粺澶熺敤浜嗐€?/p>

寰堝浜鸿繖閲屼細鎼為敊姒傚康锛岃繖涓椂闂存埑鏄浉瀵逛簬涓€涓垜浠笟鍔′腑鎸囧畾鐨勬椂闂达紙涓€鑸槸绯荤粺涓婄嚎鏃堕棿锛夛紝鑰屼笉鏄?970骞淬€傝繖閲屼竴瀹氳娉ㄦ剰銆?/p>

涓夈€佷娇鐢ㄦ柟寮忥細

鍙互灏嗛洩鑺辩畻娉曚綔涓轰竴涓崟鐙殑鏈嶅姟杩涜閮ㄧ讲锛岀劧鍚庨渶瑕佸叏灞€鍞竴 id 鐨勭郴缁燂紝璇锋眰闆姳绠楁硶鏈嶅姟鑾峰彇 id 鍗冲彲銆?/p>

锛?锛夊畨瑁卲ython绗笁鏂瑰寘锛?/p>pip install pysnowflak

锛?锛夊惎鍔ㄦ湇鍔?/p>

鍚姩pysnowflake 鈥攑ysnowflake鍩轰簬Tornado寮€鍙戯紝鍚姩鏃剁浉褰撲簬涓€涓湇鍔?/p>snowflake_start_server --address=127.0.0.1 --port=8910 --dc=1 --worker=1 --log_file_prefix=./pysnowflask.log

鍙傛暟璇存槑锛氬彲浠ラ€氳繃鈥揾elp鏌ョ湅

鈥攁ddress锛氭湰鏈虹殑IP鍦板潃榛樿localhost

鈥攄c锛氭暟鎹腑蹇冨敮涓€鏍囪瘑绗﹂粯璁や负0

鈥攚orker锛氬伐浣滆€呭敮涓€鏍囪瘑绗﹂粯璁や负0

鈥攍og_file_prefix锛氭棩蹇楁枃浠舵墍鍦ㄤ綅缃?/p>

锛?锛夎皟鐢ㄦ湇鍔¤幏鍙杋d

import snowflake.clientdef get_snowflake_uuid(): guid = snowflake.client.get_guid()    return guidres = get_snowflake_uuid()print(res)

鍥涖€侀洩鑺辩畻娉曚紭鐐癸細

楂樺苟鍙戝垎甯冨紡鐜涓嬬敓鎴愪笉閲嶅 id锛屾瘡绉掑彲鐢熸垚鐧句竾涓笉閲嶅 id銆?/p>

鍩轰簬鏃堕棿鎴筹紝浠ュ強鍚屼竴鏃堕棿鎴充笅搴忓垪鍙疯嚜澧烇紝鍩烘湰淇濊瘉 id 鏈夊簭閫掑銆?/p>

涓嶄緷璧栫涓夋柟搴撴垨鑰呬腑闂翠欢銆?/p>

绠楁硶绠€鍗曪紝鍦ㄥ唴瀛樹腑杩涜锛屾晥鐜囬珮銆?/p>

浜斻€侀洩鑺辩畻娉曟湁濡備笅缂虹偣锛?/p>

渚濊禆鏈嶅姟鍣ㄦ椂闂达紝鏈嶅姟鍣ㄦ椂閽熷洖鎷ㄦ椂鍙兘浼氱敓鎴愰噸澶?id銆傜畻娉曚腑鍙€氳繃璁板綍鏈€鍚庝竴涓敓鎴?id 鏃剁殑鏃堕棿鎴虫潵瑙e喅锛屾瘡娆$敓鎴?id 涔嬪墠姣旇緝褰撳墠鏈嶅姟鍣ㄦ椂閽熸槸鍚﹁鍥炴嫧锛岄伩鍏嶇敓鎴愰噸澶?id銆?/p>

鍏€佽嚜宸卞疄鐜伴洩鑺辩畻娉曪紙python鐗堬級锛?/p># Twitters Snowflake algorithm implementation which is used to generate distributed IDs.# timeimport loggingclass InvalidSystemClock(Exception): """ 鏃堕挓鍥炴嫧寮傚父 """ pass# 64浣岻D鐨勫垝鍒哤ORKER_ID_BITS = 5DATACENTER_ID_BITS = 5SEQUENCE_BITS = 12# 鏈€澶у彇鍊艰绠桵AX_WORKER_ID = -1 ^ (-1 << WORKER_ID_BITS) # 2**5-1 0b11111MAX_DATACENTER_ID = -1 ^ (-1 << DATACENTER_ID_BITS)# 绉讳綅鍋忕Щ璁$畻WOKER_ID_SHIFT = SEQUENCE_BITSDATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITSTIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS# 搴忓彿寰幆鎺╃爜SEQUENCE_MASK = -1 ^ (-1 << SEQUENCE_BITS)# Twitter鍏冨勾鏃堕棿鎴砊WEPOCH = 57# logger = logging.getLogger(flask.app)class IdWorker(object): """ 鐢ㄤ簬鐢熸垚IDs """ def __init__(self, datacenter_id, worker_id, sequence=0): """ 鍒濆鍖? :param datacenter_id: 鏁版嵁涓績锛堟満鍣ㄥ尯鍩燂級ID :param worker_id: 鏈哄櫒ID :param sequence: 搴忓彿 """ # sanity check if worker_id > MAX_WORKER_ID or worker_id < 0: raise ValueError(worker_id鍊艰秺鐣? if datacenter_id > MAX_DATACENTER_ID or datacenter_id < 0: raise ValueError(datacenter_id鍊艰秺鐣? self.worker_id = worker_id self.datacenter_id = datacenter_id self.sequence = sequence self.last_timestamp = -1 # 涓婃璁$畻鐨勬椂闂存埑 def _gen_timestamp(self): """ 鐢熸垚鏁存暟鏃堕棿鎴? :return:int timestamp """ return int(time.time() * 1000) def get_id(self): """ 鑾峰彇鏂癐D :return: """ timestamp = self._gen_timestamp() # 鏃堕挓鍥炴嫧 if timestamp < self.last_timestamp: logging.error(clock is moving backwards. Rejecting requests until {}.format(self.last_timestamp)) raise InvalidSystemClock if timestamp == self.last_timestamp: self.sequence = (self.sequence + 1) & SEQUENCE_MASK if self.sequence == 0: timestamp = self._til_next_millis(self.last_timestamp) else: self.sequence = 0 self.last_timestamp = timestamp new_id = ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | (self.datacenter_id << DATACENTER_ID_SHIFT) | \ (self.worker_id << WOKER_ID_SHIFT) | self.sequence return new_id def _til_next_millis(self, last_timestamp): """ 绛夊埌涓嬩竴姣 """ timestamp = self._gen_timestamp() while timestamp <= last_timestamp: timestamp = self._gen_timestamp() return timestampif __name__ == __main__: worker = IdWorker(1, 2, 0) print(worker.get_id()) print(len(str(worker.get_id())))

鍙傝€冮摼鎺ワ細

https://blog.csdn.net/pony_maggie/article/details/103380116

https://bbs.huaweicloud.com/blogs/344958

缁撴潫璇細

浠婂ぉ鐨勫垎浜氨鍒拌繖閲屼簡锛屾杩庡ぇ瀹跺叧娉ㄥ井淇?鑿滈笩绔ラ澊"

鈥?nbsp; END 鈥?/p>

鐐瑰嚮杩欓噷缁欐垜鍐欑暀瑷€馃摑

鎴?/p>

鍚庡彴鐐瑰嚮鈥滆仈绯绘垜鈥濅竴璧蜂氦娴?/p>

版权声明:admin 发表于 2022-04-20 16:01:56。
转载请注明:雪花算法的原理和实现 | 甄选网