Snowflake は、Twitter によってオープンソース化された分散 ID 生成アルゴリズムです。次の方法を使用して、グローバルに一意の ID を生成します:
この記事では、Golang で Snowflake を実装する方法を紹介します。
最初に、マシン ID、シリアル番号、最後に生成された ID などのデータを Snowflake アルゴリズムに保存するための構造体を定義する必要があります。タイムスタンプやその他の情報。
const ( workerIdBits = 10 // 机器ID位数 sequenceBits = 12 // 序列号位数 workerIdMax = -1 ^ (-1 << workerIdBits) // 最大机器ID sequenceMask = -1 ^ (-1 << sequenceBits) // 序列号掩码 timeShiftBits = workerIdBits + sequenceBits // 时间戳左移位数 workerIdShift = sequenceBits // 机器ID左移位数 ) type Snowflake struct { lastTimestamp uint64 workerId uint16 sequence uint16 }
その中で、後続の計算を容易にするために、各データの桁数、最大値、マスクなどの情報を表すために定数を使用します。
次に、グローバルに一意の ID を生成するメソッドを実装する必要があります。
具体的な実装は次のとおりです。
func (s *Snowflake) NextId() uint64 { var currTimestamp = uint64(time.Now().UnixNano() / 1e6) if currTimestamp < s.lastTimestamp { panic("Invalid timestamp") } if currTimestamp == s.lastTimestamp { s.sequence = (s.sequence + 1) & sequenceMask if s.sequence == 0 { currTimestamp = s.waitNextMillis(currTimestamp) } } else { s.sequence = 0 } s.lastTimestamp = currTimestamp return ((currTimestamp - 1483228800000) << timeShiftBits) | (uint64(s.workerId) << workerIdShift) | uint64(s.sequence) } func (s *Snowflake) waitNextMillis(currTimestamp uint64) uint64 { for currTimestamp <= s.lastTimestamp { currTimestamp = uint64(time.Now().UnixNano() / 1e6) } return currTimestamp }
実装では、時刻を表すために UNIX タイムスタンプを使用しますが、Snowflake アルゴリズムが ID を生成する時期が 2017 年から始まっているため、 need タイムスタンプから固定オフセット値 (1483228800000) を減算します。
最後に、Snowflake オブジェクトを初期化し、マシン ID を指定する必要があります。マシン ID は 0 ~ 1023 の整数である必要があり、異なるマシンの ID は異なることが保証されます。
func New(workerId int) *Snowflake { if workerId < 0 || workerId > workerIdMax { panic(fmt.Sprintf("Invalid worker ID, must be in [%d, %d]", 0, workerIdMax)) } return &Snowflake{ lastTimestamp: 0, workerId: uint16(workerId), sequence: 0, } }
上記の実装では、Golang のタイムスタンプ関数と二項演算子を使用して ID の一意性と連続性を確保し、下位のシーケンス番号によって ID の増加傾向を確保しました。タイムスタンプはミリ秒レベルまで正確であるため、Snowflake アルゴリズムは、同時実行性の高いシナリオで ID の競合を回避するのに十分な ID を生成できます。
以上がGolang で Snowflake アルゴリズムを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。