A method rollup based on Java code to generate a global unique ID for a game server _java

Source: Internet
Author: User
Tags current time redis throw exception unique id uuid

When the server system is developed, in order to adapt to the request of large data concurrency, we often need to asynchronous storage of data, especially in the distributed system, this time can not wait to insert the database returned to take the automatic ID, but need to insert the database before the creation of a global unique ID, using the global unique ID, In the game server, the globally unique ID can be used for future convenience and no key conflict occurs. can also be in the future in the case of business growth, implementation of the sub-Library, such as a user's items to be placed in the same slice, and this fragment may be based on the user ID range value to determine, such as user ID greater than 1000 less than 100000 users in a slice. At present, the following are commonly used:

1,java with the UUID itself.

Uuid.randomuuid (). ToString () can be generated locally through a service program, and the generation of IDs does not depend on the implementation of the database.

Advantage:

The local build ID does not require a remote call.

Global unique does not repeat.

The ability to scale horizontally is very good.

Disadvantage:

ID has 128 bits, occupies a larger space, needs to be stored as a string type, index efficiency is extremely low.

No timestamp in the generated ID, no guarantee of trend increment, bad dependency on database sub-tables

2, the INCR method based on Redis

The Redis itself is single-threaded, and incr guarantees an atomic incremental operation. It also supports setting the increment step.

Advantage:

Easy to deploy, simple to use, only need to call a Redis API.

Multiple servers can share a Redis service, reducing the development time of shared data.

Redis can cluster deployment to resolve a single point of failure.

Disadvantage:

If the system is too large, n multiple services to the Redis request at the same time, can cause performance bottlenecks.

3, the solution from flicker

This workaround is based on the database ID, which uses a separate database specifically for generating IDs. Detailed everyone can look for the internet, the individual feel very troublesome to use, do not recommend use.

4,twitter Snowflake

Snowflake is the Twitter open source distributed ID generation algorithm, the core idea is: the generation of a long ID, using 41bit as the number of milliseconds, 10bit as the machine number, 12bit as the number of milliseconds. The algorithm can generate a maximum of 1000* (2^12) per second, which is approximately 400W of ID, fully meet the needs of the business.

According to the idea of snowflake algorithm, we can produce our own globally unique IDs according to our own business scenarios. Because the length of the long type in Java is 64bits, the IDs we design need to be controlled at 64bits.

Advantages: High performance, low latency, independent application, orderly in time.

Disadvantage: Need for independent development and deployment.

For example, the ID of our design contains the following information:

| Bits:timestamp | 3 Bits: Area | Ten bits: Machine number | Ten bits: Serial number |

Java code that produces a unique ID:

/** * Custom ID Generator * ID generation rule: id up to bits * * | Bits:timestamp (ms) | 3 bits: Area (engine room) | Ten bits: Machine number |
Ten bits: Serial number |  * * public class gameuuid{//Base time private long Twepoch = 1288834974657L//thu Nov 01:42:54 GMT//area flag number Private
Final static long regionidbits = 3L;
Number of machine ID digits private final static long workeridbits = 10L;
Number identification number private final static long sequencebits = 10L;
Area Flag ID Maximum private final static long Maxregionid = -1l ^ ( -1l << regionidbits);
Machine ID Maximum Private final static long Maxworkerid = -1l ^ ( -1l << workeridbits);
Serial number ID maximum private final static long Sequencemask = -1l ^ ( -1l << sequencebits);
Machine ID shifted left 10-bit private final static long workeridshift = Sequencebits;
Business ID shifted left 20-bit private final static long Regionidshift = Sequencebits + workeridbits;
Time millisecond left 23-bit private final static long Timestampleftshift = sequencebits + workeridbits + regionidbits;
private static long Lasttimestamp = -1l;
Private long sequence = 0L; Private Final LoNg Workerid;
Private final long RegionID; Public Gameuuid (Long Workerid, long RegionID) {//If out of range throw exception if (Workerid > Maxworkerid | | Workerid < 0) {throw n
EW illegalargumentexception ("worker Id can ' t be greater than%d or less than 0"); } if (RegionID > Maxregionid | | RegionID < 0) {throw new IllegalArgumentException ("Datacenter Id can ' t be greater t
Han%d or less than 0 ");
} This.workerid = Workerid;
This.regionid = RegionID; Public Gameuuid (Long Workerid) {//If out of range throws exception if (Workerid > Maxworkerid | | Workerid < 0) {throw new Illegalarg
Umentexception ("Worker Id can ' t be greater than%d or less than 0");
} This.workerid = Workerid;
This.regionid = 0;
public long Generate () {return This.nextid (false, 0);}/** * @param ispadding * @param busid * @return * *
Private Synchronized Long NextID (Boolean ispadding, Long Busid) {Long timestamp = Timegen (); Long paddingnum = RegionID; if (ispadding) {paddingnum = Busid} if (Timestamp < Lasttimestamp{try {throw new Exception ("Clock moved backwards.") Refusing to generate ID for "+ (Lasttimestamp-timestamp) +" milliseconds ");}
catch (Exception e) {e.printstacktrace ();}}
If the last build time is the same as the current time, in the same millisecond if (Lasttimestamp = = timestamp) {//sequence, since sequence is only 10bit, so and sequencemask phase, remove the high
Sequence = (sequence + 1) & Sequencemask; To determine whether the overflow, which is more than 1024 per millisecond, when 1024, and sequencemask phase, sequence equals 0 if (sequence = 0) {//spin wait to the next millisecond timestamp = Tailnextmillis
(Lasttimestamp); } else {//If it is different from the last build time, reset sequence, which is the beginning of the next millisecond, the sequence count begins to accumulate from 0,//To ensure that the mantissa is more random, the last one sets a random number sequence = new Securerando
M (). Nextint (10);
} Lasttimestamp = timestamp; Return ((Timestamp-twepoch) << timestampleftshift) | (paddingnum << Regionidshift) | (Workerid << Workeridshift) |
Sequence
(///prevent the resulting time from being smaller than the previous time (due to problems such as NTP callback) to maintain an incremental trend. Private Long Tailnextmillis (final long Lasttimestamp) {Long timestamp = This.timegen (); while (timestamp <= lasttimest AMP) {timestamp = This.timegen (); Timestamp //Gets the current timestamp protected long Timegen () {return System.currenttimemillis ();}}

A few things to note when using this method of customization:

In order to maintain the trend of growth, to avoid some servers early, some servers late, need to control the time of all servers, and to avoid the NTP time server callback server time; in milliseconds, the serial number is always 0, which makes the ID number 0 more. The resulting ID is not evenly modeled, so the serial number is not normalized to 0 each time, but is a random number from 0 to 9.

These kinds of ways we can choose according to our own needs. In the game server development, according to own game type choice, for example mobile phone game, can use the simple Redis way, simple is not easy to make mistakes, because this kind of game single suit concurrent new ID quantity is not too big, can satisfy the need completely. And for the large World game server, which itself is distributed mainly, so you can use snowflake way, the above snowflake code is just an example, need to customize according to their own needs, so there is additional development volume, but also pay attention to the above mentioned points.

The above is a small set of Java code to introduce the game server to generate a global unique ID method rollup, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.