Home > Article > PHP Framework > Laravel distributed unique ID generator usage
#In applications, a globally unique ID is often required as a database primary key. How to generate a globally unique ID?
First of all, you need to determine whether the globally unique ID is an integer or a string? If it is a string, then the existing UUID fully meets the requirements and no additional work is required. The disadvantage is that strings take up a lot of space as IDs, and the indexing efficiency is lower than integers.
If an integer is used as the ID, first exclude the 32-bit int type because the range is too small and the 64-bit long type must be used.
When using integers as IDs, how to generate self-increasing, globally unique and non-duplicate IDs?
Option 1: Using the database's self-increasing ID, starting from 1, it can basically achieve continuous increment. Oracle can use SEQUENCE
, and MySQL can use AUTO_INCREMENT
for the primary key. Although it cannot guarantee global uniqueness, it is unique for each table and basically meets the needs.
The disadvantage of the database's self-increasing ID is that the ID cannot be obtained before the data is inserted. After the data is inserted, although the ID obtained is unique, the ID will not be considered valid until the transaction is submitted. Some bidirectionally referenced data has to be inserted and then updated, which is troublesome.
The second way is to use a centralized ID generator, which can be Redis or ZooKeeper, or you can use a database table to record the last assigned ID.
The biggest disadvantage of this method is that it is too complex, requires heavy reliance on third-party services, and the code configuration is cumbersome. Generally speaking, the more complex the solution, the less reliable it is and the more painful it is to test.
The third method is similar to Twitter's Snowflake algorithm, which assigns a unique identifier to each machine and then increments the timestamp identifier to achieve a globally unique ID. The advantage of this method is that the ID generation algorithm is completely a stateless machine, has no network calls, and is efficient and reliable. The disadvantage is that if unique identifiers are repeated, ID conflicts will occur.
Snowflake algorithm uses 41bit millisecond timestamp, plus 10bit machine ID, plus 12bit serial number. In theory, it can support up to 1024 machines to generate 4096000 serial numbers per second, which is enough for the scale of Twitter. .
But for most ordinary applications, there is no need for more than 4 million IDs per second, and the number of machines does not reach 1024. Therefore, we can improve it and use shorter ID generation Method:
53bitID consists of 32bit second-level timestamp, 16bit, and 5bit machine identification. It accumulates 32 machines and can generate 65,000 serial numbers per second. Core code:
private static synchronized long nextId(long epochSecond) { if (epochSecond < lastEpoch) { // warning: clock is turn back: logger.warn("clock is back: " + epochSecond + " from previous:" + lastEpoch); epochSecond = lastEpoch; } if (lastEpoch != epochSecond) { lastEpoch = epochSecond; reset(); } offset++; long next = offset & MAX_NEXT; if (next == 0) { logger.warn("maximum id reached in 1 second in epoch: " + epochSecond); return nextId(epochSecond + 1); } return generateId(epochSecond, next, SHARD_ID);}
Timestamp Subtracting a fixed value, this solution can be supported up to 2106.
What if 65,000 serial numbers per second are not enough? It doesn't matter, you can continue to increment the timestamp and "borrow" the 65,000 sequence numbers for the next second.
At the same time, the problem of time dialback is also solved.
The machine identification uses a simple host name scheme. As long as the host name matches host-1
, host-2
can automatically extract the machine identification without configuration.
Finally, why use up to 53-bit integers instead of 64-bit integers? This is because considering that most applications are web applications, if you want to deal with JavaScript, the maximum integer supported by JavaScript is 53 digits. Beyond this number, JavaScript will lose precision. Therefore, a 53-bit integer can be read directly by JavaScript, but when it exceeds 53 bits, it must be converted into a string to ensure correct processing by JavaScript, which will bring additional complexity to the API interface. This is also the reason why Sina Weibo’s API interface returns both id
and idstr
.
Recommended tutorials: "PHP" "Laravel Tutorial"
The above is the detailed content of Laravel distributed unique ID generator usage. For more information, please follow other related articles on the PHP Chinese website!