Distributed global ID generating program

Traditional single framework, we basically single library and business structure of a single table. Each service ID table we are generally from 1 increases, by AUTO_INCREMENT=1setting the self-energizing start value, but in the design of the distributed services architecture model of sub-library sub-table, so that a plurality of libraries or a plurality of tables stored in the same service data . This situation will produce the same ID based on the case of the self-energizing ID database, we can not guarantee unique primary keys.

Above, if the first line is stored in the order ID DB1 is 1, and when a new order is stored in the storage DB2 is also an order ID. Although our system architecture is distributed, but at the user level it should be no perception of repeat orders obvious primary key is not allowed. So how do the primary key uniqueness it for distributed systems?

UUID

UUID (Universally Unique Identifier), an abbreviation for Universal unique identification code. UUID is constituted by a set of 32-digit hexadecimal numbers, the total number of theoretical UUID 16 ^ 32 ^ 2 = 128, equal to about 3.4 x 10 ^ 38. That is if UUID generate 1 trillion per nanosecond, it takes 10 billion years to run all the UUID.

UUID is generated by the 8-4-4-4-12data format, where 32 characters and four hyphen '-', when we generally use will be deleted hyphens uuid.toString().replaceAll("-","").

Currently there are five generated UUID way versions, different versions of each algorithm, the scope of application is different.

  • Time-based UUID - Version 1 : This is usually through the current time, a random number, and address local Mac calculated, you can org.apache.logging.log4j.core.utilpackage UuidUtil.getTimeBasedUuid()to use tools or other package. The use of a MAC address, it is possible to ensure uniqueness, but also exposed the MAC address, privacy is not good enough.

  • DCE security UUID - Version 2 DCE (Distributed Computing Environment) UUID and UUID security algorithm based on the same time, but the time stamp will change the position of the front 4 POSIX UID or GID. This version of the UUID less frequently used in practice.

  • Name-based UUID (MD5) - version 3 name-based UUID worth to name and name space by calculating the MD5 hash. This version of the UUID ensures: uniqueness of the same name space generated UUID of different names; the uniqueness of different namespace UUID of; the same namespace the same name repeatedly generating the same UUID.

  • Random UUID - version 4 UUID generated according to a random number or pseudo-random number. The probability of this UUID generated duplicate can be calculated, but the potential for duplication is negligible, so this version is also frequently used version. JDK is used in this version.

  • Name-based UUID (SHA1) - version 5 and UUID algorithm name is similar, but the hash value is calculated using the SHA1 (Secure Hash Algorithm 1) algorithm.

We in Java JDK that comes with version 4 UUID way to generate a random number generated UUID and version of name-based UUID 3, are interested can go to look at its source code.

public static void main(String[] args) {

    //获取一个版本4根据随机字节数组的UUID。
    UUID uuid = UUID.randomUUID();
    System.out.println(uuid.toString().replaceAll("-",""));

    //获取一个版本3(基于名称)根据指定的字节数组的UUID。
    byte[] nbyte = {10, 20, 30};
    UUID uuidFromBytes = UUID.nameUUIDFromBytes(nbyte);
    System.out.println(uuidFromBytes.toString().replaceAll("-",""));
}
复制代码

UUID the results obtained,

59f51e7ea5ca453bbfaf2c1579f09f1d
7f49b84d0bbc38e9a493718013baace6
复制代码

Although convenient UUID generated, consumed locally generated no network, but there are some drawbacks to use,

  • Easy to store: UUID long, 128-bit bytes 16, 36 generally indicates the length of the string, a lot of scenes is not applicable.
  • Unsafe information: MAC address generation algorithm UUID-based MAC address may result in leakage, exposure to the user's location.
  • MySQL index for the negative: if, as a database primary key in InnoDB engine, UUID disorder may cause frequent changes in location data seriously affect performance, you can access the knowledge Mysql B + Tree indexing works.

Database generation

Is not necessarily to be based on external conditions to meet the needs of distributed unique ID of it, we can get the ID we need based on our distributed databases on?

Since starting from the value of the distributed database as it will have a conflict happens, then increment the same service ID table we distributed database system is designed to be not the same start value, and then set a fixed step length, the step value is the number of sub-library or sub-table number.

