Home > Database > Redis > body text

How to implement the Redis global ID generator

PHPz
Release: 2023-05-27 12:02:49
forward
1462 people have browsed it

The global ID generator is a tool used to generate globally unique IDs in distributed systems. It generally meets the following characteristics:

  • Uniqueness: Ensure that the ID is unique , non-repeatable

  • Incremental: Ensure that the whole is gradually increasing, which is conducive to database creation index

  • Security: the law of ID The sex is not particularly obvious, preventing guessing other IDs based on the ID number, ensuring security

  • High performance: ensuring that the speed of generating IDs is fast enough

  • High availability: Ensure that it can be used at any time

Implementation principle:

In order to improve the security of the ID, you can use the Redis auto-increment value with other information The ID is formed by splicing. The specific composition method is as shown in the figure:

How to implement the Redis global ID generator

  • Sign bit: 1bit, always 0, indicating a positive number

  • Timestamp: 31 bit, in seconds, can be used for about 69 years

  • Serial number: 32 bit, in the case of the same number of seconds, ID Increase the serial number position to support the generation of 2^32 different IDs per second

Code implementation:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
 
@Component
public class RedisIdWorker {
 
    /**
     * 开始时间戳 (2022-01-01 00:00:00)
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;
 
    /**
     * 序列号的位数
     */
    private static final int COUNT_BITS = 32;
 
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
 
    /**
     * 生成ID
     *
     * @param keyPrefix 业务系统的前缀
     * @return ID
     */
    public long nextId(String keyPrefix) {
        // 生成时间戳
        long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) - BEGIN_TIMESTAMP;
        // 生成序列号
        String key = "icr:" + keyPrefix + ":" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        long count = stringRedisTemplate.opsForValue().increment(key);
        // 拼接并返回
        return timestamp << COUNT_BITS | count;
    }
 
    /**
     * 获取时间戳 (2022-01-01 00:00:00)
     * @param args
     */
    public static void main(String[] args) {
        LocalDateTime time = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
        long second = time.toEpochSecond(ZoneOffset.UTC);
        System.out.println(second);
    }
}
Copy after login

Generate serial number:

Redis There is an upper limit to the self-increment, and the maximum value is 2^64. Although this number is large, there is an upper limit after all, and if time goes on long enough, it is still possible to exceed this number. Therefore, even if it is the same business, it cannot use the same key. Therefore, you can add a date to the key, such as: icr: business name: 2022:05:14. The key generated in this way will be a new key every day, and the daily increment will not exceed 2^64, so such a key is a more appropriate choice.

The above is the detailed content of How to implement the Redis global ID generator. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template