Redis实战案例10-优惠券1-全局唯一ID

news2024/10/6 10:31:21

1. 全局ID生成器

在这里插入图片描述

id的规律性明显造成某些信息的泄露;
使用自增ID作为主键会导致一些问题。首先,由于自增ID必须是唯一的,因此当达到最大值时,无法再向表中插入新的数据,这限制了表的数据量。例如:订单如果一直自增,id值达到数亿级别时,单表就很难插入了;
其次,由于每次插入新数据都需要更新自增ID的值,当表中存在大量数据时,这个过程会变得越来越耗时;

在这里插入图片描述

  1. 全局唯一性:生成的ID在整个分布式系统中必须是唯一的,避免ID冲突的发生。这是保证数据一致性和避免数据丢失的关键。

  2. 高性能:生成ID的速度应该足够快,以满足高并发的请求。高性能的ID生成器能够处理大量的请求,而不会成为系统的瓶颈。

  3. 递增性:生成的ID应该具备趋势递增的特性,即后续生成的ID值应该大于前面生成的ID值。这可以提高数据库索引的性能,减少IO的次数。

  4. 高可用:ID生成器应该是可靠可用的,即保证在系统故障或网络中断的情况下,依然能够正常生成唯一ID。

  5. 安全性:生成的ID应该是难以被猜测到且具有权限控制机制,还有不包括敏感信息。

系列号就是Redis自增的数值

在这里插入图片描述

在这里插入图片描述

2. Redis实现全局ID

要点:
在对序列号进行自增长时,为防止自增值过大采用拼接时间戳date;
最后得到全局ID,时间戳左移与序列号做或运算得到全局ID,思路值得学习;

@Component
public class RedisIdWorker {

    private StringRedisTemplate stringRedisTemplate;

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

    /**
     * 开始时间戳
     */
    private static final long BEGIN_TIMESTAMP = 1640995200L;

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

    public long nextId(String keyPrefix){
        //1. 生成时间戳
        LocalDateTime now = LocalDateTime.now();
        long nowEpochSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timeStamp = nowEpochSecond - BEGIN_TIMESTAMP;
        //2. 生成序列号
        //2.1 获取当前日期,精确到天
        String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
        //2.2 自增长
        long count = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date);
        //3. 拼接并返回(时间戳左移与序列号做或运算得到全局ID)
        return timeStamp << COUNT_BITS | count;
    }
}

对生成ID策略进行测试;
要点:
lambda表达式的应用;
多线程运用以及线程池的应用,关于计算多线程的运算时间的方法;
new CountDownLatch(300),设置初始计数值为300;
调用await()方法进行等待,直到计数器值为0,才会继续执行后续代码,从而得出运算的时间;
通过使用CountDownLatch来等待所有任务执行完毕,并使用线程池来并发执行任务,评估redisIdWorker的性能;

Runnable task = new Runnable() {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            long id = redisIdWorker.nextId("order");
            System.out.println("id= " + id);
        }
    }
};
@Resource
private RedisIdWorker redisIdWorker;
/**
 * 创建线程池
 */
private ExecutorService ex = Executors.newFixedThreadPool(500);
@Test
void testIdWorker() throws InterruptedException {
    CountDownLatch countDownLatch = new CountDownLatch(300);
    //lambda表达式
    Runnable task = () -> {
        for (int i = 0; i < 100; i++) {
            long id = redisIdWorker.nextId("order");
            System.out.println("id= " + id);
        }
        countDownLatch.countDown();
    };
    
    long begin = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
        ex.submit(task);
    }
    countDownLatch.await();
    long end = System.currentTimeMillis();
    System.out.println("time = " + (end - begin));
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/720836.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基本介绍实施工程师,以及实施工程师在软件开发的作用

