ਸਨੋਫਲੇਕ ਆਈਡੀ ਜਨਰੇਟਰ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਟੂਲ
ਟਵਿੱਟਰ ਸਨੋਫਲੇਕ ਆਈਡੀ, ਵਿਸ਼ੇਸ਼ 64-ਬਿੱਟ ਪਛਾਣਕਰਤਾ ਜੋ ਵੰਡੇ ਗਏ ਪ੍ਰਣਾਲੀਆਂ ਵਿੱਚ ਵਰਤੇ ਜਾਂਦੇ ਹਨ, ਨੂੰ ਜਨਰੇਟ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕਰੋ। ਇਹ ਟੂਲ ਤੁਹਾਨੂੰ ਨਵੇਂ ਸਨੋਫਲੇਕ ਆਈਡੀ ਬਣਾਉਣ ਅਤੇ ਮੌਜੂਦਾ ਆਈਡੀ ਨੂੰ ਪਾਰਸ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਉਨ੍ਹਾਂ ਦੇ ਟਾਈਮਸਟੈਂਪ, ਮਸ਼ੀਨ ਆਈਡੀ ਅਤੇ ਸੀਕਵੈਂਸ ਨੰਬਰ ਦੇ ਘਟਕਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ।
ਸਨੋਫਲੇਕ ਆਈਡੀ ਜਨਰੇਟਰ
ਸਨੋਫਲੇਕ ਆਈਡੀ ਜਨਰੇਟਰ
ਦਸਤਾਵੇਜ਼
1## Snowflake ID Generator
2
3### Introduction
4
5ਇੱਕ Snowflake ID ਇੱਕ ਵਿਲੱਖਣ ਪਛਾਣਕਰਤਾ ਹੈ ਜੋ ਵੰਡੇ ਗਏ ਪ੍ਰਣਾਲੀਆਂ ਵਿੱਚ ਵਰਤਿਆ ਜਾਂਦਾ ਹੈ, ਜੋ ਪਹਿਲਾਂ ਟਵਿੱਟਰ ਦੁਆਰਾ ਵਿਕਸਤ ਕੀਤਾ ਗਿਆ ਸੀ। ਇਹ ਟੂਲ ਤੁਹਾਨੂੰ Snowflake IDs ਨੂੰ ਜਨਰੇਟ ਅਤੇ ਵਿਸ਼ਲੇਸ਼ਣ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜੋ ਕਿ ਇੱਕ ਟਾਈਮਸਟੈਂਪ, ਮਸ਼ੀਨ ID, ਅਤੇ ਕ੍ਰਮ ਨੰਬਰ ਤੋਂ ਬਣੇ 64-ਬਿੱਟ ਇੰਟੀਜਰ ਹਨ।
6
7### How Snowflake IDs Work
8
9Snowflake IDs 64-ਬਿੱਟ ਇੰਟੀਜਰ ਹਨ ਜੋ ਇਸ ਤਰ੍ਹਾਂ ਦੀ ਰਚਨਾ ਰੱਖਦੇ ਹਨ:
10
11- 41 ਬਿੱਟ: ਟਾਈਮਸਟੈਂਪ (ਇੱਕ ਕਸਟਮ ਯੁੱਗ ਤੋਂ ਬਾਅਦ ਦੇ ਮਿਲੀਸਕਿੰਟ)
12- 10 ਬਿੱਟ: ਮਸ਼ੀਨ ID (5 ਬਿੱਟ ਡੇਟਾ ਸੈਂਟਰ ID ਲਈ, 5 ਬਿੱਟ ਵਰਕਰ ID ਲਈ)
13- 12 ਬਿੱਟ: ਕ੍ਰਮ ਨੰਬਰ
14
15ਇਹ ਰਚਨਾ ਇੱਕ ਮਸ਼ੀਨ ਪ੍ਰਤੀ ਮਿਲੀਸਕਿੰਟ ਵਿੱਚ ਲਗਭਗ 4,096 ਵਿਲੱਖਣ IDs ਦੇ ਨਿਰਮਾਣ ਦੀ ਆਗਿਆ ਦਿੰਦੀ ਹੈ।
16
17### Using the Snowflake ID Generator
18
191. (ਵਿਕਲਪਿਕ) ਇੱਕ ਕਸਟਮ ਯੁੱਗ ਸੈਟ ਕਰੋ (ਡਿਫਾਲਟ ਟਵਿੱਟਰ ਦਾ ਯੁੱਗ: 2010-11-04T01:42:54.657Z)
202. ਇੱਕ ਮਸ਼ੀਨ ID (0-31) ਅਤੇ ਡੇਟਾ ਸੈਂਟਰ ID (0-31) ਦਰਜ ਕਰੋ
213. ਇੱਕ ਨਵਾਂ Snowflake ID ਬਣਾਉਣ ਲਈ "ਜਨਰੇਟ" 'ਤੇ ਕਲਿਕ ਕਰੋ
224. ਬਣਾਇਆ ਗਿਆ ID ਅਤੇ ਇਸ ਦੇ ਘਟਕ ਦਿਖਾਏ ਜਾਣਗੇ
23
24ਇੱਕ ਮੌਜੂਦਾ Snowflake ID ਨੂੰ ਪਾਰਸ ਕਰਨ ਲਈ, ਇਸਨੂੰ "Parse ID" ਖੇਤਰ ਵਿੱਚ ਦਰਜ ਕਰੋ ਅਤੇ "Parse" 'ਤੇ ਕਲਿਕ ਕਰੋ।
25
26### Formula
27
28Snowflake ID ਬਿੱਟਵਾਈਜ਼ ਓਪਰੇਸ਼ਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਬਣਾਇਆ ਜਾਂਦਾ ਹੈ:
29
30
plaintext ID = (timestamp << 22) | (datacenterId << 17) | (workerId << 12) | sequence
1
2ਜਿੱਥੇ:
3- `timestamp` ਯੁੱਗ ਤੋਂ ਬਾਅਦ ਦੇ ਮਿਲੀਸਕਿੰਟ ਦੀ ਗਿਣਤੀ ਹੈ
4- `datacenterId` ਇੱਕ 5-ਬਿੱਟ ਦਾ ਇੰਟੀਜਰ (0-31)
5- `workerId` ਇੱਕ 5-ਬਿੱਟ ਦਾ ਇੰਟੀਜਰ (0-31)
6- `sequence` ਇੱਕ 12-ਬਿੱਟ ਦਾ ਇੰਟੀਜਰ (0-4095)
7
8### Calculation
9
10Snowflake ID ਜਨਰੇਟਰ ਹੇਠ ਲਿਖੇ ਕਦਮਾਂ ਨੂੰ ਅੰਜਾਮ ਦਿੰਦਾ ਹੈ:
11
121. ਮਿਲੀਸਕਿੰਟ ਵਿੱਚ ਮੌਜੂਦਾ ਟਾਈਮਸਟੈਂਪ ਪ੍ਰਾਪਤ ਕਰੋ
132. ਯਕੀਨੀ ਬਣਾਓ ਕਿ ਟਾਈਮਸਟੈਂਪ ਪਿਛਲੇ ਵਰਤੇ ਗਏ ਟਾਈਮਸਟੈਂਪ ਤੋਂ ਵੱਧ ਹੈ (ਵਿਲੱਖਣਤਾ ਲਈ)
143. ਜੇ ਟਾਈਮਸਟੈਂਪ ਪਿਛਲੇ ਨਾਲ ਸਮਾਨ ਹੈ, ਤਾਂ ਕ੍ਰਮ ਨੰਬਰ ਵਧਾਓ
154. ਜੇ ਕ੍ਰਮ ਨੰਬਰ ਓਵਰਫਲੋ ਹੋ ਜਾਂਦਾ ਹੈ (4096 ਤੱਕ ਪਹੁੰਚ ਜਾਂਦਾ ਹੈ), ਤਾਂ ਅਗਲੇ ਮਿਲੀਸਕਿੰਟ ਲਈ ਰੁਕੋ
165. ਆਖਰੀ ID ਬਣਾਉਣ ਲਈ ਬਿੱਟਵਾਈਜ਼ ਓਪਰੇਸ਼ਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਘਟਕਾਂ ਨੂੰ ਜੋੜੋ
17
18### Use Cases
19
20Snowflake IDs ਖਾਸ ਤੌਰ 'ਤੇ ਹੇਠ ਲਿਖੇ ਵਿੱਚ ਲਾਭਦਾਇਕ ਹਨ:
21
221. ਵੰਡੇ ਗਏ ਪ੍ਰਣਾਲੀਆਂ: ਬਿਨਾਂ ਸਹਿਯੋਗ ਦੇ ਕਈ ਮਸ਼ੀਨਾਂ ਵਿੱਚ ਵਿਲੱਖਣ IDs ਬਣਾਉਣਾ
232. ਉੱਚ-ਵੋਲਿਊਮ ਡੇਟਾ: ਵੱਡੇ ਡੇਟਾਸੇਟਾਂ ਲਈ ਸੋਰਟ ਕਰਨਯੋਗ IDs ਬਣਾਉਣਾ
243. ਮਾਈਕਰੋਸਰਵਿਸਜ਼: ਵੱਖ-ਵੱਖ ਸੇਵਾਵਾਂ ਵਿੱਚ ਵਿਲੱਖਣ ਪਛਾਣਕਰਤਾ ਯਕੀਨੀ ਬਣਾਉਣਾ
254. ਡੇਟਾਬੇਸ ਸ਼ਾਰਡਿੰਗ: ਪ੍ਰਭਾਵਸ਼ਾਲੀ ਸ਼ਾਰਡਿੰਗ ਲਈ ਟਾਈਮਸਟੈਂਪ ਜਾਂ ਮਸ਼ੀਨ ID ਘਟਕ ਦੀ ਵਰਤੋਂ ਕਰੋ
26
27#### Alternatives
28
29ਜਦੋਂ ਕਿ Snowflake IDs ਸ਼ਕਤੀਸ਼ਾਲੀ ਹਨ, ਹੋਰ ID ਜਨਰੇਸ਼ਨ ਪ੍ਰਣਾਲੀਆਂ ਵਿੱਚ ਸ਼ਾਮਲ ਹਨ:
30
311. UUID (ਯੂਨੀਵਰਸਲ ਯੂਨੀਕ ਪਛਾਣਕਰਤਾ): ਜਦੋਂ ਵੰਡੇ ਗਏ ਜਨਰੇਸ਼ਨ ਦੀ ਲੋੜ ਹੋਵੇ ਬਿਨਾਂ ਸੋਰਟ ਕਰਨਯੋਗਤਾ
322. ਆਟੋ-ਇੰਕ੍ਰਿਮੈਂਟਿੰਗ ਡੇਟਾਬੇਸ IDs: ਸਧਾਰਨ ਪਰ ਇੱਕਲ ਡੇਟਾਬੇਸ ਉਦਾਹਰਣਾਂ ਲਈ ਸੀਮਤ
333. ULID (ਯੂਨੀਵਰਸਲ ਯੂਨੀਕ ਲੈਕਸਿਕੋਗ੍ਰਾਫਿਕਲੀ ਸੋਰਟ ਕਰਨਯੋਗ ਪਛਾਣਕਰਤਾ): Snowflake ਦੇ ਸਮਾਨ, ਪਰ ਵੱਖਰੀ ਰਚਨਾ ਨਾਲ
34
35### Edge Cases and Limitations
36
371. ਘੜੀ ਸਮਰੂਪਤਾ: Snowflake IDs ਸਿਸਟਮ ਦੇ ਸਮੇਂ 'ਤੇ ਨਿਰਭਰ ਕਰਦੇ ਹਨ। ਜੇ ਘੜੀ NTP ਸਮਾਜਾਂਤਰਣ ਜਾਂ ਦਿਨ ਦੀ ਬਚਤ ਸਮੇਂ ਦੇ ਬਦਲਾਅ ਕਾਰਨ ਪਿੱਛੇ ਜਾਂਦੀ ਹੈ, ਤਾਂ ID ਜਨਰੇਸ਼ਨ ਵਿੱਚ ਸਮੱਸਿਆ ਹੋ ਸਕਦੀ ਹੈ।
38
392. ਸਾਲ 2038 ਸਮੱਸਿਆ: 41-ਬਿੱਟ ਦਾ ਟਾਈਮਸਟੈਂਪ 2079 ਵਿੱਚ ਓਵਰਫਲੋ ਹੋ ਜਾਵੇਗਾ (ਟਵਿੱਟਰ ਯੁੱਗ ਨੂੰ ਧਿਆਨ ਵਿੱਚ ਰੱਖਦੇ ਹੋਏ)। Snowflake IDs ਵਰਤਣ ਵਾਲੇ ਪ੍ਰਣਾਲੀਆਂ ਨੂੰ ਇਸ ਸੰਭਾਵਨਾ ਲਈ ਯੋਜਨਾ ਬਣਾਉਣੀ ਚਾਹੀਦੀ ਹੈ।
40
413. ਮਸ਼ੀਨ ID ਟਕਰਾਅ: ਵੱਡੇ ਵੰਡੇ ਗਏ ਪ੍ਰਣਾਲੀਆਂ ਵਿੱਚ, ਵਿਲੱਖਣ ਮਸ਼ੀਨ IDs ਨੂੰ ਯਕੀਨੀ ਬਣਾਉਣਾ ਚੁਣੌਤੀਪੂਰਨ ਹੋ ਸਕਦਾ ਹੈ ਅਤੇ ਹੋਰ ਸਹਿਯੋਗ ਦੀ ਲੋੜ ਹੋ ਸਕਦੀ ਹੈ।
42
434. ਕ੍ਰਮ ਓਵਰਫਲੋ: ਬਹੁਤ ਉੱਚ-ਥਰੋਪੁੱਟ ਸਥਿਤੀਆਂ ਵਿੱਚ, 4096 ਕ੍ਰਮਾਂ ਨੂੰ ਪ੍ਰਤੀ ਮਿਲੀਸਕਿੰਟ ਖਤਮ ਕਰਨਾ ਸੰਭਵ ਹੈ, ਜੋ ਸੰਭਵਤ: ਦੇਰੀ ਦਾ ਕਾਰਨ ਬਣ ਸਕਦਾ ਹੈ।
44
455. ਮਸ਼ੀਨਾਂ ਵਿੱਚ ਗੈਰ-ਮੋਨੋਟੋਨਿਕਤਾ: ਜਦੋਂ ਕਿ IDs ਇੱਕ ਹੀ ਮਸ਼ੀਨ 'ਤੇ ਮੋਨੋਟੋਨਿਕ ਵਧ ਰਹੇ ਹਨ, ਉਹ ਕਈ ਮਸ਼ੀਨਾਂ ਵਿੱਚ ਸਖਤ ਮੋਨੋਟੋਨਿਕ ਨਹੀਂ ਹੋ ਸਕਦੇ।
46
47### History
48
49Snowflake IDs 2010 ਵਿੱਚ ਟਵਿੱਟਰ ਦੁਆਰਾ ਵੰਡੇ ਗਏ, ਸਮੇਂ-ਸੋਰਟ ਕਰਨਯੋਗ ਵਿਲੱਖਣ ਪਛਾਣਕਰਤਿਆਂ ਦੀ ਲੋੜ ਨੂੰ ਪੂਰਾ ਕਰਨ ਲਈ। ਇਹ ਬਾਅਦ ਵਿੱਚ ਹੋਰ ਕਈ ਕੰਪਨੀਆਂ ਅਤੇ ਪ੍ਰੋਜੈਕਟਾਂ ਦੁਆਰਾ ਅਪਣਾਏ ਗਏ ਅਤੇ ਅਨੁਕੂਲਿਤ ਕੀਤੇ ਗਏ ਹਨ।
50
51### Examples
52
53ਇਹਾਂ ਵੱਖ-ਵੱਖ ਭਾਸ਼ਾਵਾਂ ਵਿੱਚ Snowflake ID ਜਨਰੇਟਰਾਂ ਦੇ ਕਾਰਜਾਂ ਹਨ:
54
55
javascript class SnowflakeGenerator { constructor(epoch = 1288834974657, datacenterIdBits = 5, workerIdBits = 5, sequenceBits = 12) { this.epoch = BigInt(epoch); this.datacenterIdBits = datacenterIdBits; this.workerIdBits = workerIdBits; this.sequenceBits = sequenceBits; this.maxDatacenterId = -1n ^ (-1n << BigInt(datacenterIdBits)); this.maxWorkerId = -1n ^ (-1n << BigInt(workerIdBits)); this.sequenceMask = -1n ^ (-1n << BigInt(sequenceBits)); this.workerIdShift = BigInt(sequenceBits); this.datacenterIdShift = BigInt(sequenceBits + workerIdBits); this.timestampLeftShift = BigInt(sequenceBits + workerIdBits + datacenterIdBits); this.sequence = 0n; this.lastTimestamp = -1n; }
nextId(datacenterId, workerId) { let timestamp = this.currentTimestamp();
if (timestamp < this.lastTimestamp) {
throw new Error('ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ। ID ਬਣਾਉਣ ਤੋਂ ਇਨਕਾਰ ਕਰਨਾ');
}
if (timestamp === this.lastTimestamp) {
this.sequence = (this.sequence + 1n) & this.sequenceMask;
if (this.sequence === 0n) {
timestamp = this.tilNextMillis(this.lastTimestamp);
}
} else {
this.sequence = 0n;
}
this.lastTimestamp = timestamp;
return ((timestamp - this.epoch) << this.timestampLeftShift) |
(BigInt(datacenterId) << this.datacenterIdShift) |
(BigInt(workerId) << this.workerIdShift) |
this.sequence;
}
tilNextMillis(lastTimestamp) { let timestamp = this.currentTimestamp(); while (timestamp <= lastTimestamp) { timestamp = this.currentTimestamp(); } return timestamp; }
currentTimestamp() { return BigInt(Date.now()); } }
// ਵਰਤੋਂ
const generator = new SnowflakeGenerator();
const id = generator.nextId(1, 1);
console.log(ਬਣਾਇਆ ਗਿਆ Snowflake ID: ${id}
);
1
2
python import time import threading
class SnowflakeGenerator: def init(self, datacenter_id, worker_id, sequence=0): self.datacenter_id = datacenter_id self.worker_id = worker_id self.sequence = sequence
self.last_timestamp = -1
self.epoch = 1288834974657
self.datacenter_id_bits = 5
self.worker_id_bits = 5
self.sequence_bits = 12
self.max_datacenter_id = -1 ^ (-1 << self.datacenter_id_bits)
self.max_worker_id = -1 ^ (-1 << self.worker_id_bits)
self.worker_id_shift = self.sequence_bits
self.datacenter_id_shift = self.sequence_bits + self.worker_id_bits
self.timestamp_left_shift = self.sequence_bits + self.worker_id_bits + self.datacenter_id_bits
self.sequence_mask = -1 ^ (-1 << self.sequence_bits)
self._lock = threading.Lock()
def _til_next_millis(self, last_timestamp):
timestamp = self._get_timestamp()
while timestamp <= last_timestamp:
timestamp = self._get_timestamp()
return timestamp
def _get_timestamp(self):
return int(time.time() * 1000)
def next_id(self):
with self._lock:
timestamp = self._get_timestamp()
if timestamp < self.last_timestamp:
raise ValueError("ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ। ID ਬਣਾਉਣ ਤੋਂ ਇਨਕਾਰ ਕਰਨਾ")
if timestamp == self.last_timestamp:
self.sequence = (self.sequence + 1) & self.sequence_mask
if self.sequence == 0:
timestamp = self._til_next_millis(self.last_timestamp)
else:
self.sequence = 0
self.last_timestamp = timestamp
return ((timestamp - self.epoch) << self.timestamp_left_shift) | \
(self.datacenter_id << self.datacenter_id_shift) | \
(self.worker_id << self.worker_id_shift) | \
self.sequence
ਵਰਤੋਂ
generator = SnowflakeGenerator(datacenter_id=1, worker_id=1) snowflake_id = generator.next_id() print(f"ਬਣਾਇਆ ਗਿਆ Snowflake ID: {snowflake_id}")
1
2
java import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
public class SnowflakeGenerator { private final long epoch; private final long datacenterIdBits; private final long workerIdBits; private final long sequenceBits; private final long maxDatacenterId; private final long maxWorkerId; private final long workerIdShift; private final long datacenterIdShift; private final long timestampLeftShift; private final long sequenceMask;
private long datacenterId;
private long workerId;
private long sequence = 0L;
private long lastTimestamp = -1L;
private final Lock lock = new ReentrantLock();
public SnowflakeGenerator(long datacenterId, long workerId) {
this.epoch = 1288834974657L;
this.datacenterIdBits = 5L;
this.workerIdBits = 5L;
this.sequenceBits = 12L;
this.maxDatacenterId = ~(-1L << datacenterIdBits);
this.maxWorkerId = ~(-1L << workerIdBits);
this.workerIdShift = sequenceBits;
this.datacenterIdShift = sequenceBits + workerIdBits;
this.timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
this.sequenceMask = ~(-1L << sequenceBits);
if (datacenterId > maxDatacenterId || datacenterId < 0) {
throw new IllegalArgumentException("datacenterId can't be greater than maxDatacenterId or less than 0");
}
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException("workerId can't be greater than maxWorkerId or less than 0");
}
this.datacenterId = datacenterId;
this.workerId = workerId;
}
public long nextId() {
lock.lock();
try {
long timestamp = timeGen();
if (timestamp < lastTimestamp) {
throw new RuntimeException("ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ। ID ਬਣਾਉਣ ਤੋਂ ਇਨਕਾਰ ਕਰਨਾ");
}
if (lastTimestamp == timestamp) {
sequence = (sequence + 1) & sequenceMask;
if (sequence == 0) {
timestamp = tilNextMillis(lastTimestamp);
}
} else {
sequence = 0L;
}
lastTimestamp = timestamp;
return ((timestamp - epoch) << timestampLeftShift) |
(datacenterId << datacenterIdShift) |
(workerId << workerIdShift) |
sequence;
} finally {
lock.unlock();
}
}
private long tilNextMillis(long lastTimestamp) {
long timestamp = timeGen();
while (timestamp <= lastTimestamp) {
timestamp = timeGen();
}
return timestamp;
}
private long timeGen() {
return System.currentTimeMillis();
}
public static void main(String[] args) {
SnowflakeGenerator generator = new SnowflakeGenerator(1, 1);
long id = generator.nextId();
System.out.println("ਬਣਾਇਆ ਗਿਆ Snowflake ID: " + id);
}
}
1
2
ruby require 'time'
class SnowflakeGenerator def initialize(datacenter_id, worker_id, sequence = 0) @datacenter_id = datacenter_id @worker_id = worker_id @sequence = sequence @last_timestamp = -1 @epoch = 1288834974657
@datacenter_id_bits = 5
@worker_id_bits = 5
@sequence_bits = 12
@max_datacenter_id = -1 ^ (-1 << @datacenter_id_bits)
@max_worker_id = -1 ^ (-1 << @worker_id_bits)
@worker_id_shift = @sequence_bits
@datacenter_id_shift = @sequence_bits + @worker_id_bits
@timestamp_left_shift = @sequence_bits + @worker_id_bits + @datacenter_id_bits
@sequence_mask = -1 ^ (-1 << @sequence_bits)
end
def next_id timestamp = (Time.now.to_f * 1000).to_i
raise 'ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ' if timestamp < @last_timestamp
if timestamp == @last_timestamp
@sequence = (@sequence + 1) & @sequence_mask
timestamp = til_next_millis(@last_timestamp) if @sequence == 0
else
@sequence = 0
end
@last_timestamp = timestamp
((timestamp - @epoch) << @timestamp_left_shift) |
(@datacenter_id << @datacenter_id_shift) |
(@worker_id << @worker_id_shift) |
@sequence
end
private
def til_next_millis(last_timestamp) timestamp = (Time.now.to_f * 1000).to_i timestamp = (Time.now.to_f * 1000).to_i while timestamp <= last_timestamp timestamp end end
ਵਰਤੋਂ
generator = SnowflakeGenerator.new(1, 1) snowflake_id = generator.next_id puts "ਬਣਾਇਆ ਗਿਆ Snowflake ID: #{snowflake_id}"
1
2
php
epoch = 1288834974657; $this->datacenterIdBits = 5; $this->workerIdBits = 5; $this->sequenceBits = 12; $this->maxDatacenterId = -1 ^ (-1 << $this->datacenterIdBits); $this->maxWorkerId = -1 ^ (-1 << $this->workerIdBits); $this->workerIdShift = $this->sequenceBits; $this->datacenterIdShift = $this->sequenceBits + $this->workerIdBits; $this->timestampLeftShift = $this->sequenceBits + $this->workerIdBits + $this->datacenterIdBits; $this->sequenceMask = -1 ^ (-1 << $this->sequenceBits); if ($datacenterId > $this->maxDatacenterId || $datacenterId < 0) { throw new Exception("datacenterId can't be greater than maxDatacenterId or less than 0"); } if ($workerId > $this->maxWorkerId || $workerId < 0) { throw new Exception("workerId can't be greater than maxWorkerId or less than 0"); } $this->datacenterId = $datacenterId; $this->workerId = $workerId; } public function nextId() { $timestamp = $this->timeGen(); if ($timestamp < $this->lastTimestamp) { throw new Exception("ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ। ID ਬਣਾਉਣ ਤੋਂ ਇਨਕਾਰ ਕਰਨਾ"); } if ($this->lastTimestamp == $timestamp) { $this->sequence = ($this->sequence + 1) & $this->sequenceMask; if ($this->sequence == 0) { $timestamp = $this->tilNextMillis($this->lastTimestamp); } } else { $this->sequence = 0; } $this->lastTimestamp = $timestamp; return (($timestamp - $this->epoch) << $this->timestampLeftShift) | ($this->datacenterId << $this->datacenterIdShift) | ($this->workerId << $this->workerIdShift) | $this->sequence; } private function tilNextMillis($lastTimestamp) { $timestamp = $this->timeGen(); while ($timestamp <= $lastTimestamp) { $timestamp = $this->timeGen(); } return $timestamp; } private function timeGen() { return floor(microtime(true) * 1000); } } // ਵਰਤੋਂ $generator = new SnowflakeGenerator(1, 1); $id = $generator->nextId(); echo "ਬਣਾਇਆ ਗਿਆ Snowflake ID: " . $id . "\n";1
2
csharp using System; using System.Threading;
public class SnowflakeGenerator { private readonly long _epoch; private readonly int _datacenterIdBits; private readonly int _workerIdBits; private readonly int _sequenceBits; private readonly long _maxDatacenterId; private readonly long _maxWorkerId; private readonly int _workerIdShift; private readonly int _datacenterIdShift; private readonly int _timestampLeftShift; private readonly long _sequenceMask;
private readonly long _datacenterId;
private readonly long _workerId;
private long _sequence = 0L;
private long _lastTimestamp = -1L;
private readonly object _lock = new object();
public SnowflakeGenerator(long datacenterId, long workerId)
{
_epoch = 1288834974657L;
_datacenterIdBits = 5;
_workerIdBits = 5;
_sequenceBits = 12;
_maxDatacenterId = -1L ^ (-1L << _datacenterIdBits);
_maxWorkerId = -1L ^ (-1L << _workerIdBits);
_workerIdShift = _sequenceBits;
_datacenterIdShift = _sequenceBits + _workerIdBits;
_timestampLeftShift = _sequenceBits + _workerIdBits + _datacenterIdBits;
_sequenceMask = -1L ^ (-1L << _sequenceBits);
if (datacenterId > _maxDatacenterId || datacenterId < 0)
{
throw new ArgumentException($"datacenterId can't be greater than {_maxDatacenterId} or less than 0");
}
if (workerId > _maxWorkerId || workerId < 0)
{
throw new ArgumentException($"workerId can't be greater than {_maxWorkerId} or less than 0");
}
_datacenterId = datacenterId;
_workerId = workerId;
}
public long NextId()
{
lock (_lock)
{
var timestamp = TimeGen();
if (timestamp < _lastTimestamp)
{
throw new Exception("ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ। ID ਬਣਾਉਣ ਤੋਂ ਇਨਕਾਰ ਕਰਨਾ");
}
if (_lastTimestamp == timestamp)
{
_sequence = (_sequence + 1) & _sequenceMask;
if (_sequence == 0)
{
timestamp = TilNextMillis(_lastTimestamp);
}
}
else
{
_sequence = 0L;
}
_lastTimestamp = timestamp;
return ((timestamp - _epoch) << _timestampLeftShift) |
(_datacenterId << _datacenterIdShift) |
(_workerId << _workerIdShift) |
_sequence;
}
}
private long TilNextMillis(long lastTimestamp)
{
var timestamp = TimeGen();
while (timestamp <= lastTimestamp)
{
timestamp = TimeGen();
}
return timestamp;
}
private long TimeGen()
{
return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
}
// ਵਰਤੋਂ class Program { static void Main(string[] args) { var generator = new SnowflakeGenerator(1, 1); var id = generator.NextId(); Console.WriteLine($"ਬਣਾਇਆ ਗਿਆ Snowflake ID: {id}"); } }
1
2
go package main
import ( "fmt" "sync" "time" )
type SnowflakeGenerator struct { epoch int64 datacenterIdBits uint workerIdBits uint sequenceBits uint maxDatacenterId int64 maxWorkerId int64 workerIdShift uint datacenterIdShift uint timestampLeftShift uint sequenceMask int64
datacenterId int64
workerId int64
sequence int64
lastTimestamp int64
lock sync.Mutex
}
func NewSnowflakeGenerator(datacenterId, workerId int64) (*SnowflakeGenerator, error) { g := &SnowflakeGenerator{ epoch: 1288834974657, datacenterIdBits: 5, workerIdBits: 5, sequenceBits: 12, lastTimestamp: -1, }
g.maxDatacenterId = -1 ^ (-1 << g.datacenterIdBits)
g.maxWorkerId = -1 ^ (-1 << g.workerIdBits)
g.workerIdShift = g.sequenceBits
g.datacenterIdShift = g.sequenceBits + g.workerIdBits
g.timestampLeftShift = g.sequenceBits + g.workerIdBits + g.datacenterIdBits
g.sequenceMask = -1 ^ (-1 << g.sequenceBits)
if datacenterId > g.maxDatacenterId || datacenterId < 0 {
return nil, fmt.Errorf("datacenterId can't be greater than %d or less than 0", g.maxDatacenterId)
}
if workerId > g.maxWorkerId || workerId < 0 {
return nil, fmt.Errorf("workerId can't be greater than %d or less than 0", g.maxWorkerId)
}
g.datacenterId = datacenterId
g.workerId = workerId
return g, nil
}
func (g *SnowflakeGenerator) NextId() (int64, error) { g.lock.Lock() defer g.lock.Unlock()
timestamp := g.timeGen()
if timestamp < g.lastTimestamp {
return 0, fmt.Errorf("ਘੜੀ ਪਿੱਛੇ ਮੁੜ ਗਈ ਹੈ, ID ਬਣਾਉਣ ਤੋਂ ਇਨਕਾਰ ਕਰਨਾ")
}
if g.lastTimestamp == timestamp {
g.sequence = (g.sequence + 1) & g.sequenceMask
if g.sequence == 0 {
timestamp = g.tilNextMillis(g.lastTimestamp)
}
} else {
g.sequence = 0
}
g.lastTimestamp = timestamp
return ((timestamp - g.epoch) << g.timestampLeftShift) |
(g.datacenterId << g.datacenterIdShift) |
(g.workerId << g.workerIdShift) |
g.sequence, nil
}
func (g *SnowflakeGenerator) tilNextMillis(lastTimestamp int64) int64 { timestamp := g.timeGen() for timestamp <= lastTimestamp { timestamp = g.timeGen() } return timestamp }
func (g *SnowflakeGenerator) timeGen() int64 { return time.Now().UnixNano() / int64(time.Millisecond) }
func main() { generator, err := NewSnowflakeGenerator(1, 1) if err != nil { fmt.Printf("ਜਨਰੇਟਰ ਬਣਾਉਣ ਵਿੱਚ ਗਲਤੀ: %v\n", err) return }
id, err := generator.NextId()
if err != nil {
fmt.Printf("ID ਬਣਾਉਣ ਵਿੱਚ ਗਲਤੀ: %v\n", err)
return
}
fmt.Printf("ਬਣਾਇਆ ਗਿਆ Snowflake ID: %d\n", id)
}
1
2### Diagram
3
4ਇੱਥੇ Snowflake ID ਦੀ ਰਚਨਾ ਦਾ ਵਿਜ਼ੂਅਲ ਪ੍ਰਤੀਨਿਧੀ ਹੈ:
5
6<svg width="600" height="100" xmlns="http://www.w3.org/2000/svg">
7 <rect x="0" y="0" width="380" height="50" fill="#4299e1"/>
8 <text x="190" y="30" font-family="Arial" fontSize="14" fill="white" textAnchor="middle">ਟਾਈਮਸਟੈਂਪ (41 ਬਿੱਟ)</text>
9
10 <rect x="380" y="0" width="90" height="50" fill="#48bb78"/>
11 <text x="425" y="30" font-family="Arial" fontSize="14" fill="white" textAnchor="middle">ਮਸ਼ੀਨ ID (10 ਬਿੱਟ)</text>
12
13 <rect x="470" y="0" width="130" height="50" fill="#ed8936"/>
14 <text x="535" y="30" font-family="Arial" fontSize="14" fill="white" textAnchor="middle">ਕ੍ਰਮ (12 ਬਿੱਟ)</text>
15
16 <text x="300" y="80" font-family="Arial" fontSize="16" fill="black" textAnchor="middle">64-ਬਿੱਟ Snowflake ID ਰਚਨਾ</text>
17</svg>
18
19### References
20
211. "Snowflake ਦੀ ਘੋਸ਼ਣਾ।" ਟਵਿੱਟਰ ਇੰਜੀਨੀਅਰਿੰਗ ਬਲਾਗ, https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
222. "Snowflake ID।" ਵਿਕੀਪੀਡੀਆ, https://en.wikipedia.org/wiki/Snowflake_ID
233. "ਮਾਈਕਰੋਸਰਵਿਸਜ਼ ਵਿੱਚ ਵੰਡੇ ਗਏ ID ਜਨਰੇਸ਼ਨ।" ਮੀਡਿਅਮ, https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f
24
ਫੀਡਬੈਕ
ਇਸ ਟੂਲ ਬਾਰੇ ਫੀਡਬੈਕ ਦੇਣ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਫੀਡਬੈਕ ਟੋਸਟ 'ਤੇ ਕਲਿੱਕ ਕਰੋ
ਸੰਬੰਧਿਤ ਟੂਲ
ਹੋਰ ਟੂਲਾਂ ਦੀ ਖੋਜ ਕਰੋ ਜੋ ਤੁਹਾਡੇ ਕੰਮ ਦੇ ਪ੍ਰਵਾਹ ਲਈ ਲਾਭਦਾਇਕ ਹੋ ਸਕਦੀਆਂ ਹਨ