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
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:
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); } }
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!