In MySQL example, using a field setting auto_increment_incrementand auto_increment_offsetto ensure the self-energizing ID.

  • auto_increment_offset: represents an increase from the number of fields from the beginning, his range 1 .. 65535.
  • auto_increment_increment: indicates growth since each increment of the amount field, the default value is 1, the range is 1 .. 65535.

Suppose there are three machines, the ID of the starting order table DB1 is 1, the starting value in order DB2 table is 2, the start value in order DB3 Table 3, since they are growing step 3, the scope ID generation thereof is shown below:

By obvious advantage of this approach it is dependent on the database itself does not require additional resources, and the ID number monotonous increment, can achieve some special requirements for ID business.

But the disadvantage is also obvious, first of all it strongly dependent DB, DB abnormality when the entire system unusable. Although it can increase the availability of possible configurations copied from the master, but the data is difficult to ensure consistency in exceptional circumstances. When switching from the main inconsistency may result in duplicate Fa. There is a performance bottleneck ID numbers issued in a single read and write performance of MySQL.

Use redis achieve

Redis implementation of distributed primarily by providing a unique ID like INCR and INCRBY increment atomic command such, due to the characteristics of single-threaded so Redis itself can guarantee generated ID must be the only orderly.

But there is a stand-alone performance bottlenecks, unable to meet the business needs of high concurrency, so the way the cluster can be used to achieve. Cluster embodiment will relate to the same problem and the database cluster, and it is also set segmentation step is achieved.

In order to avoid long-term self-energizing after the number is too large can be used by combining with the current timestamp, the other issues in order to ensure concurrency and business multithreaded Redis + Lua methods can be used to encode, to ensure safety.

Redis implementing distributed globally unique ID, which is a relatively high performance, the generated data is ordered, it is advantageous for sorting operations, but it is equally dependent on redis, the introduction of the system needs to redis assembly, adds complexity to the system configuration.

Of course, now of use Redis is very common, so if other businesses have introduced Redis cluster, you can consider using Redis resource utilization to achieve.

Snow algorithm -Snowflake

Snowflake, Snow algorithm is revenue distributed by Twitter ID generation algorithm, so as to divide the namespace 64-bit bit divided into a plurality of portions, each portion represents a different meaning. The 64bit integer in Java is Long type, so in Java SnowFlake algorithm generated ID is long to store.

  • 1 occupies bit 1bit, whose value is always 0, can be seen as a sign bit is not used.
  • No. 2 starting timestamp 41, 41-bit 41-bit number can represent 2 ^, each represents the number of milliseconds, then the snow life time is available algorithms (1L << 41) / (1000L 3600 24 * 365 ) = 69 years.
  • The 10-bit intermediate bits may represent a number of machines, i.e., 2 ^ 10 = 1024 machine, but in general we do not deploy such a machine. If we have a need for IDC (Internet Data Center), 10-bit can also be divided 5-bit to IDC, points 5-bit machine to work. This can represent 32 IDC, the machine 32 can each IDC, the specific division can be defined according to their needs.
  • The last 12-bit bit sequence is incremented, it may represent a number of 2 ^ 12 = 4096.

After this division is equivalent to 4096 may generate an ordered does not overlap a machine ID in a data center of a millisecond. But we IDC and certainly more than a number of machines, so ordered a few milliseconds can be generated ID is doubled.

Snowflake's Twitter official original is written in Scala, Scala language and some students of the study can go on to the next, following is the Java version of the wording.

package com.jajian.demo.distribute;

/**
 * Twitter_Snowflake<br>
 * SnowFlake的结构如下(每部分用-分开):<br>
 * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
 * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
 * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
 * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
 * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
 * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
 * 加起来刚好64位,为一个Long型。<br>
 * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
 */
public class SnowflakeDistributeId {


    // ==============================Fields===========================================
    /**
     * 开始时间截 (2015-01-01)
     */
    private final long twepoch = 1420041600000L;

    /**
     * 机器id所占的位数
     */
    private final long workerIdBits = 5L;

    /**
     * 数据标识id所占的位数
     */
    private final long datacenterIdBits = 5L;

