സ്നോഫ്ലേക്ക് ഐഡി ജനറേറ്റർ: ഐഡി സൃഷ്ടി & വിശകലനം
വിതരണ സംവിധാനങ്ങളിൽ ഉപയോഗിക്കുന്ന ഏകീകൃത 64-ബിറ്റ് തിരിച്ചറിയലുകൾ ആയ ട്വിറ്റർ സ്നോഫ്ലേക്ക് ഐഡുകൾ സൃഷ്ടിക്കുകയും വിശകലനം ചെയ്യുകയും ചെയ്യുക. ഈ ഉപകരണം പുതിയ സ്നോഫ്ലേക്ക് ഐഡുകൾ സൃഷ്ടിക്കാൻ അനുവദിക്കുന്നു, നിലവിലുള്ളവയെ പാഴ്സുചെയ്യുകയും അവയുടെ ടൈംസ്റ്റാമ്പ്, യന്ത്ര ഐഡി, സീക്വൻസ് നമ്പർ ഘടകങ്ങൾക്കുള്ള洞察ം നൽകുന്നു.
സ്നോഫ്ലേക്ക് ഐഡി ജനറേറ്റർ
സ്നോഫ്ലേക്ക് ഐഡി ജനറേറ്റർ
ഡോക്യുമെന്റേഷൻ
1## Snowflake ID Generator
2
3### Introduction
4
5Snowflake ID ഒരു വ്യത്യസ്തമായ തിരിച്ചറിയലാണ്, ഇത് വിതരണ സംവിധാനങ്ങളിൽ ഉപയോഗിക്കുന്നു, ആദ്യം Twitter-ൽ വികസിപ്പിച്ചെടുത്തത്. ഈ ഉപകരണം നിങ്ങൾക്ക് Snowflake ID-കൾ സൃഷ്ടിച്ച് വിശകലനം ചെയ്യാൻ അനുവദിക്കുന്നു, ഇത് ടൈംസ്റ്റാമ്പ്, മെഷീൻ ID, സീക്വൻസ് നമ്പർ എന്നിവയാൽ നിർമ്മിത 64-ബിറ്റ് ഇന്റേജർ ആണ്.
6
7### How Snowflake IDs Work
8
9Snowflake ID-കൾ 64-ബിറ്റ് ഇന്റേജർ രൂപത്തിൽ ഘടനയിടുന്നു:
10
11- 41 ബിറ്റ്: ടൈംസ്റ്റാമ്പ് (ഒരു കസ്റ്റം എപ്പോക്കിൽ നിന്ന് മില്ലിസെക്കൻഡ്)
12- 10 ബിറ്റ്: മെഷീൻ ID (ഡാറ്റാ സെന്റർ ID-ക്കായി 5 ബിറ്റ്, വർക്കർ ID-ക്കായി 5 ബിറ്റ്)
13- 12 ബിറ്റ്: സീക്വൻസ് നമ്പർ
14
15ഈ ഘടന ഒരു മെഷീനിൽ മില്ലിസെക്കൻഡിൽ ഏകദേശം 4,096 വ്യത്യസ്ത ID-കൾ സൃഷ്ടിക്കാൻ അനുവദിക്കുന്നു.
16
17### Using the Snowflake ID Generator
18
191. (ഐച്ഛികമായി) ഒരു കസ്റ്റം എപ്പോക്ക് സജ്ജമാക്കുക (ഡിഫോൾട്ട് Twitter-ന്റെ എപ്പോക്ക്: 2010-11-04T01:42:54.657Z)
202. ഒരു മെഷീൻ ID (0-31)യും ഡാറ്റാ സെന്റർ ID (0-31)യും നൽകുക
213. പുതിയ Snowflake ID സൃഷ്ടിക്കാൻ "Generate" ക്ലിക്ക് ചെയ്യുക
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 ID-കൾ പ്രത്യേകിച്ച് ഈ മേഖലകളിൽ ഉപകാരപ്രദമാണ്:
21
221. വിതരണ സംവിധാനങ്ങൾ: നിരവധി മെഷീനുകൾക്കിടയിൽ ഏകീകൃത ID-കൾ സൃഷ്ടിക്കുക
232. ഉയർന്ന വോളിയം ഡാറ്റ: വലിയ ഡാറ്റാസെറ്റുകൾക്കായി ക്രമീകരിക്കാവുന്ന ID-കൾ സൃഷ്ടിക്കുക
243. മൈക്രോസർവീസുകൾ: വ്യത്യസ്ത സേവനങ്ങൾക്കിടയിൽ ഏകീകൃത തിരിച്ചറിയലുകൾ ഉറപ്പാക്കുക
254. ഡാറ്റാബേസ് ഷാർഡിംഗ്: കാര്യക്ഷമമായ ഷാർഡിംഗിന് ടൈംസ്റ്റാമ്പ് അല്ലെങ്കിൽ മെഷീൻ ID ഘടകം ഉപയോഗിക്കുക
26
27#### Alternatives
28
29Snowflake ID-കൾ ശക്തമായവയായിരിക്കുമ്പോൾ, മറ്റ് ID ജനറേഷൻ സംവിധാനങ്ങൾ ഉൾപ്പെടുന്നു:
30
311. UUID (Universally Unique Identifier): ക്രമീകരണത്തിന്റെ ആവശ്യം ഇല്ലാതെ വിതരണ സൃഷ്ടനം ആവശ്യമായപ്പോൾ ഉപകാരപ്രദമാണ്
322. ഓട്ടോ-ഇൻക്രീമന്റിംഗ് ഡാറ്റാബേസ് ID-കൾ: ലളിതമായത്, എന്നാൽ ഏകദേശം ഒരു ഡാറ്റാബേസ് ഇൻസ്റ്റൻസുകൾക്ക് പരിമിതമായത്
333. ULID (Universally Unique Lexicographically Sortable Identifier): Snowflake-നോട് സമാനമായ, എന്നാൽ വ്യത്യസ്ത ഘടനയുള്ളത്
34
35### Edge Cases and Limitations
36
371. ക്ലോക്ക് സമന്വയം: Snowflake ID-കൾ സിസ്റ്റം സമയത്തെ ആശ്രയിക്കുന്നു. NTP ക്രമീകരണങ്ങൾക്കോ ദിനപ്രവർത്തന സമയ മാറ്റങ്ങൾക്കോ കാരണം ക്ലോക്ക് പിന്നോട്ടു പോയാൽ, ID ജനറേഷനിൽ പ്രശ്നങ്ങൾ ഉണ്ടാകാം.
38
392. വർഷം 2038 പ്രശ്നം: 41-ബിറ്റ് ടൈംസ്റ്റാമ്പ് 2079-ൽ ഓവർഫ്ലോ ചെയ്യും (Twitter എപ്പോക്കിനെ ആശ്രയിച്ച്). Snowflake ID-കൾ ഉപയോഗിക്കുന്ന സംവിധാനങ്ങൾ ഈ സംഭവവശാൽ പദ്ധതിയിടണം.
40
413. മെഷീൻ ID തർക്കങ്ങൾ: വലിയ വിതരണ സംവിധാനങ്ങളിൽ, ഏകീകൃത മെഷീൻ ID-കൾ ഉറപ്പാക്കുന്നത് വെല്ലുവിളിയാകാം, കൂടാതെ അധിക സമന്വയം ആവശ്യമായേക്കാം.
42
434. സീക്വൻസ് ഓവർഫ്ലോ: അത്യന്തം ഉയർന്ന തീവ്രതയുള്ള സാഹചര്യങ്ങളിൽ, 4096 സീക്വൻസുകൾ മില്ലിസെക്കൻഡിൽ അവസാനിപ്പിക്കാനുള്ള സാധ്യതയുണ്ട്, ഇത് വൈകിപ്പിക്കാൻ കാരണമാകാം.
44
455. മെഷീനുകൾക്കിടയിൽ അന്യോന്യത: ഒരു മെഷീനിൽ ID-കൾ ക്രമീകരണമായി വർദ്ധിക്കുന്നതായിരിക്കുമ്പോൾ, പല മെഷീനുകൾക്കിടയിൽ അവ കൃത്യമായ ക്രമീകരണമായിരിക്കില്ല.
46
47### History
48
49Snowflake ID-കൾ 2010-ൽ Twitter-ൽ അവതരിപ്പിച്ചു, വിതരണ, സമയ ക്രമീകരണമായ ഏകീകൃത തിരിച്ചറിയലുകൾക്കുള്ള ആവശ്യം പരിഹരിക്കാൻ. പിന്നീട്, ഈ ID-കൾ നിരവധി മറ്റ് കമ്പനികൾക്കും പദ്ധതികൾക്കും സ്വീകരിക്കപ്പെട്ടു.
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('Clock moved backwards. Refusing to generate 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()); } }
// Usage
const generator = new SnowflakeGenerator();
const id = generator.nextId(1, 1);
console.log(Generated 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("Clock moved backwards. Refusing to generate 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
Usage
generator = SnowflakeGenerator(datacenter_id=1, worker_id=1) snowflake_id = generator.next_id() print(f"Generated 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("Clock moved backwards. Refusing to generate 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("Generated 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 'Clock moved backwards' 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
Usage
generator = SnowflakeGenerator.new(1, 1) snowflake_id = generator.next_id puts "Generated 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("Clock moved backwards. Refusing to generate 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); } } // Usage $generator = new SnowflakeGenerator(1, 1); $id = $generator->nextId(); echo "Generated 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("Clock moved backwards. Refusing to generate 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)
{
long timestamp = TimeGen();
while (timestamp <= lastTimestamp)
{
timestamp = TimeGen();
}
return timestamp;
}
private long TimeGen()
{
return DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
}
// Usage class Program { static void Main(string[] args) { var generator = new SnowflakeGenerator(1, 1); var id = generator.NextId(); Console.WriteLine($"Generated 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("clock moved backwards, refusing to generate 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("Error creating generator: %v\n", err) return }
id, err := generator.NextId()
if err != nil {
fmt.Printf("Error generating ID: %v\n", err)
return
}
fmt.Printf("Generated Snowflake ID: %d\n", id)
}
1
2### Diagram
3
4Snowflake 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. "Announcing Snowflake." Twitter Engineering Blog, https://blog.twitter.com/engineering/en_us/a/2010/announcing-snowflake
222. "Snowflake ID." Wikipedia, https://en.wikipedia.org/wiki/Snowflake_ID
233. "Distributed ID Generation in Microservices." Medium, https://medium.com/swlh/distributed-id-generation-in-microservices-b6ce9a8dd93f
24
പ്രതികരണം
ഈ ഉപകരണത്തെക്കുറിച്ച് പ്രതികരണം നൽകാൻ പ്രതികരണ ടോസ്റ്റിൽ ക്ലിക്ക് ചെയ്യുക
ബന്ധപ്പെട്ട ഉപകരണങ്ങൾ
നിങ്ങളുടെ പ്രവൃത്തി പ്രവാഹത്തിന് ഉപകാരപ്രദമായ കൂടുതൽ ഉപകരണങ്ങൾ കണ്ടെത്തുക