ಸ್ನೋಫ್ಲೇಕ್ ಐಡಿ ಜನರೇಟರ್ - 64-ಬಿಟ್ ಗುರುತಿಸುವಿಕೆ ಸಾಧನ
ವಿತರಣಾ ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ಬಳಸುವ ವಿಶಿಷ್ಟ 64-ಬಿಟ್ ಗುರುತಿಸುವಿಕೆಯನ್ನು, ಟ್ವಿಟರ್ ಸ್ನೋಫ್ಲೇಕ್ ಐಡಿಗಳನ್ನು ಉಂಟುಮಾಡಲು ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲು. ಈ ಸಾಧನವು ಹೊಸ ಸ್ನೋಫ್ಲೇಕ್ ಐಡಿಗಳನ್ನು ರಚಿಸಲು ಮತ್ತು ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಐಡಿಗಳನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು ಅನುಮತಿಸುತ್ತದೆ, ಅವುಗಳ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್, ಯಂತ್ರ ಐಡಿ ಮತ್ತು ಅನುಕ್ರಮ ಸಂಖ್ಯೆಯ ಅಂಶಗಳ ಬಗ್ಗೆ洞察ಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ.
ಸ್ನೋಫ್ಲೇಕ್ ಐಡಿ ಜನರೇಟರ್
ಸ್ನೋಫ್ಲೇಕ್ ಐಡಿ ಜನರೇಟರ್
ದಾಖಲೆ
Snowflake ID ಜನರೇಟರ್
ಪರಿಚಯ
Snowflake ID ಒಂದು ವಿಶಿಷ್ಟ ಗುರುತಿನ ಚಿಹ್ನೆ, ಇದು ವಿತರಣಾ ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ಬಳಸಲಾಗುತ್ತದೆ, ಮೊದಲನೆಯದಾಗಿ ಟ್ವಿಟ್ಟರ್ ಮೂಲಕ ಅಭಿವೃದ್ಧಿಪಡಿಸಲಾಗಿದೆ. ಈ ಸಾಧನವು ನಿಮಗೆ Snowflake IDs ಅನ್ನು ಜನರೇಟ್ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲು ಅವಕಾಶ ನೀಡುತ್ತದೆ, ಇದು ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್, ಯಂತ್ರ ID ಮತ್ತು ಕೀಳ್ಮಟ್ಟ ಸಂಖ್ಯೆಯೊಂದಿಗೆ 64-ಬಿಟ್ ಪೂರ್ಣಾಂಕಗಳನ್ನು ಒಳಗೊಂಡಿದೆ.
Snowflake IDs ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ
Snowflake IDs 64-ಬಿಟ್ ಪೂರ್ಣಾಂಕಗಳಾಗಿ ಈ ಕೆಳಗಿನ ರಚನೆಯಲ್ಲಿವೆ:
- 41 ಬಿಟ್: ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ (ಕಸ್ಟಮ್ ಎಪೋಕ್ನಿಂದ ಮಿಲ್ಲಿಸೆಕೆಂಡುಗಳು)
- 10 ಬಿಟ್: ಯಂತ್ರ ID (ಡೇಟಾ ಕೇಂದ್ರ ID ಗೆ 5 ಬಿಟ್, ಕಾರ್ಮಿಕ ID ಗೆ 5 ಬಿಟ್)
- 12 ಬಿಟ್: ಕೀಳ್ಮಟ್ಟ ಸಂಖ್ಯೆ
ಈ ರಚನೆಯು ಪ್ರತಿ ಯಂತ್ರಕ್ಕೆ ಪ್ರತಿ ಮಿಲ್ಲಿಸೆಕೆಂಡು 4,096 ವಿಶಿಷ್ಟ IDs ಅನ್ನು ಜನರೇಟ್ ಮಾಡಲು ಅವಕಾಶ ನೀಡುತ್ತದೆ.
Snowflake ID ಜನರೇಟರ್ ಅನ್ನು ಬಳಸುವುದು
- (ಐಚ್ಛಿಕ) ಕಸ್ಟಮ್ ಎಪೋಕ್ ಅನ್ನು ಹೊಂದಿಸಿ (ಡೀಫಾಲ್ಟ್ ಟ್ವಿಟ್ಟರ್ನ ಎಪೋಕ್: 2010-11-04T01:42:54.657Z)
- ಯಂತ್ರ ID (0-31) ಮತ್ತು ಡೇಟಾ ಕೇಂದ್ರ ID (0-31) ಅನ್ನು ನಮೂದಿಸಿ
- ಹೊಸ Snowflake ID ಅನ್ನು ನಿರ್ಮಿಸಲು "ಜನರೇಟ್" ಕ್ಲಿಕ್ ಮಾಡಿ
- ಉತ್ಪಾದಿತ ID ಮತ್ತು ಅದರ ಅಂಶಗಳು ಪ್ರದರ್ಶಿಸಲಾಗುತ್ತವೆ
ಹಾಜರಿರುವ Snowflake ID ಅನ್ನು ಪಾರ್ಸ್ ಮಾಡಲು, "ID ಪಾರ್ಸ್" ಕ್ಷೇತ್ರದಲ್ಲಿ ಅದನ್ನು ನಮೂದಿಸಿ ಮತ್ತು "ಪಾರ್ಸ್" ಕ್ಲಿಕ್ ಮಾಡಿ.
ಸೂತ್ರ
Snowflake ID ಅನ್ನು ಬಿಟ್ವೈಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನಿರ್ಮಿಸಲಾಗಿದೆ:
1ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
2
ಎಲ್ಲಿ:
timestamp
ಎಪೋಕ್ನಿಂದ ಮಿಲ್ಲಿಸೆಕೆಂಡುಗಳ ಸಂಖ್ಯೆಯಾಗಿದೆdatacenterId
5-ಬಿಟ್ ಪೂರ್ಣಾಂಕ (0-31)workerId
5-ಬಿಟ್ ಪೂರ್ಣಾಂಕ (0-31)sequence
12-ಬಿಟ್ ಪೂರ್ಣಾಂಕ (0-4095)
ಲೆಕ್ಕಾಚಾರ
Snowflake ID ಜನರೇಟರ್ ಈ ಕೆಳಗಿನ ಹಂತಗಳನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ:
- ಪ್ರಸ್ತುತ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ ಅನ್ನು ಮಿಲ್ಲಿಸೆಕೆಂಡುಗಳಲ್ಲಿ ಪಡೆಯಿರಿ
- ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ ಹಿಂದಿನ ಬಳಸಿದ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ಗಿಂತ ಹೆಚ್ಚು ಎಂದು ಖಚಿತಪಡಿಸಿ (ವಿಶಿಷ್ಟತೆಗೆ)
- ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ ಹಿಂದಿನದಷ್ಟೇ ಇದ್ದರೆ, ಕೀಳ್ಮಟ್ಟ ಸಂಖ್ಯೆಯನ್ನು ಹೆಚ್ಚಿಸಿ
- ಕೀಳ್ಮಟ್ಟ ಸಂಖ್ಯೆ ಓವರ್ಫ್ಲೋ ಮಾಡಿದರೆ (4096 ತಲುಪಿದರೆ), ಮುಂದಿನ ಮಿಲ್ಲಿಸೆಕೆಂಡುಗಾಗಿ ಕಾಯಿರಿ
- ಅಂತಿಮ ID ಅನ್ನು ರಚಿಸಲು ಬಿಟ್ವೈಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಅಂಶಗಳನ್ನು ಸಂಯೋಜಿಸಿ
ಬಳಕೆದಾರಿಕೆಗಳು
Snowflake IDs ವಿಶೇಷವಾಗಿ ಈಗಳಲ್ಲಿ ಉಪಯೋಗಿಸುತ್ತವೆ:
- ವಿತರಣಾ ವ್ಯವಸ್ಥೆಗಳು: ಯಾವುದೇ ಸಮನ್ವಯವಿಲ್ಲದೆ ಬಹಳಷ್ಟು ಯಂತ್ರಗಳಲ್ಲಿ ವಿಶಿಷ್ಟ IDs ಅನ್ನು ಜನರೇಟ್ ಮಾಡಲು
- ಹೆಚ್ಚಿನ ಪ್ರಮಾಣದ ಡೇಟಾ: ದೊಡ್ಡ ಡೇಟಾಸೆಟ್ಗಳಿಗೆ ಶ್ರೇಣೀಬದ್ಧವಾದ IDs ಅನ್ನು ರಚಿಸಲು
- ಮೈಕ್ರೋಸರ್ವೀಸ್: ವಿಭಿನ್ನ ಸೇವೆಗಳ ನಡುವೆ ವಿಶಿಷ್ಟ ಗುರುತಿನ ಚಿಹ್ನೆಗಳನ್ನು ಖಚಿತಪಡಿಸಲು
- ಡೇಟಾಬೇಸ್ ಶಾರ್ಡಿಂಗ್: ಪರಿಣಾಮಕಾರಿ ಶಾರ್ಡಿಂಗ್ಗಾಗಿ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ ಅಥವಾ ಯಂತ್ರ ID ಅಂಶವನ್ನು ಬಳಸಲು
ಪರ್ಯಾಯಗಳು
Snowflake IDs ಶಕ್ತಿಯುತವಾಗಿದ್ದರೂ, ಇತರ ID ಜನರೇಟಿಂಗ್ ವ್ಯವಸ್ಥೆಗಳು ಇವೆ:
- UUID (ಯುನಿವರ್ಸಲ್ ಯುನಿಕ್ ಐಡಂಟಿಫೈಯರ್): ಶ್ರೇಣೀಬದ್ಧತೆಯ ಅಗತ್ಯವಿಲ್ಲದೆ ವಿತರಣಾ ಜನರೇಶನ್ಗಾಗಿ ಉಪಯುಕ್ತ
- ಸ್ವಾಯತ್ತ-ಊಟುವ ಡೇಟಾಬೇಸ್ IDs: ಸರಳ ಆದರೆ ಏಕಕಾಲದಲ್ಲಿ ಒಂದೇ ಡೇಟಾಬೇಸ್ ಉದಾಹರಣೆಗಳಿಗೆ ಮಾತ್ರ ಸೀಮಿತ
- ULID (ಯುನಿವರ್ಸಲ್ ಯುನಿಕ್ ಲೆಕ್ಸಿಕೋಗ್ರಾಫಿಕಲ್ ಶ್ರೇಣೀಬದ್ಧ ಗುರುತಿನ ಚಿಹ್ನೆ): Snowflake ಗೆ ಸಮಾನ, ಆದರೆ ವಿಭಿನ್ನ ರಚನೆಯೊಂದಿಗೆ
ತೀವ್ರ ಪ್ರಕರಣಗಳು ಮತ್ತು ನಿರ್ಬಂಧಗಳು
-
ಕ್ಲಾಕ್ ಸಮನ್ವಯ: Snowflake IDs ವ್ಯವಸ್ಥಾ ಸಮಯವನ್ನು ಆಧಾರಿತವಾಗಿರುತ್ತವೆ. NTP ಸಮನ್ವಯ ಅಥವಾ ದಿನದ ಬೆಳವಣಿಗೆ ಸಮಯ ಬದಲಾವಣೆಗಳಿಂದ ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದರೆ, ID ಜನರೇಶನ್ನಲ್ಲಿ ಸಮಸ್ಯೆಗಳನ್ನು ಉಂಟುಮಾಡಬಹುದು.
-
ವರ್ಷ 2038 ಸಮಸ್ಯೆ: 41-ಬಿಟ್ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ 2079 ರಲ್ಲಿ ಓವರ್ಫ್ಲೋ ಆಗುತ್ತದೆ (ಟ್ವಿಟ್ಟರ್ ಎಪೋಕ್ ಅನ್ನು ಪರಿಗಣಿಸಿದಾಗ). Snowflake IDs ಬಳಸುವ ವ್ಯವಸ್ಥೆಗಳು ಈ ಸಂಭವನೀಯತೆಯನ್ನು ಯೋಜಿಸಬೇಕು.
-
ಯಂತ್ರ ID ಔಟ್ಕೋಮ್ಗಳು: ದೊಡ್ಡ ವಿತರಣಾ ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ, ವಿಶಿಷ್ಟ ಯಂತ್ರ IDs ಅನ್ನು ಖಚಿತಪಡಿಸುವುದು ಸವಾಲಾಗಬಹುದು ಮತ್ತು ಹೆಚ್ಚುವರಿ ಸಮನ್ವಯವನ್ನು ಅಗತ್ಯವಿರಬಹುದು.
-
ಕೀಳ್ಮಟ್ಟ ಓವರ್ಫ್ಲೋ: ಅತ್ಯಂತ ಹೆಚ್ಚಿನ ಪ್ರಮಾಣದ ದೃಷ್ಟಿಕೋನದಲ್ಲಿ, 4096 ಶ್ರೇಣೀಬದ್ಧ ಸಂಖ್ಯೆಗಳ ಮಿಲ್ಲಿಸೆಕೆಂಡುಗಳನ್ನು ಸಂಪೂರ್ಣಗೊಳಿಸುವ ಸಾಧ್ಯತೆ ಇದೆ, ಇದರಿಂದ ವಿಳಂಬ ಉಂಟಾಗಬಹುದು.
-
ಯಂತ್ರಗಳ ನಡುವಿನ ಅಸಮಾನತೆ: IDs ಒಬ್ಬ ಯಂತ್ರದ ಮೇಲೆ ಕ್ರಮಬದ್ಧವಾಗಿ ಹೆಚ್ಚಾಗಿರುವಾಗ, ಬಹಳಷ್ಟು ಯಂತ್ರಗಳ ನಡುವೆ ಅವು ಕಠಿಣವಾಗಿ ಕ್ರಮಬದ್ಧವಾಗಿರಬಹುದು.
ಇತಿಹಾಸ
Snowflake IDs 2010 ರಲ್ಲಿ ಟ್ವಿಟ್ಟರ್ ಮೂಲಕ ಪರಿಚಯಿಸಲಾಯಿತು, ಇದು ವಿತರಣಾ, ಕಾಲ-ಶ್ರೇಣೀಬದ್ಧ ವಿಶಿಷ್ಟ ಗುರುತಿನ ಚಿಹ್ನೆಗಳ ಅಗತ್ಯವನ್ನು ಪರಿಹರಿಸಲು. ಇವು ನಂತರ ಹಲವಾರು ಇತರ ಕಂಪನಿಗಳು ಮತ್ತು ಯೋಜನೆಗಳಿಂದ ಸ್ವೀಕರಿಸಲ್ಪಟ್ಟವು ಮತ್ತು ಹೊಂದಿಸಲಾಗಿದೆ.
ಉದಾಹರಣೆಗಳು
ಇವು ವಿವಿಧ ಭಾಷೆಗಳಲ್ಲಿ Snowflake ID ಜನರೇಟರ್ಗಳ ಕಾರ್ಯಗತಗೊಳಣೆಗಳಾಗಿವೆ:
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('ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ. 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(`ಉತ್ಪತ್ತಿ ಮಾಡಿದ 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("ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ. 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"ಉತ್ಪತ್ತಿ ಮಾಡಿದ 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("ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ. 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("ಉತ್ಪತ್ತಿ ಮಾಡಿದ 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 @datacenter_id_bits = 5
11 @worker_id_bits = 5
12 @sequence_bits = 12
13 @max_datacenter_id = -1 ^ (-1 << @datacenter_id_bits)
14 @max_worker_id = -1 ^ (-1 << @worker_id_bits)
15 @worker_id_shift = @sequence_bits
16 @datacenter_id_shift = @sequence_bits + @worker_id_bits
17 @timestamp_left_shift = @sequence_bits + @worker_id_bits + @datacenter_id_bits
18 @sequence_mask = -1 ^ (-1 << @sequence_bits)
19 end
20
21 def next_id
22 timestamp = (Time.now.to_f * 1000).to_i
23 raise 'ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ' if timestamp < @last_timestamp
24
25 if timestamp == @last_timestamp
26 @sequence = (@sequence + 1) & @sequence_mask
27 timestamp = til_next_millis(@last_timestamp) if @sequence == 0
28 else
29 @sequence = 0
30 end
31
32 @last_timestamp = timestamp
33
34 ((timestamp - @epoch) << @timestamp_left_shift) |
35 (@datacenter_id << @datacenter_id_shift) |
36 (@worker_id << @worker_id_shift) |
37 @sequence
38 end
39
40 private
41
42 def til_next_millis(last_timestamp)
43 timestamp = (Time.now.to_f * 1000).to_i
44 timestamp = (Time.now.to_f * 1000).to_i while timestamp <= last_timestamp
45 timestamp
46 end
47end
48
49## ಬಳಸುವುದು
50generator = SnowflakeGenerator.new(1, 1)
51snowflake_id = generator.next_id
52puts "ಉತ್ಪತ್ತಿ ಮಾಡಿದ Snowflake ID: #{snowflake_id}"
53
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 can't be greater than maxDatacenterId or less than 0");
36 }
37 if ($workerId > $this->maxWorkerId || $workerId < 0) {
38 throw new Exception("workerId can't be greater than maxWorkerId or less than 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("ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ. 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// ಬಳಸುವುದು
82$generator = new SnowflakeGenerator(1, 1);
83$id = $generator->nextId();
84echo "ಉತ್ಪತ್ತಿ ಮಾಡಿದ Snowflake ID: " . $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 can't be greater than {_maxDatacenterId} or less than 0");
42 }
43 if (workerId > _maxWorkerId || workerId < 0)
44 {
45 throw new ArgumentException($"workerId can't be greater than {_maxWorkerId} or less than 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("ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ. 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// ಬಳಸುವುದು
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($"ಉತ್ಪತ್ತಿ ಮಾಡಿದ Snowflake ID: {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 can't be greater than %d or less than 0", g.maxDatacenterId)
48 }
49 if workerId > g.maxWorkerId || workerId < 0 {
50 return nil, fmt.Errorf("workerId can't be greater than %d or less than 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("ಕ್ಲಾಕ್ ಹಿಂದಕ್ಕೆ ಹೋಗಿದೆ, 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("ಜನರೇಟರ್ ರಚಿಸುವಾಗ ದೋಷ: %v\n", err)
101 return
102 }
103
104 id, err := generator.NextId()
105 if err != nil {
106 fmt.Printf("ID ಅನ್ನು ಉತ್ಪಾದಿಸುವಾಗ ದೋಷ: %v\n", err)
107 return
108 }
109
110 fmt.Printf("ಉತ್ಪತ್ತಿ ಮಾಡಿದ Snowflake ID: %d\n", id)
111}
112
ಚಿತ್ರಣ
Snowflake ID ರಚನೆಯ ದೃಶ್ಯಾತ್ಮಕ ಪ್ರತಿನಿಧಿಯನ್ನು ಇಲ್ಲಿದೆ:
ಉಲ್ಲೇಖಗಳು
- "Snowflake ಅನ್ನು ಘೋಷಿಸುತ್ತಿರುವುದು." ಟ್ವಿಟ್ಟರ್ ಎಂಜಿನಿಯರಿಂಗ್ ಬ್ಲಾಗ್, https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
- "Snowflake ID." ವಿಕಿಪೀಡಿಯಾ, https://en.wikipedia.org/wiki/Snowflake_ID
- "ಮೈಕ್ರೋಸರ್ವೀಸ್ಗಳಲ್ಲಿ ವಿತರಣಾ ID ಉತ್ಪಾದನೆ." ಮೀಡಿಯಮ್, https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f
ಪ್ರತಿಕ್ರಿಯೆ
ಈ ಸಾಧನದ ಬಗ್ಗೆ ಪ್ರತಿಕ್ರಿಯೆ ನೀಡಲು ಪ್ರತಿಕ್ರಿಯೆ ಟೋಸ್ಟ್ ಅನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿ
ಸಂಬಂಧಿತ ಸಾಧನಗಳು
ನಿಮ್ಮ ಕಾರ್ಯಪ್ರವೃತ್ತಿಗೆ ಉಪಯುಕ್ತವಾಗಬಹುದಾದ ಇನ್ನಷ್ಟು ಸಾಧನಗಳನ್ನು ಅನ್ವೇಷಿಸಿ