    /**
     * 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
     */
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);

    /**
     * 支持的最大数据标识id,结果是31
     */
    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

    /**
     * 序列在id中占的位数
     */
    private final long sequenceBits = 12L;

    /**
     * 机器ID向左移12位
     */
    private final long workerIdShift = sequenceBits;

    /**
     * 数据标识id向左移17位(12+5)
     */
    private final long datacenterIdShift = sequenceBits + workerIdBits;

    /**
     * 时间截向左移22位(5+5+12)
     */
    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

    /**
     * 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095)
     */
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);

    /**
     * 工作机器ID(0~31)
     */
    private long workerId;

    /**
     * 数据中心ID(0~31)
     */
    private long datacenterId;

    /**
     * 毫秒内序列(0~4095)
     */
    private long sequence = 0L;

    /**
     * 上次生成ID的时间截
     */
    private long lastTimestamp = -1L;

    //==============================Constructors=====================================

    /**
     * 构造函数
     *
     * @param workerId     工作ID (0~31)
     * @param datacenterId 数据中心ID (0~31)
     */
    public SnowflakeDistributeId(long workerId, long datacenterId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        if (datacenterId > maxDatacenterId || datacenterId < 0) {
            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
        }
        this.workerId = workerId;
        this.datacenterId = datacenterId;
    }

    // ==============================Methods==========================================

    /**
     * 获得下一个ID (该方法是线程安全的)
     *
     * @return SnowflakeId
     */
    public synchronized long nextId() {
        long timestamp = timeGen();

        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
        if (timestamp < lastTimestamp) {
            throw new RuntimeException(
                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
        }

        //如果是同一时间生成的,则进行毫秒内序列
        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            //毫秒内序列溢出
            if (sequence == 0) {
                //阻塞到下一个毫秒,获得新的时间戳
                timestamp = tilNextMillis(lastTimestamp);
            }
        }
        //时间戳改变,毫秒内序列重置
        else {
            sequence = 0L;
        }

        //上次生成ID的时间截
        lastTimestamp = timestamp;

        //移位并通过或运算拼到一起组成64位的ID
        return ((timestamp - twepoch) << timestampLeftShift) //
                | (datacenterId << datacenterIdShift) //
                | (workerId << workerIdShift) //
                | sequence;
    }

    /**
     * 阻塞到下一个毫秒,直到获得新的时间戳
     *
     * @param lastTimestamp 上次生成ID的时间截
     * @return 当前时间戳
     */
    protected long tilNextMillis(long lastTimestamp) {
        long timestamp = timeGen();
        while (timestamp <= lastTimestamp) {
            timestamp = timeGen();
        }
        return timestamp;
    }

    /**
     * 返回以毫秒为单位的当前时间
     *
     * @return 当前时间(毫秒)
     */
    protected long timeGen() {
        return System.currentTimeMillis();
    }
}
复制代码

Test code as follows

public static void main(String[] args) {
    SnowflakeDistributeId idWorker = new SnowflakeDistributeId(0, 0);
    for (int i = 0; i < 1000; i++) {
        long id = idWorker.nextId();
//      System.out.println(Long.toBinaryString(id));
        System.out.println(id);
    }
}
复制代码

Snow algorithm provides a good design ideas, snowflake algorithm generated ID is incremented trend, does not rely on third-party database systems, as a service deployment, greater stability, performance generated ID is very high, and can bit allocation bit according to their business characteristics, very flexible.

However, the algorithm strongly relies snow machine clock, the clock on the machine if the callback will result Fa is repeated or services are unavailable. If it happens before the rollback generate some ID, and time back to back, the generated ID is likely to be repeated. For this official did not give a solution, but simply throwing error handling, this will result in the period of time before being recovered service is unavailable.

Many other types of snow on this algorithm is then designed to improve intellectual defects circumvent it, Baidu UidGenerator US group ID described later in a distributed generation system in Leaf snowflake pattern is out on the basis of the evolution of the snowflake.

Baidu -UidGenerator

Baidu's UidGenerator is a unique ID generator Baidu open-source Java-based implementation, is to do some improvements on the basis of the algorithm snowflake snowflakes on. UidGenerator the form of components work in your application, support for custom workerId digits and initialization strategies, examples of suitable automatic restart at docker and other virtual environments, drift scene.

