What is a snowflake algorithm? First, let me ask a question, how to generate a uniqueness ID in a distributed system and keep that ID roughly self-increasing? This is the most important business scenario on Twitter, so Twitter has introduced a snowflake algorithm.
Foreword: Recently need to do a set of CMS system, because the function is relatively single, and requirements flexible, so give up the mature system such as WP, do a relatively simple set of their own. Article details page URL want to make the URL pseudo-static format is xxx.html which XXX considered directly with the self-increment primary key, but feel a little exposure to the article number, some students say the initial value can be set higher, but still can be the ID difference to calculate the number of articles over a period of time, So you need an algorithm that can generate a unique ID.
The methods that have been considered are
A series of methods that directly use timestamps or derive from it.
MySQL comes with a UUID
Both of these methods can be found, not much to explain.
Finally chose Twitter's snowflake algorithm.
The benefits of this algorithm are simple enough to produce approximately 400W different 16-bit digital IDs per second (10 binary)
The principle is simple.
ID is made up of 64bit
One of the first bit vacancies
41bit for storing millisecond timestamps
10bit for storing machine ID
12bit for storing self-increment ID
In addition to the top bit marked as unavailable, the remaining three sets of bit placeholders can be floated to see the specific business requirements. By default, the 41bit timestamp can support the algorithm by 2082, the 10bit working machine ID can support 1023 machines, the serial number supports 1 milliseconds to generate 4,095 self-increment sequence IDs.
Below is the PHP source code
<?phpnamespace App\services;abstract class Particle {const EPOCH = 1479533469598; Const MAX12BIT = 4095; Const MAX41BIT = 1099511627775; static $machineId = null; public static function MachineID ($mId = 0) {self:: $machineId = $mId; public static function Generateparticle () {/* * Time-42 bits * * $time = Floor (Microtime (TRUE) * 1000); /* * Substract custom Epoch from current time */$time-= Self::epoch; /* * Create a base and add time to it */$base = Decbin (self::max41bit + $time); /* * Configured machine id-10 bits-up to 1024x768 machines */if (!self:: $machineId) {$machineid = self:: $ma Chineid; } else {$machineid = Str_pad (Decbin (self:: $machineId), and "0", str_pad_left); }/* * sequence number-12 bits-up to 4096 random numbers per machine */$random = Str_pad (Decbin (Mt_ra nd (0, self::max12bit)), N, "0", str_pad_left); /* Pack */$base = $base. $machineid. $random;/* * Return unique time ID no */return Bindec ($base); public static function Timefromparticle ($particle) {/* * return time */return Bindec (substr (Decbin ($parti CLE), 0,41)-self::max41bit + Self::epoch; }}?>
The calling method is as follows
Particle::generateparticle ($machineId);//Generate Idparticle::timefromparticle ($particle);//Reverse Compute timestamp
I made a improvement here. If the machine ID is 0, the 10bit will be removed because sometimes we may not have so many IDs.
The above is the whole content of this article, I hope that everyone's study has helped.