天天看點

高性能可定制化分布式發号器

高性能可定制化分布式發号器

玄靖

劉兵,花名玄靖,目前供職于阿裡巴巴,開源技術愛好者,高性能redis中間件nredis-proxy作者,目前研究方向為java中間件,微服務等技術。

(一) 什麼是分布式發号器

    說起分布式發号器的前生今世,咱們應該感恩這個時代;随着網際網路在中國越來越普及化,單機系統或者一個小系統已經無法滿足需要,随着使用者逐漸增多,資料量越來越大,單個應用或者單個資料庫已經無法滿足需求,在應用以至于微服務來臨,在資料庫存儲方面分庫分表來臨,可以解決問題;但是新的問題産生,怎麼樣做到多個應用可以有唯一主鍵或者序号,防止資料重複呢?分布式發号器正好為解決這個問題,可以讓大家無須為這個問題煩惱了,這是本人寫這篇文章初衷

(二) 分布式發号器優勢

1) 解決分庫分表中唯一序号的問題

2) 解決分布式應用或者微服務架構中唯一序号的問題

3) 提供可定制化生成規則,根據業務需求可自定義擴充

4) 性能高效且系統簡單穩定

5) 系統可任意擴充

(三) 分布式發号器架構圖

高性能可定制化分布式發号器

(四) 分布式發号器流程圖

1) 分布式發号器重要字段

高性能可定制化分布式發号器

2) concurrentvalue不存在的流程圖

高性能可定制化分布式發号器

3) concurrentvalue存在的流程圖

高性能可定制化分布式發号器

(五) 目前存在分布式發号器解決方案

1) uuid

 universally unique identifier(uuid),有着正兒八經的rfc規範,是一個128bit的數字,也可以表現為32個16進制的字元(每個字元0-f的字元代表4bit),中間用"-"分割。

 時間戳+uuid版本号: 分三段占16個字元(60bit+4bit)

 clock sequence号與保留字段:占4個字元(13bit+3bit)

 節點辨別:占12個字元(48bit)

2) hibernate

hibernate的customversiononestrategy.java,解決了之前version 1的兩個問題

 時間戳(6bytes, 48bit):毫秒級别的,從1970年算起,能撐8925年....

 順序号(2bytes, 16bit, 最大值65535): 沒有時間戳過了一毫秒要歸零的事,各搞各的,short溢出到了負數就歸0。

 機器辨別(4bytes 32bit): 拿localhost的ip位址,ipv4呢正好4個byte,但如果是ipv6要16個bytes,就隻拿前4個byte。

 程序辨別(4bytes 32bit): 用目前時間戳右移8位再取整數應付,不信兩條線程會同時啟動。

3) mongodb

  mongodb的objectid.java

 時間戳(4 bytes 32bit):是秒級别的,從1970年算起,能撐136年。

 自增序列(3bytes 24bit, 最大值一千六百萬): 是一個從随機數開始(機智)的int不斷加一,也沒有時間戳過了一秒要歸零的事,各搞各的。因為隻有3bytes,是以一個4bytes的int還要截一下後3bytes。

 機器辨別(3bytes 24bit): 将所有網卡的mac位址拼在一起做個hashcode,同樣一個int還要截一下後3bytes。搞不到網卡就用随機數混過去。

 程序辨別(2bytes 16bits):從jmx裡搞回來到程序号,搞不到就用程序名的hash或者随機數混過去。

可見,mongodb的每一個字段設計都比hibernate的更合理一點,時間戳是秒級别的,自增序列變長了,程序辨別變短了。總長度也降到了12 bytes 96bit。

4) twitter的snowflake派号器

  snowflake也是一個派号器,基于thrift的服務,不過不是用redis簡單自增,而是類似uuid version1,

隻有一個long 64bit的長度,是以idworker緊巴巴的配置設定成:

 時間戳(42bit) :自從2012年以來(比那些從1970年算起的會過日子)的毫秒數,能撐139年。

 自增序列(12bit,最大值4096):毫秒之内的自增,過了一毫秒會重新置0。

 datacenter id (5 bit, 最大值32):配置值,支援多機房。

 worker id ( 5 bit, 最大值32),配置值,因為是派号器的id,一個機房裡最多32個派号器就夠了,還會在zk裡做下注冊。

        可見,因為是中央派号器,把至少40bit的節點辨別都省出來了,換成10bit的派号器辨別。是以整個uid能夠隻用一個long表達。

  另外,這種派号器,client每次隻能一個id,不能批量取,是以額外增加的延時是問題,而且隻能1024台機器範圍之内。

  以上幾種方案同一個問題,不可自定義,位數過長

來源:中生代技術

<a href="https://mp.weixin.qq.com/s/d9qiuzgyi6l23khnyqhzfw" target="_blank">原文連結</a>