On realization, UidGenerator provides two ways to generate a unique ID, respectively DefaultUidGenerator and CachedUidGenerator, the official suggested that if there are performance considerations, then use CachedUidGenerator ways.

UidGenerator is still divided namespace way 64-bit bit-splitting into multiple parts, but it's way different from the default partitioning algorithm snowflake snowflake. It is divided by the 1-28-22-13 default format. According to the situation and characteristics of your business, make their own adjustments digits each field occupies.

  • No. 1 is still occupied by 1bit, its value is always 0.
  • No. 2 starting timestamp 28, 28-bit 2 ^ 28 bits may represent the number, there is no longer in milliseconds but in seconds , represents the number per second is available (1L << 28) / (3600 24- 365) ≈ 8.51 years.
  • WorkId intermediate (+ data center working machine, other components may be manner) by the 22-bit bits can represent 2 ^ 22 = 4,194,304 work ID.
  • Finally, the self-energizing constituting 13-bit sequence consisting of bits, may represent a number of 2 ^ 13 = 8192.

Which workId (machine id), can support up to 420w times about the machine starts. Built to achieve when starting a database assignment (table named WORKER_NODE), the default assignment policy is disposable, can provide subsequent reuse strategies.

DROP TABLE IF EXISTS WORKER_NODE;
CREATE TABLE WORKER_NODE
(
ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id',
HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name',
PORT VARCHAR(64) NOT NULL COMMENT 'port',
TYPE INT NOT NULL COMMENT 'node type: ACTUAL or CONTAINER',
LAUNCH_DATE DATE NOT NULL COMMENT 'launch date',
MODIFIED TIMESTAMP NOT NULL COMMENT 'modified time',
CREATED TIMESTAMP NOT NULL COMMENT 'created time',
PRIMARY KEY(ID)
)
 COMMENT='DB WorkerID Assigner for UID Generator',ENGINE = INNODB;
复制代码

DefaultUidGenerator achieve

DefaultUidGenerator is generated according to the normal mode as well as a time stamp and serial number of the machine level, and the algorithm is very similar to snow, only the clock callback throw exception handling. Just something different, such as a unit in seconds rather than milliseconds and support Docker and other virtual environments.

protected synchronized long nextId() {
    long currentSecond = getCurrentSecond();

    // Clock moved backwards, refuse to generate uid
    if (currentSecond < lastSecond) {
        long refusedSeconds = lastSecond - currentSecond;
        throw new UidGenerateException("Clock moved backwards. Refusing for %d seconds", refusedSeconds);
    }

    // At the same second, increase sequence
    if (currentSecond == lastSecond) {
        sequence = (sequence + 1) & bitsAllocator.getMaxSequence();
        // Exceed the max sequence, we wait the next second to generate uid
        if (sequence == 0) {
            currentSecond = getNextSecond(lastSecond);
        }

    // At the different second, sequence restart from zero
    } else {
        sequence = 0L;
    }

    lastSecond = currentSecond;

    // Allocate bits for UID
    return bitsAllocator.allocate(currentSecond - epochSeconds, workerId, sequence);
}
复制代码

If you want to use implementation DefaultUidGenerator of it, more than the number of bits can be divided occupancy parameters by spring.

<bean id="defaultUidGenerator" class="com.baidu.fsg.uid.impl.DefaultUidGenerator" lazy-init="false">
    <property name="workerIdAssigner" ref="disposableWorkerIdAssigner"/>

    <!-- Specified bits & epoch as your demand. No specified the default value will be used -->
    <property name="timeBits" value="29"/>
    <property name="workerBits" value="21"/>
    <property name="seqBits" value="13"/>
    <property name="epochStr" value="2016-09-20"/>
</bean>
复制代码

CachedUidGenerator achieve

The official suggested higher performance CachedUidGenerator generation method is to use id RingBuffer cache generated. Each element of the array into a slot. RingBuffer capacity, the default is the maximum value of Snowflake algorithm sequence (2 ^ 13 = 8192). Expansion can be carried out by boostPower configured to increase read and write throughput RingBuffer.

