Redis生成全局唯一ID的实现方法

目录
  • 简介:
  • 特性:
  • 生成规则:
  • ID生成类:
  • 测试类:

简介:

全局唯一ID生成器是一种在分布式系统下用来生成全局唯一ID的工具

特性:

  • 唯一性
  • 高性能
  • 安全性
  • 高可用
  • 递增性

生成规则:

有时为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其他信息

ID组成部分:

  • 符号位:1bit,永远为0
  • 时间戳:31bit,以秒为单位,可以使用69年
  • 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID

ID生成类:

package com.example.util;

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;

/**
 * @Author DaBai
 * @Date 2022/3/17 下午 09:25
 * @Version 1.0
 */

@Component
public class RedisIDWorker {
    private static final long BEGIN_TIMESTAMP = 1640995200L;

    /**
     * 序列号位数
     */
    private static final int COUNT_BITS = 32;

    private StringRedisTemplate stringRedisTemplate;

    public RedisIDWorker(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    public long nextID(String keyPrefix) {
        //1、生成时间戳
        LocalDateTime now = LocalDateTime.now();
        long nowScond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowScond - BEGIN_TIMESTAMP;
        //2、生成序列号
        // 2.1 获取当前日期,精确到天
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        long count = stringRedisTemplate.opsForValue().increment("icr" + keyPrefix + ":" + date);

        //3、拼接字符串
        // 时间戳左移32位,然后 或 序列号,有1为1
        long ids = timestamp << COUNT_BITS | count;
        return ids;
    }

测试类:

@Resource
    RedisIDWorker redisIDWorker;

    private ExecutorService es = Executors.newFixedThreadPool(500);

    @Test
    public void ShowID() throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(300);
        Runnable task = () -> {
            for (int i = 0; i < 100; i++) {
                long id = redisIDWorker.nextID("order");
                System.out.println("id = " + id);
            }
            countDownLatch.countDown();
        };
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 300; i++) {
            es.submit(task);
        }
        countDownLatch.await();
        long end = System.currentTimeMillis();
        System.out.println("time = " + (end - startTime));
    }

到此这篇关于Redis生成全局唯一ID的实现方法的文章就介绍到这了,更多相关Redis生成全局唯一ID内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis生成分布式系统全局唯一ID的实现

    目录 分布式系统全局唯一ID 基于Redis INCR 命令生成分布式全局唯一ID 采用Redis生成商品全局唯一ID 分布式系统全局唯一ID 在互联网系统中,并发越大的系统,数据就越大,数据越大就越需要分布式,而大量的分布式数据就越需要唯一标识来识别它们. 例如淘宝的商品系统有千亿级别商品,订单系统有万亿级别的订单数据,这些数据都是日渐增长,传统的单库单表是无法支撑这种级别的数据,必须对其进行分库分表:一旦分库分表,表的自增ID就失去了意义:故需要一个全局唯一的ID来标识每一条数据(商品.订单

  • Redis生成全局唯一ID的实现方法

    目录 简介: 特性: 生成规则: ID生成类: 测试类: 简介: 全局唯一ID生成器是一种在分布式系统下用来生成全局唯一ID的工具 特性: 唯一性 高性能 安全性 高可用 递增性 生成规则: 有时为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其他信息 ID组成部分: 符号位:1bit,永远为0 时间戳:31bit,以秒为单位,可以使用69年 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID ID生成类: package com.example.util

  • 基于Java代码实现游戏服务器生成全局唯一ID的方法汇总

    在服务器系统开发时,为了适应数据大并发的请求,我们往往需要对数据进行异步存储,特别是在做分布式系统时,这个时候就不能等待插入数据库返回了取自动id了,而是需要在插入数据库之前生成一个全局的唯一id,使用全局的唯一id,在游戏服务器中,全局唯一的id可以用于将来合服方便,不会出现键冲突.也可以将来在业务增长的情况下,实现分库分表,比如某一个用户的物品要放在同一个分片内,而这个分片段可能是根据用户id的范围值来确定的,比如用户id大于1000小于100000的用户在一个分片内.目前常用的有以下几种:

  • springboot集成redis并使用redis生成全局唯一索引ID

    部署redis Windows下搭建Reids本地集群,可参考https://www.jb51.net/article/242520.htm springboot集成 redis pom文件 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency&

  • 一种简单的ID生成策略: Mysql表生成全局唯一ID的实现

    生成全局ID的方法很多, 这里记录下一种简单的方案: 利用mysql的自增id生成全局唯一ID. 1. 创建一张只需要两个字段的表: CREATE TABLE `guid` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `stub` char(1) NOT NULL DEFAULT '' COMMENT '桩字段,占坑的', PRIMARY KEY (`id`), UNIQUE KEY `uk_stub` (`stub`) -- 将 st

  • Java几种分布式全局唯一ID生成方案

    目录 缘起 常见方案 UUID 数据库自增键 TDDL Sequence Leaf-segment 类雪花算法 时间回拨问题 Leaf-snowflake Seata UUID 总结 缘起 在分布式微服务系统架构下,有非常多的情况我们需要生成一个全局唯一的 ID 来做标识,比如: 需要分库分表的情况下,分库或分表会导致表本事的自增键不具备唯一性. 较长的业务链路涉及到多个微服务之间的调用,需要一个唯一 ID 来标识比如订单 ID.消息 ID.优惠券 ID.分布式事务全局事务 ID. 对于全局唯一

  • PHP实现Snowflake生成分布式唯一ID的方法示例

    前言 Twitter 的 snowflake 在分布式生成唯一 UUID 应用还是蛮广泛的,基于 snowflake 的一些变种的算法网上也有不少.使用 snowflake 生成 UUID 很多都是在分布式场景下使用,我看了下网上有其中有几篇 PHP 实现的都没有考虑到线程安全.现在 PHP 有了 Swoole 的锁和协程的加持,对于我们开发线程安全和高并发模拟还是很方便的,这里用 PHP 结合 Swoole 来学习下实现最简单的 snowflake. 先来看以下 snowflake 的结构:

  • 详解Spring Boot工程集成全局唯一ID生成器 UidGenerator的操作步骤

    Spring Boot中全局唯一流水号ID生成器集成实验 概述 流水号生成器(全局唯一 ID生成器)是服务化系统的基础设施,其在保障系统的正确运行和高可用方面发挥着重要作用.而关于流水号生成算法首屈一指的当属 Snowflake 雪花算法,然而 Snowflake本身很难在现实项目中直接使用,因此实际应用时需要一种可落地的方案. UidGenerator 由百度开发,是Java实现的, 基于 Snowflake算法的唯一ID生成器.UidGenerator以组件形式工作在应用项目中, 支持自定义

  • springboot整合dubbo设置全局唯一ID进行日志追踪的示例代码

    1.新建项目 利用idea创建一个父项目,三个子项目,其中一个项目为生产者,一个项目为消费者,一个为接口等公共服务项目,生产者和消费者需要有web依赖,可以作为tomcat容器启动. 2.项目依赖 <dependencies> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <v

  • Javascript生成全局唯一标识符(GUID,UUID)的方法

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度为128位的数字标识符.GUID 的格式为"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",其中的 x 是 0-9 或 a-f 范围内的一个32位十六进制数.在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUID. GUID 的总数达到了2^128(3

随机推荐