Snowflake ID Generator for Distributed Systems and Analysis
Tạo và phân tích ID Snowflake của Twitter, các định danh 64-bit duy nhất được sử dụng trong các hệ thống phân tán. Công cụ này cho phép bạn tạo ID Snowflake mới và phân tích các ID hiện có, cung cấp cái nhìn về thành phần thời gian, ID máy và số thứ tự của chúng.
Trình tạo ID Snowflake
Trình tạo ID Snowflake
Tài liệu
Trình Tạo ID Snowflake
Giới Thiệu
ID Snowflake là một định danh duy nhất được sử dụng trong các hệ thống phân tán, ban đầu được phát triển bởi Twitter. Công cụ này cho phép bạn tạo và phân tích các ID Snowflake, là các số nguyên 64-bit được cấu thành từ một dấu thời gian, ID máy và số thứ tự.
Cách Hoạt Động Của ID Snowflake
ID Snowflake là các số nguyên 64-bit được cấu trúc như sau:
- 41 bit: Dấu thời gian (miligiây kể từ một thời điểm tùy chỉnh)
- 10 bit: ID máy (5 bit cho ID trung tâm dữ liệu, 5 bit cho ID máy chủ)
- 12 bit: Số thứ tự
Cấu trúc này cho phép tạo ra khoảng 4.096 ID duy nhất mỗi miligiây trên mỗi máy.
Sử Dụng Trình Tạo ID Snowflake
- (Tùy chọn) Đặt một thời điểm tùy chỉnh (mặc định là thời điểm của Twitter: 2010-11-04T01:42:54.657Z)
- Nhập ID máy (0-31) và ID trung tâm dữ liệu (0-31)
- Nhấn "Tạo" để tạo một ID Snowflake mới
- ID được tạo và các thành phần của nó sẽ được hiển thị
Để phân tích một ID Snowflake hiện có, nhập nó vào trường "Phân Tích ID" và nhấn "Phân Tích".
Công Thức
ID Snowflake được xây dựng bằng cách sử dụng các phép toán bitwise:
1ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
2
Trong đó:
timestamp
là số miligiây kể từ thời điểmdatacenterId
là một số nguyên 5 bit (0-31)workerId
là một số nguyên 5 bit (0-31)sequence
là một số nguyên 12 bit (0-4095)
Tính Toán
Trình tạo ID Snowflake thực hiện các bước sau:
- Lấy dấu thời gian hiện tại theo miligiây
- Đảm bảo rằng dấu thời gian lớn hơn dấu thời gian đã sử dụng cuối cùng (để đảm bảo tính duy nhất)
- Nếu dấu thời gian giống như dấu thời gian cuối cùng, tăng số thứ tự
- Nếu số thứ tự tràn (đạt đến 4096), chờ đến miligiây tiếp theo
- Kết hợp các thành phần bằng cách sử dụng các phép toán bitwise để tạo ra ID cuối cùng
Trường Hợp Sử Dụng
ID Snowflake đặc biệt hữu ích trong:
- Hệ Thống Phân Tán: Tạo ID duy nhất trên nhiều máy mà không cần phối hợp
- Dữ Liệu Khối Lượng Lớn: Tạo ID có thể sắp xếp cho các tập dữ liệu lớn
- Microservices: Đảm bảo các định danh duy nhất giữa các dịch vụ khác nhau
- Chia Tách Cơ Sở Dữ Liệu: Sử dụng thành phần dấu thời gian hoặc ID máy cho việc chia tách hiệu quả
Các Lựa Chọn Thay Thế
Mặc dù ID Snowflake mạnh mẽ, các hệ thống tạo ID khác bao gồm:
- UUID (Định danh duy nhất toàn cầu): Hữu ích khi cần tạo phân tán mà không cần sắp xếp
- ID tự tăng trong cơ sở dữ liệu: Đơn giản nhưng giới hạn ở các thể hiện cơ sở dữ liệu đơn
- ULID (Định danh duy nhất toàn cầu có thể sắp xếp): Tương tự như Snowflake, nhưng với cấu trúc khác
Các Trường Hợp Cạnh Và Hạn Chế
-
Đồng Bộ Đồng Hồ: ID Snowflake phụ thuộc vào thời gian hệ thống. Nếu đồng hồ quay ngược do điều chỉnh NTP hoặc thay đổi giờ mùa hè, nó có thể gây ra sự cố trong việc tạo ID.
-
Vấn Đề Năm 2038: Dấu thời gian 41 bit sẽ tràn vào năm 2079 (giả sử thời điểm của Twitter). Các hệ thống sử dụng ID Snowflake nên lập kế hoạch cho khả năng này.
-
Va Chạm ID Máy: Trong các hệ thống phân tán lớn, việc đảm bảo ID máy duy nhất có thể gặp khó khăn và có thể yêu cầu phối hợp thêm.
-
Tràn Số Thứ Tự: Trong các kịch bản có lưu lượng cao cực kỳ, có thể xảy ra tình trạng cạn kiệt 4096 số thứ tự mỗi miligiây, có thể gây ra sự chậm trễ.
-
Không Đơn Điệu Giữa Các Máy: Mặc dù ID tăng dần trên một máy đơn, chúng có thể không hoàn toàn đơn điệu giữa nhiều máy.
Lịch Sử
ID Snowflake được giới thiệu bởi Twitter vào năm 2010 để giải quyết nhu cầu về các định danh duy nhất có thể sắp xếp theo thời gian trong môi trường phân tán. Chúng đã được nhiều công ty và dự án khác áp dụng và điều chỉnh.
Ví Dụ
Dưới đây là các triển khai của trình tạo ID Snowflake trong nhiều ngôn ngữ khác nhau:
1class SnowflakeGenerator {
2 constructor(epoch = 1288834974657, datacenterIdBits = 5, workerIdBits = 5, sequenceBits = 12) {
3 this.epoch = BigInt(epoch);
4 this.datacenterIdBits = datacenterIdBits;
5 this.workerIdBits = workerIdBits;
6 this.sequenceBits = sequenceBits;
7 this.maxDatacenterId = -1n ^ (-1n << BigInt(datacenterIdBits));
8 this.maxWorkerId = -1n ^ (-1n << BigInt(workerIdBits));
9 this.sequenceMask = -1n ^ (-1n << BigInt(sequenceBits));
10 this.workerIdShift = BigInt(sequenceBits);
11 this.datacenterIdShift = BigInt(sequenceBits + workerIdBits);
12 this.timestampLeftShift = BigInt(sequenceBits + workerIdBits + datacenterIdBits);
13 this.sequence = 0n;
14 this.lastTimestamp = -1n;
15 }
16
17 nextId(datacenterId, workerId) {
18 let timestamp = this.currentTimestamp();
19
20 if (timestamp < this.lastTimestamp) {
21 throw new Error('Đồng hồ di chuyển ngược. Từ chối tạo id');
22 }
23
24 if (timestamp === this.lastTimestamp) {
25 this.sequence = (this.sequence + 1n) & this.sequenceMask;
26 if (this.sequence === 0n) {
27 timestamp = this.tilNextMillis(this.lastTimestamp);
28 }
29 } else {
30 this.sequence = 0n;
31 }
32
33 this.lastTimestamp = timestamp;
34
35 return ((timestamp - this.epoch) << this.timestampLeftShift) |
36 (BigInt(datacenterId) << this.datacenterIdShift) |
37 (BigInt(workerId) << this.workerIdShift) |
38 this.sequence;
39 }
40
41 tilNextMillis(lastTimestamp) {
42 let timestamp = this.currentTimestamp();
43 while (timestamp <= lastTimestamp) {
44 timestamp = this.currentTimestamp();
45 }
46 return timestamp;
47 }
48
49 currentTimestamp() {
50 return BigInt(Date.now());
51 }
52}
53
54// Sử Dụng
55const generator = new SnowflakeGenerator();
56const id = generator.nextId(1, 1);
57console.log(`ID Snowflake được tạo: ${id}`);
58
1import time
2import threading
3
4class SnowflakeGenerator:
5 def __init__(self, datacenter_id, worker_id, sequence=0):
6 self.datacenter_id = datacenter_id
7 self.worker_id = worker_id
8 self.sequence = sequence
9
10 self.last_timestamp = -1
11 self.epoch = 1288834974657
12
13 self.datacenter_id_bits = 5
14 self.worker_id_bits = 5
15 self.sequence_bits = 12
16
17 self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
18 self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
19
20 self.worker_id_shift = self.sequence_bits
21 self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
22 self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
23 self.sequence_mask = -1 ^ (-1 << self.sequence_bits)
24
25 self._lock = threading.Lock()
26
27 def _til_next_millis(self, last_timestamp):
28 timestamp = self._get_timestamp()
29 while timestamp <= last_timestamp:
30 timestamp = self._get_timestamp()
31 return timestamp
32
33 def _get_timestamp(self):
34 return int(time.time() * 1000)
35
36 def next_id(self):
37 with self._lock:
38 timestamp = self._get_timestamp()
39
40 if timestamp < self.last_timestamp:
41 raise ValueError("Đồng hồ di chuyển ngược. Từ chối tạo id")
42
43 if timestamp == self.last_timestamp:
44 self.sequence = (self.sequence + 1) & self.sequence_mask
45 if self.sequence == 0:
46 timestamp = self._til_next_millis(self.last_timestamp)
47 else:
48 self.sequence = 0
49
50 self.last_timestamp = timestamp
51
52 return ((timestamp - self.epoch) << self.timestamp_left_shift) | \
53 (self.datacenter_id << self.datacenter_id_shift) | \
54 (self.worker_id << self.worker_id_shift) | \
55 self.sequence
56
57## Sử Dụng
58generator = SnowflakeGenerator(datacenter_id=1, worker_id=1)
59snowflake_id = generator.next_id()
60print(f"ID Snowflake được tạo: {snowflake_id}")
61
1import java.util.concurrent.locks.Lock;
2import java.util.concurrent.locks.ReentrantLock;
3
4public class SnowflakeGenerator {
5 private final long epoch;
6 private final long datacenterIdBits;
7 private final long workerIdBits;
8 private final long sequenceBits;
9 private final long maxDatacenterId;
10 private final long maxWorkerId;
11 private final long workerIdShift;
12 private final long datacenterIdShift;
13 private final long timestampLeftShift;
14 private final long sequenceMask;
15
16 private long datacenterId;
17 private long workerId;
18 private long sequence = 0L;
19 private long lastTimestamp = -1L;
20
21 private final Lock lock = new ReentrantLock();
22
23 public SnowflakeGenerator(long datacenterId, long workerId) {
24 this.epoch = 1288834974657L;
25 this.datacenterIdBits = 5L;
26 this.workerIdBits = 5L;
27 this.sequenceBits = 12L;
28
29 this.maxDatacenterId = ~(-1L << datacenterIdBits);
30 this.maxWorkerId = ~(-1L << workerIdBits);
31
32 this.workerIdShift = sequenceBits;
33 this.datacenterIdShift = sequenceBits + workerIdBits;
34 this.timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
35 this.sequenceMask = ~(-1L << sequenceBits);
36
37 if (datacenterId > maxDatacenterId || datacenterId < 0) {
38 throw new IllegalArgumentException("datacenterId không thể lớn hơn maxDatacenterId hoặc nhỏ hơn 0");
39 }
40 if (workerId > maxWorkerId || workerId < 0) {
41 throw new IllegalArgumentException("workerId không thể lớn hơn maxWorkerId hoặc nhỏ hơn 0");
42 }
43 this.datacenterId = datacenterId;
44 this.workerId = workerId;
45 }
46
47 public long nextId() {
48 lock.lock();
49 try {
50 long timestamp = timeGen();
51 if (timestamp < lastTimestamp) {
52 throw new RuntimeException("Đồng hồ di chuyển ngược. Từ chối tạo id");
53 }
54
55 if (lastTimestamp == timestamp) {
56 sequence = (sequence + 1) & sequenceMask;
57 if (sequence == 0) {
58 timestamp = tilNextMillis(lastTimestamp);
59 }
60 } else {
61 sequence = 0L;
62 }
63
64 lastTimestamp = timestamp;
65
66 return ((timestamp - epoch) << timestampLeftShift) |
67 (datacenterId << datacenterIdShift) |
68 (workerId << workerIdShift) |
69 sequence;
70 } finally {
71 lock.unlock();
72 }
73 }
74
75 private long tilNextMillis(long lastTimestamp) {
76 long timestamp = timeGen();
77 while (timestamp <= lastTimestamp) {
78 timestamp = timeGen();
79 }
80 return timestamp;
81 }
82
83 private long timeGen() {
84 return System.currentTimeMillis();
85 }
86
87 public static void main(String[] args) {
88 SnowflakeGenerator generator = new SnowflakeGenerator(1, 1);
89 long id = generator.nextId();
90 System.out.println("ID Snowflake được tạo: " + id);
91 }
92}
93
1require 'time'
2
3class SnowflakeGenerator
4 def initialize(datacenter_id, worker_id, sequence = 0)
5 @datacenter_id = datacenter_id
6 @worker_id = worker_id
7 @sequence = sequence
8 @last_timestamp = -1
9 @epoch = 1288834974657
10
11 @datacenter_id_bits = 5
12 @worker_id_bits = 5
13 @sequence_bits = 12
14
15 @max_datacenter_id = -1 ^ (-1 << @datacenter_id_bits)
16 @max_worker_id = -1 ^ (-1 << @worker_id_bits)
17
18 @worker_id_shift = @sequence_bits
19 @datacenter_id_shift = @sequence_bits + @worker_id_bits
20 @timestamp_left_shift = @sequence_bits + @worker_id_bits + @datacenter_id_bits
21 @sequence_mask = -1 ^ (-1 << @sequence_bits)
22 end
23
24 def next_id
25 timestamp = (Time.now.to_f * 1000).to_i
26
27 raise 'Đồng hồ di chuyển ngược' if timestamp < @last_timestamp
28
29 if timestamp == @last_timestamp
30 @sequence = (@sequence + 1) & @sequence_mask
31 timestamp = til_next_millis(@last_timestamp) if @sequence == 0
32 else
33 @sequence = 0
34 end
35
36 @last_timestamp = timestamp
37
38 ((timestamp - @epoch) << @timestamp_left_shift) |
39 (@datacenter_id << @datacenter_id_shift) |
40 (@worker_id << @worker_id_shift) |
41 @sequence
42 end
43
44 private
45
46 def til_next_millis(last_timestamp)
47 timestamp = (Time.now.to_f * 1000).to_i
48 timestamp = (Time.now.to_f * 1000).to_i while timestamp <= last_timestamp
49 timestamp
50 end
51end
52
53## Sử Dụng
54generator = SnowflakeGenerator.new(1, 1)
55snowflake_id = generator.next_id
56puts "ID Snowflake được tạo: #{snowflake_id}"
57
1<?php
2
3class SnowflakeGenerator {
4 private $epoch;
5 private $datacenterIdBits;
6 private $workerIdBits;
7 private $sequenceBits;
8 private $maxDatacenterId;
9 private $maxWorkerId;
10 private $workerIdShift;
11 private $datacenterIdShift;
12 private $timestampLeftShift;
13 private $sequenceMask;
14
15 private $datacenterId;
16 private $workerId;
17 private $sequence = 0;
18 private $lastTimestamp = -1;
19
20 public function __construct($datacenterId, $workerId) {
21 $this->epoch = 1288834974657;
22 $this->datacenterIdBits = 5;
23 $this->workerIdBits = 5;
24 $this->sequenceBits = 12;
25
26 $this->maxDatacenterId = -1 ^ (-1 << $this->datacenterIdBits);
27 $this->maxWorkerId = -1 ^ (-1 << $this->workerIdBits);
28
29 $this->workerIdShift = $this->sequenceBits;
30 $this->datacenterIdShift = $this->sequenceBits + $this->workerIdBits;
31 $this->timestampLeftShift = $this->sequenceBits + $this->workerIdBits + $this->datacenterIdBits;
32 $this->sequenceMask = -1 ^ (-1 << $this->sequenceBits);
33
34 if ($datacenterId > $this->maxDatacenterId || $datacenterId < 0) {
35 throw new Exception("datacenterId không thể lớn hơn maxDatacenterId hoặc nhỏ hơn 0");
36 }
37 if ($workerId > $this->maxWorkerId || $workerId < 0) {
38 throw new Exception("workerId không thể lớn hơn maxWorkerId hoặc nhỏ hơn 0");
39 }
40 $this->datacenterId = $datacenterId;
41 $this->workerId = $workerId;
42 }
43
44 public function nextId() {
45 $timestamp = $this->timeGen();
46
47 if ($timestamp < $this->lastTimestamp) {
48 throw new Exception("Đồng hồ di chuyển ngược. Từ chối tạo id");
49 }
50
51 if ($this->lastTimestamp == $timestamp) {
52 $this->sequence = ($this->sequence + 1) & $this->sequenceMask;
53 if ($this->sequence == 0) {
54 $timestamp = $this->tilNextMillis($this->lastTimestamp);
55 }
56 } else {
57 $this->sequence = 0;
58 }
59
60 $this->lastTimestamp = $timestamp;
61
62 return (($timestamp - $this->epoch) << $this->timestampLeftShift) |
63 ($this->datacenterId << $this->datacenterIdShift) |
64 ($this->workerId << $this->workerIdShift) |
65 $this->sequence;
66 }
67
68 private function tilNextMillis($lastTimestamp) {
69 $timestamp = $this->timeGen();
70 while ($timestamp <= $lastTimestamp) {
71 $timestamp = $this->timeGen();
72 }
73 return $timestamp;
74 }
75
76 private function timeGen() {
77 return floor(microtime(true) * 1000);
78 }
79}
80
81// Sử Dụng
82$generator = new SnowflakeGenerator(1, 1);
83$id = $generator->nextId();
84echo "ID Snowflake được tạo: " . $id . "\n";
85
1using System;
2using System.Threading;
3
4public class SnowflakeGenerator
5{
6 private readonly long _epoch;
7 private readonly int _datacenterIdBits;
8 private readonly int _workerIdBits;
9 private readonly int _sequenceBits;
10 private readonly long _maxDatacenterId;
11 private readonly long _maxWorkerId;
12 private readonly int _workerIdShift;
13 private readonly int _datacenterIdShift;
14 private readonly int _timestampLeftShift;
15 private readonly long _sequenceMask;
16
17 private readonly long _datacenterId;
18 private readonly long _workerId;
19 private long _sequence = 0L;
20 private long _lastTimestamp = -1L;
21
22 private readonly object _lock = new object();
23
24 public SnowflakeGenerator(long datacenterId, long workerId)
25 {
26 _epoch = 1288834974657L;
27 _datacenterIdBits = 5;
28 _workerIdBits = 5;
29 _sequenceBits = 12;
30
31 _maxDatacenterId = -1L ^ (-1L << _datacenterIdBits);
32 _maxWorkerId = -1L ^ (-1L << _workerIdBits);
33
34 _workerIdShift = _sequenceBits;
35 _datacenterIdShift = _sequenceBits + _workerIdBits;
36 _timestampLeftShift = _sequenceBits + _workerIdBits + _datacenterIdBits;
37 _sequenceMask = -1L ^ (-1L << _sequenceBits);
38
39 if (datacenterId > _maxDatacenterId || datacenterId < 0)
40 {
41 throw new ArgumentException($"datacenterId không thể lớn hơn {_maxDatacenterId} hoặc nhỏ hơn 0");
42 }
43 if (workerId > _maxWorkerId || workerId < 0)
44 {
45 throw new ArgumentException($"workerId không thể lớn hơn {_maxWorkerId} hoặc nhỏ hơn 0");
46 }
47 _datacenterId = datacenterId;
48 _workerId = workerId;
49 }
50
51 public long NextId()
52 {
53 lock (_lock)
54 {
55 var timestamp = TimeGen();
56
57 if (timestamp < _lastTimestamp)
58 {
59 throw new Exception("Đồng hồ di chuyển ngược. Từ chối tạo id");
60 }
61
62 if (_lastTimestamp == timestamp)
63 {
64 _sequence = (_sequence + 1) & _sequenceMask;
65 if (_sequence == 0)
66 {
67 timestamp = TilNextMillis(_lastTimestamp);
68 }
69 }
70 else
71 {
72 _sequence = 0L;
73 }
74
75 _lastTimestamp = timestamp;
76
77 return ((timestamp - _epoch) << _timestampLeftShift) |
78 (_datacenterId << _datacenterIdShift) |
79 (_workerId << _workerIdShift) |
80 _sequence;
81 }
82 }
83
84 private long TilNextMillis(long lastTimestamp)
85 {
86 var timestamp = TimeGen();
87 while (timestamp <= lastTimestamp)
88 {
89 timestamp = TimeGen();
90 }
91 return timestamp;
92 }
93
94 private long TimeGen()
95 {
96 return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
97 }
98}
99
100// Sử Dụng
101class Program
102{
103 static void Main(string[] args)
104 {
105 var generator = new SnowflakeGenerator(1, 1);
106 var id = generator.NextId();
107 Console.WriteLine($"ID Snowflake được tạo: {id}");
108 }
109}
110
1package main
2
3import (
4 "fmt"
5 "sync"
6 "time"
7)
8
9type SnowflakeGenerator struct {
10 epoch int64
11 datacenterIdBits uint
12 workerIdBits uint
13 sequenceBits uint
14 maxDatacenterId int64
15 maxWorkerId int64
16 workerIdShift uint
17 datacenterIdShift uint
18 timestampLeftShift uint
19 sequenceMask int64
20
21 datacenterId int64
22 workerId int64
23 sequence int64
24 lastTimestamp int64
25
26 lock sync.Mutex
27}
28
29func NewSnowflakeGenerator(datacenterId, workerId int64) (*SnowflakeGenerator, error) {
30 g := &SnowflakeGenerator{
31 epoch: 1288834974657,
32 datacenterIdBits: 5,
33 workerIdBits: 5,
34 sequenceBits: 12,
35 lastTimestamp: -1,
36 }
37
38 g.maxDatacenterId = -1 ^ (-1 << g.datacenterIdBits)
39 g.maxWorkerId = -1 ^ (-1 << g.workerIdBits)
40
41 g.workerIdShift = g.sequenceBits
42 g.datacenterIdShift = g.sequenceBits + g.workerIdBits
43 g.timestampLeftShift = g.sequenceBits + g.workerIdBits + g.datacenterIdBits
44 g.sequenceMask = -1 ^ (-1 << g.sequenceBits)
45
46 if datacenterId > g.maxDatacenterId || datacenterId < 0 {
47 return nil, fmt.Errorf("datacenterId không thể lớn hơn %d hoặc nhỏ hơn 0", g.maxDatacenterId)
48 }
49 if workerId > g.maxWorkerId || workerId < 0 {
50 return nil, fmt.Errorf("workerId không thể lớn hơn %d hoặc nhỏ hơn 0", g.maxWorkerId)
51 }
52 g.datacenterId = datacenterId
53 g.workerId = workerId
54
55 return g, nil
56}
57
58func (g *SnowflakeGenerator) NextId() (int64, error) {
59 g.lock.Lock()
60 defer g.lock.Unlock()
61
62 timestamp := g.timeGen()
63
64 if timestamp < g.lastTimestamp {
65 return 0, fmt.Errorf("đồng hồ di chuyển ngược, từ chối tạo id")
66 }
67
68 if g.lastTimestamp == timestamp {
69 g.sequence = (g.sequence + 1) & g.sequenceMask
70 if g.sequence == 0 {
71 timestamp = g.tilNextMillis(g.lastTimestamp)
72 }
73 } else {
74 g.sequence = 0
75 }
76
77 g.lastTimestamp = timestamp
78
79 return ((timestamp - g.epoch) << g.timestampLeftShift) |
80 (g.datacenterId << g.datacenterIdShift) |
81 (g.workerId << g.workerIdShift) |
82 g.sequence, nil
83}
84
85func (g *SnowflakeGenerator) tilNextMillis(lastTimestamp int64) int64 {
86 timestamp := g.timeGen()
87 for timestamp <= lastTimestamp {
88 timestamp = g.timeGen()
89 }
90 return timestamp
91}
92
93func (g *SnowflakeGenerator) timeGen() int64 {
94 return time.Now().UnixNano() / int64(time.Millisecond)
95}
96
97func main() {
98 generator, err := NewSnowflakeGenerator(1, 1)
99 if err != nil {
100 fmt.Printf("Lỗi khi tạo trình tạo: %v\n", err)
101 return
102 }
103
104 id, err := generator.NextId()
105 if err != nil {
106 fmt.Printf("Lỗi khi tạo ID: %v\n", err)
107 return
108 }
109
110 fmt.Printf("ID Snowflake được tạo: %d\n", id)
111}
112
Sơ Đồ
Dưới đây là một biểu diễn hình ảnh của cấu trúc ID Snowflake:
Tài Liệu Tham Khảo
- "Thông Báo Snowflake." Blog Kỹ Thuật Twitter, https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
- "ID Snowflake." Wikipedia, https://en.wikipedia.org/wiki/Snowflake_ID
- "Tạo ID Phân Tán Trong Microservices." Medium, https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f
Phản hồi
Nhấp vào thông báo phản hồi để bắt đầu gửi phản hồi về công cụ này
Công cụ liên quan
Khám phá thêm các công cụ có thể hữu ích cho quy trình làm việc của bạn