Tail Pointer, Cursor slot pointer for reading and writing on the annular array:

  • Tail pointer indicates the maximum number Producer production (this number starts from 0, continued to increase). Tail not exceed Cursor, namely producers can not cover the unconsumed slot. When Tail has caught curosr, this time can be specified by rejectedPutBufferHandler PutRejectPolicy

  • Cursor pointer indicates Consumer consumption to a minimum number (the sequence number Producer sequence identity). Cursor can not exceed Tail, that is, not consumption not production slot. When Cursor has caught tail, this time can be specified by rejectedTakeBufferHandler TakeRejectPolicy

CachedUidGenerator a dual RingBuffer, Uid-RingBuffer for storing Uid, Flag-RingBuffer Uid for storing status (whether filled, whether consumption).

Since the array elements in memory are allocated contiguously, maximize the use of available CPU cache to improve performance. But it will also bring FalseSharing problem "false sharing", used for this purpose CacheLine filled way Tail, Cursor pointer, Flag-RingBuffer in.

RingBuffer filled with opportunity

  • When the pre-filled RingBuffer initialization initialization, pre-filling up the entire RingBuffer.

  • Take immediate consumption when filled, the amount of instant check remaining available slot (tail - cursor), such as less than a set threshold, the complement idle slots. Threshold may be configured by paddingFactor, refer to the Quick Start CachedUidGenerator configuration.

  • Schedule threads by filling cycle, the timing of completion idle slots. By scheduleInterval configured to apply the regular fill function and specify a time interval Schedule.

US Mission Leaf

Leaf is a beautiful group of basic research and development platform to launch a distributed generation ID service, the name taken from the German philosopher and mathematician Leibniz's famous phrase of: "There are no two identical leaves in the world", the world can not presence of the same two leaves.

Leaf also offers two ways to generate the ID, respectively Leaf-segment programs and databases Leaf-snowflake scheme.

Leaf-segment database program

Leaf-segment database scheme is described above in the use of the database program, the following changes made:

  • The original proposal had read once each time to get the ID database, create database pressure. Using a proxy server to obtain a batch, each segment acquires a value (STEP determines the size) of the segment number. After the database runs out to go get a new paragraph, can greatly reduce the pressure on the database.

  • Different respective business needs by Fa biz_tagfield to distinguish each of biz-tag ID acquisition isolated from each other, independently of each other. If later there is a database performance requirements for expansion need, the above description does not require complicated operation expansion, only sub-table for the sub-library biz_tag line.

Database table design is as follows:

CREATE TABLE `leaf_alloc` (
  `biz_tag` varchar(128)  NOT NULL DEFAULT '' COMMENT '业务key',
  `max_id` bigint(20) NOT NULL DEFAULT '1' COMMENT '当前已经分配了的最大id',
  `step` int(11) NOT NULL COMMENT '初始步长,也是动态调整的最小步长',
  `description` varchar(256)  DEFAULT NULL COMMENT '业务key的描述',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`biz_tag`)
) ENGINE=InnoDB;
复制代码

The original always need to write to get the ID database, now just need to step set large enough, such as 1000. Then only when the 1000 numbers will be consumed over time to re-write database. Frequency read from a database is reduced to 1 / step, substantially architecture as shown below:

Meanwhile Leaf-segment in order to solve TP999 (meet the minimum time-consuming network requests nine hundred ninety-nine thousandths of needed) large fluctuations in the data, when the number of segments used up or will hang on to update the database I / O, TP999 data will issue occasional spikes, it provides a dual buffer optimization.

Simply put, Leaf opportunity to take a number of segments is carried out in the period when the number of consumed, issued a critical point of time under the ID will mean that segment depends on a number retrieval time period number from DB, and this will come in during the request because the DB does not take back the number segment, resulting in thread blocking. If the request network stability DB and DB, its impact on the system is small, but if taking time jitter occurs to the network DB or DB query will lead to the occurrence of the slow response time of the system becomes slow.

DB process to take a number of segments can do non-blocking, does not need time to take a number of segments DB block the request thread, it is loaded into memory asynchronously to the next segment No. No. That is when the consumer segment to a point, and You do not need to wait until the number of segments used up before going to update the number of segments. Doing so can reduce system TP999 index largely. Detailed implementation shown below:

Dual buffer manner, Leaf internal service with the number two segments buffer segment. When number segment has issued the current 10%, if the next segment number is not updated, then start a separate thread to update a number of segments update next. The current segment number issued after all, if the next segment number is ready to switch to the next segment for the current segment number issued Subsequently, ad infinitum.

  • Each biz-tag has a consumption rate monitoring is generally recommended segment length is set to service the peak of 600 times the number issued QPS (10 minutes), so even if the DB is down, Leaf numbers are not affected can still continue making 10-20 minutes .

  • Analyzing each request will be a temporary state in which a number of segments, to update this paragraph, so occasionally a network jitter will not affect the next update number segment.

For this scheme are still some problems, it is still dependent on the stability of DB, DB primary need to improve the availability of the backup slave mode, and Leaf-segment program ID is generated by increasing trend, this ID number may be calculated is , for example, order ID generated scene, the order id number can roughly calculate the subtraction company orders a day, this can not be tolerated.

Leaf-snowflake scheme

Leaf-snowflake design scheme completely follows snowflake bit bit scheme, to the dispensing workerID introduces Zookeeper lasting order of nodes characteristic of snowflake automatic configuration wokerID node. When the service to avoid large-scale, hands-on configuration too costly problem.

Leaf-snowflake is started in accordance with the following steps:

  • Start Leaf-snowflake service that connects Zookeeper, check whether they have been registered (if there is the order of the child nodes) at leaf_forever parent.
  • If you have registered directly get their workerID (zk node generates a sequence of type int ID number), start the service.
  • If not registered, create a lasting order of the nodes in the parent node below to create a successful retrieval sequence number as their workerID number, start the service.

In order to reduce the dependence on Zookeeper, workerID a cached file on the local file system. When ZooKeeper problems, problems just need to restart the machine, to ensure the service to start properly.

Had problems set forth above, there are clocks in the callback class method snowflake, Leaf-snowflake callback problem solving the clock by checking the system itself is time leaf_forever/${self}to do comparative measures and node records the time to start the alarm.

US Mission official recommendation is due to the strong dependence clock, more sensitive to the requirements of time, when the machine work NTP synchronization can also cause second-level rollback, we recommend that you can turn off direct NTP synchronization. Either directly when the clock does not provide services directly callback return ERROR_CODE, such as a clock to catch up. Or make one retry, and then reported to the alarm system, it is found to have a clock or automatic callback and, after removal of the alarm node itself.

Performance data on the current performance of official Leaf on the machine can be pressed QPS 4C8G the measured near 5w / s, TP999 1ms.

to sum up

All of the above basic list of common distributed ID generation mode, then we can actually broadly classified into two categories:

One is the type of class DB to achieve incremental trend according to set different starting values ​​and steps need to be considered fault tolerance and availability of services.

Another type is the class snowflake, which is to be divided into 64 different sections, each section representing a different meaning, is substantially timestamp, sequence number and machine ID. This approach is the need to consider the issue of call back the clock and do some of the buffer of a buffer designed to improve performance.

But also by the three (timestamp, machine ID, the sequence number) into a different number of bits and the number of concurrent changes life.

For example, the number of concurrent less demanding, long-term use of the desired application, can increase the median time stamp, a sequence number, for example, reducing the number of bits arranged. { "WorkerBits": 23, "timeBits": 31, "seqBits": 9} when can support 28 nodes to the overall concurrency 14400 UID / s speed continuous operation for 68 years.

For frequencies node restart frequently desirable to use long-term use, may increase the number of bits and time stamp bits working machine, for example, reducing the number of sequences digits arranged { "workerBits":. 27, "timeBits": 30, "seqBits": 6 }, the node 37 can support the entire amount of concurrent 2400 UID / s speed continuous operation for 34 years.

reference:

  1. blog.csdn.net
  2. github.com/baidu/uid-g…
  3. tech.meituan.com
  4. mp.weixin.qq.com

Personal Public Number: JaJian

Welcome to long press drawing public attention number: JaJian!

Explanation and analysis of distributed regularly offer micro-tier Internet companies and other service-related technology for you.

Guess you like

Origin juejin.im/post/5d22972f6fb9a07edd2a34cc