一.软件实施介绍 1.什么是软件实施&#xff1f; 软件实施是指将软件开发完成后&#xff0c;按照计划进行部署和安装&#xff0c;使软件能够在目标环境中正常运行的过程。下面是软件实施的一般步骤&#xff1a; 1. 规划和准备&#xff1a;确定实施的范围、目标和计划&#xff0…

如何将PNG格式照片转换为JPG格式

如何将PNG格式照片转换为JPG格式 当您需要在网络上共享或存储图像时&#xff0c;将PNG格式的照片转换为JPG格式是一个常见的需求。本文将介绍一些关于将PNG格式照片转换为JPG格式的相关知识。 问题与解决方案 图像质量损失 在将PNG格式照片转换为JPG格式的过程中&#xff0…

IMX6ULL 移植篇-uboot 网络命令NFS

一. uboot 网络操作命令 本文介绍 nfs 命令的使用&#xff0c;具体是&#xff1a;通过 NFS服务向开发板下载 zImage内核镜像文件。 二. nfs 命令 nfs命令使用的目的&#xff1a;为了方便开发板调试。 nfs(Network File System) 网络文件系统&#xff0c;通过 nfs 可以在计算…

MyBatis实现主键ID、创建时间、更新时间的自动填充

注意事项 一&#xff1a;如果插入时有设置的值就使用之前设置的值&#xff0c;不带时才自动赋值。 二&#xff1a;xml文件中必须带有需要自动赋值的字段&#xff0c;否则无法知道赋值&#xff08;如id、create_time、update_time&#xff09; 代码详解 注解&#xff1a; …

【vue2+echarts】树状图(标签显示不全、节点文本过长换行等问题解决)

前言 树状图的使用。官方文档 正文 关于根节点标签显示不全问题解决 一开始的series->边距设置的如下。所以根节点的标签只显示了一半多出来。 top: "1%",left: "7%",bottom: "1%",right: "20%",后面修改成 top: "1%"…

css基础知识十八:CSS如何画一个三角形?原理是什么?

一、前言 在前端开发的时候&#xff0c;我们有时候会需要用到一个三角形的形状&#xff0c;比如地址选择或者播放器里面播放按钮 通常情况下&#xff0c;我们会使用图片或者svg去完成三角形效果图&#xff0c;但如果单纯使用css如何完成一个三角形呢&#xff1f; 实现过程似乎…

Maven安装与配置以及idea配置Maven

文章目录 一、安装本地Maven 二、安装 三、配置环境变量 四、配置settings文件 五、idea配置 一、安装本地Maven 选择你需要的maven版本下载&#xff1a;官网下载传送门 我使用的是3.6.1版本&#xff1a;maven-3.6.1-bin.zip ​ 二、安装 把下载好的maven压缩包解压到…

小样本目标检测综述__刘浩宇(导航与控制2021)论文阅读

小样本目标检测综述__刘浩宇(导航与控制2021)阅读 0、引言 早期采用了大量标注样本回归候选框的位置&#xff0c;但后来目标集和训练集数据分布不同导致检测效果下降。 对于没有大量样本支持的小样本检测应用就需要使用先验知识来弥补样本的不足。 可以分为三类&#xff1a…

Redis实战——商户查询(二)

缓存穿透 缓存穿透 &#xff1a;客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这样的请求都会访问到数据库&#xff0c;这样的大量请求同时过来访问这种不存在的数据&#xff0c;这些请求就都会访问到数据库&#xff0c;对数据库造…

js:使用diff.js实现文本内容差异比较

实现效果 目录 简介安装示例1、json比较diffJson2、按行比较diffLines3、比较数组diffArrays 总结参考资料 简介 A javascript text differencing implementation. 译文&#xff1a;javascript文本差异实现。 相关文档 github https://github.com/kpdecker/jsdiffnpmjs htt…

YoloV8改进---注意力机制:高斯上下文变换器GCT,性能优于ECA、SE等注意力模块 | CVPR2021

