יצירת וניתוח מזהי סנופלייק של טוויטר, מזהים ייחודיים בני 64 סיביות המשמשים במערכות מבוזרות. כלי זה מאפשר לך ליצור מזהי סנופלייק חדשים ולנתח קיימים, תוך מתן תובנות לגבי רכיבי הזמן, מזהה המחשב ומספר הרצף שלהם.
מחולל מזהי סנופלייק יוצר מזהים ייחודיים עבור מערכות מפוזרות, שפותח במקור על ידי טוויטר כדי להתמודד עם עיבוד נתונים בקנה מידה עצום. מחולל מזהים ייחודיים זה מפיק מספרים שלמים באורך 64 ביט המורכבים מחותמת זמן, מזהה מכונה ומספר רצף, ומבטיח ייחודיות בין מערכות מפוזרות ללא תיאום בין השרתים.
הכלי שלנו למחולל מזהי סנופלייק מקוון בחינם מאפשר לך ליצור ולפרש מזהי סנופלייק מידית, מה שהופך אותו למושלם עבור מפתחים העובדים עם מיקרו-שירותים, מסדי נתונים מפוזרים ויישומים בעלי קצב גבוה.
מזהי סנופלייק הם מספרים שלמים באורך 64 ביט עם מבנה מעוצב בקפידה המבטיח ייחודיות:
מבנה ה-ID המפוזר הזה מאפשר יצירה של כ-4,096 מזהים ייחודיים למילישנייה לכל מכונה, מה שהופך אותו לאידיאלי עבור מערכות מפוזרות בעלות קצב גבוה.
עקוב אחרי הצעדים הפשוטים הללו כדי ליצור מזהי סנופלייק ייחודיים:
כדי לפענח מזהה סנופלייק, הזן אותו בשדה "פענח מזהה" ולחץ על "פענח" כדי לראות את חותמת הזמן, מזהה המכונה ורכיבי הרצף שלו.
האלגוריתם של מזהי סנופלייק בונה מזהים ייחודיים באמצעות פעולות בייט:
1ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
2
רכיבי הנוסחה:
timestamp
: מספר המילישניות מאז האפוקdatacenterId
: מספר שלם באורך 5 ביט (0-31) המזהה את מרכז הנתוניםworkerId
: מספר שלם באורך 5 ביט (0-31) המזהה את מכונת העובדsequence
: מספר שלם באורך 12 ביט (0-4095) עבור מספר מזהים למילישנייההאלגוריתם של יצירת מזהי סנופלייק עוקב אחרי הצעדים המדויקים הללו:
תהליך זה מבטיח מזהים הולכים וגדלים בתוך כל מכונה תוך שמירה על ייחודיות גלובלית בין מערכות מפוזרות.
מזהי סנופלייק מצטיינים במגוון תרחישי מחשוב מפוזרים:
בעוד שמזהי סנופלייק הם חזקים, מערכות אחרות ליצירת מזהים ייחודיים כוללות:
הבנת המגבלות של מזהי סנופלייק מסייעת ביישום נכון:
מזהי סנופלייק הוצגו על ידי טוויטר בשנת 2010 כדי לפתור את האתגר של יצירת מזהים ייחודיים, מפוזרים וניתנים למיון בזמן בקנה מידה עצום. כאשר בסיס המשתמשים של טוויטר ונפח הציוצים התפוצץ, מזהים אוטומטיים מסורתיים הפכו לבלתי מספיקים עבור האדריכלות המפוזרת שלהם.
המערכת אומצה מאז על ידי חברות טכנולוגיה גדולות כולל אינסטגרם, דיסקורד ומספר רב של פלטפורמות אחרות שדורשות יצירת מזהים בקנה מידה עבור מערכות מפוזרות.
יישם יצירת מזהי סנופלייק בשפת התכנות המועדפת עליך:
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('Clock moved backwards. Refusing to generate 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// שימוש
55const generator = new SnowflakeGenerator();
56const id = generator.nextId(1, 1);
57console.log(`Generated Snowflake ID: ${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("Clock moved backwards. Refusing to generate 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## שימוש
58generator = SnowflakeGenerator(datacenter_id=1, worker_id=1)
59snowflake_id = generator.next_id()
60print(f"Generated Snowflake ID: {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 can't be greater than maxDatacenterId or less than 0");
39 }
40 if (workerId > maxWorkerId || workerId < 0) {
41 throw new IllegalArgumentException("workerId can't be greater than maxWorkerId or less than 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("Clock moved backwards. Refusing to generate 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("Generated Snowflake ID: " + 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 'Clock moved backwards' 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## שימוש
54generator = SnowflakeGenerator.new(1, 1)
55snowflake_id = generator.next_id
56puts "Generated Snowflake ID: #{snowflake_id}"
57
גלה עוד כלים שעשויים להיות שימושיים עבור זרימת העבודה שלך