目录 1.GCT介绍 实验结果 2.GCT引入到yolov8 2.1 修改modules.py中&#xff1a; 2.2 加入tasks.py中&#xff1a; 2.3 yolov8_GCT.yaml 3.YOLOv8魔术师专栏介绍 1.GCT介绍 论文&#xff1a;https://openaccess.thecvf.com/content/CVPR2021/papers/Ruan_Gaussian_Context_…

MySQL数据库架构

MySQL数据库架构 MySQL架构自顶向下大致可以分为连接层 , SQL层 , 存储引擎层 , 物理文件层。架构如下 连接层 -- 查看最大连接数 show variables like %max_connections%;客户端连接器&#xff0c;MySQL向外提供交互接口连接各种不同的客户端。 客户端/应用程序&#xff1a;客…

7.3.6 【Linux】磁盘/文件系统参数修订

mknod 用到的磁盘 /dev/vda 的相关设备代码如下&#xff1a; 上表当中 252 为主要设备代码 &#xff08;Major&#xff09; 而 0~5 则为次要设备代码 &#xff08;Minor&#xff09;。 我们的Linux 核心认识的设备数据就是通过这两个数值来决定的&#xff01;举例来说&#xf…

如何批量将PDF转换为图片?

在生活工作中&#xff0c;我们会处理很多电子合同。这些电子合同一般是PDF格式&#xff0c;不但存储空间大&#xff0c;且预览起来不太便捷&#xff0c;需要我们转换为图片格式更方便预览。如果人工一一处理比较繁琐复杂&#xff0c;有没有什么方案可以快速将pdf转换为图片呢&a…

如果想用unity做一个项目作为面试作品,至少该达到什么样的标准?

本文仅针对题目“如果想用unity做一个项目作为面试作品&#xff0c;至少该达到什么样的标准&#xff1f;”回答内容。 明确职业目标 首先要明确自身的职业目标&#xff0c;不同的行业、公司、游戏类型、岗位对作品的要求是不同的。 去什么样的行业&#xff1f;unity可做的有很…

python的IOError使用

try:npzfile np.load(calibrate.npz)mtx npzfile[mtx]dist npzfile[dist]except IOError:calibrate()python语言IOError错误一般多发生在对文件操作报错时&#xff0c;表示要打开的文件不存在

PostpreSQL内核学习-Chapter4 Foreign Data Wrapper(FDW)

FDW连接 preparations 两个在不同主机&#xff08;满足TCP/IP连接是分属于不同IP地址下&#xff09;&#xff08;如果是安装PG源码&#xff09;进入源码目录下面的/contrib/postgres_fdw/&#xff0c;然后用make & make install编译和安装 [rootlocalhost /]# cd 源码存…

为什么truncate函数(四舍五入)是x+0.4999997而不是+0.5?

目录 float的不精确表示 0.5的舍入方法 该方法的漏洞 0.4999997f舍入的结果错误 以0.4999997f改进舍入方法 可以用0.49999996、0.49999998或者0.49999999替换0.49999997吗&#xff1f; 在做舍入函数研究时&#xff0c;发现函数中实现四舍五入的trunc函数大概采用的逻辑是floor(…

LVS负载均衡-----DR模式

目录 1.DR模式原理 2.DR 模式的特点&#xff1a; 3.LVS-DR中的ARP问题 问题原因&#xff1a; 解决方法&#xff1a; 问题二&#xff1a;返回报文时源地址使用VIP&#xff0c;导致网关设备的ARP缓存表紊乱 解决方法&#xff1a; 4.DR模式 LVS负载均衡群集部署 1.配置负…

python进程线程问题

参考链接&#xff1a; 代码可去原博文复制&#xff1a; python缩短大量数据处理时间-进程池pool()和map() 一 定义与解释 1、对于python代码&#xff0c;多线程其实是个假的&#xff0c;因为每次计算的时候&#xff0c;实质上只有一个线程计算。使用多线程时&#xff0c;是几…