当前位置: 首页 > news >正文

基于Redis自增实现全局ID生成器(详解)

 本博客为个人学习笔记,学习网站与详细见:黑马程序员Redis入门到实战 P48 - P49 

目录

全局ID生成器介绍

基于Redis自增实现全局ID

实现代码


全局ID生成器介绍

背景介绍
当用户在抢购商品时,就会生成订单并保存到数据库的某一张表中,而订单表如果使用数据库自增ID就会存在一些问题:
1. id的规律性太明显
2. 受单表数据量的限制

基于使用数据库自增ID带来的两个问题,我们来做场景分析:
1. 场景分析一:如果我们的id具有太明显的规则,用户或者说商业对手很容易猜测出来我们的一些敏感信息,比如商城在一天时间内,卖出了多少单,这明显不合适。
2. 场景分析二:MySQL的单表容量不宜超过500万条记录。随着我们商城规模的扩大,数据量增长到一定程度后,我们需要进行数据库拆分和表拆分。拆分后,这些表在逻辑上仍然属于同一张表,因此它们之间的数据ID不能相同。因此,我们必须确保全局ID的唯一性。

全局ID生成器
全局ID生成器,是一种在分布式系统下用来生成全局唯一ID的工具,一般要满足下列特性:
1. 唯一性
2. 高性能
3. 高可用
4. 递增性
5. 安全性


基于Redis自增实现全局ID

全局ID组成结构图:

序列号:由于Redis的自增操作是原子性的,保证了在并发情况下生成ID的唯一性,避免了传统数据库中的锁竞争和性能瓶颈。因此我们可以利用Redis的自增原子性,让序列号由Redis自增的数值组成,因此我们确保了全局ID序列号的唯一性,从而确保了整个全局ID的唯一性。

同时,我们还需要考虑一个问题,我们利用Redis自增实现全局ID,但如果我们只设置一个Key值,随着业务的日积月累,自增值将会达到上限。为避免这种情况发生,我们需要设置不同的Key值,于是我们决定用年月日的格式 yyyy:MM:dd 来添加到Key值的前缀当中,因此一个Key值的自增量不再是用来表示所有时间的业务量,而只是用来表示某年某月某天的业务量,而一天的业务量是不可能超过 2^32 (几十亿) 这么大的数值的,我们从而确保了Key值不会达到上限。

而这种做法也方便了我们对业务数据的统计,当我们想查询一年中的业务量时,我们只需要查询前缀为 yyyy 的Key值自增量即可,如果我们想查询某年某月的业务量时,我们只需要查询前缀为 yyyy:MM 的Key值自增量即可。

时间戳:为了增加全局ID的安全性,我们并能不直接把Redis的自增值(序列号)当作全局ID,而是应该在此基础上拼接一些其它信息,我们可以先设置某一个时间的时间戳作为参照时间戳,如2000年1月1日0时0分0秒,之后每当用户下单,我们可以获取下单时间的时间戳,再与参照时间戳做差,得到的差值用来组成全局ID的时间戳这一部分。(显然,我们全局ID设置的时间戳只有32位,因此我们需要确保差值是在2^32大小内,而2^32秒相当于136年的时间,因此是妥妥够用的,或者我们也可以选择对参照时间差进行调整来确保差值不会超过2^32)


实现代码

全局ID生成器代码如下

@Component
public class RedisIdWorker {private static final long BEGIN_TIMESTAMP = 1640995200L;private static final long COUNT_BITS = 32;@Resourceprivate StringRedisTemplate stringRedisTemplate;public long nextId(String KeyPrefix) {// 1.生成全局ID时间戳部分LocalDateTime now = LocalDateTime.now();long nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - BEGIN_TIMESTAMP;// 2.生成全局ID序列号部分// 2.1获取当前日期,精确到天String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));// 2.2获取自增长值Long count = stringRedisTemplate.opsForValue().increment("icr:" + KeyPrefix + ":" + date);// 3.拼接时间戳和序列号并返回return timestamp << COUNT_BITS | count;}// 用于计算20220101时间戳给BEGIN_TIMESTAMP赋值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 = " + second);}}

相关文章:

基于Redis自增实现全局ID生成器(详解)

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P48 - P49 目录 全局ID生成器介绍 基于Redis自增实现全局ID 实现代码 全局ID生成器介绍 背景介绍 当用户在抢购商品时&#xff0c;就会生成订单并保存到数据库的某一张表中&#…...

hadoop 总结

1.hadoop 配置文件 core-site hdfs-site yarn-site.xml worker hdfs-site.xml <?xml version"1.0" encoding"UTF-8"?> <?xml-stylesheet type"text/xsl" href"configuration.xsl"?> <configuration><pr…...

luatos框架中LVGL如何使用中文字体〈二〉编写脚本设置中文字体

本节内容&#xff0c;将和大家一同学习&#xff0c;在luatos环境中&#xff0c;使用lvgl库&#xff0c;一步步的编译固件、编写脚本&#xff0c;最终实现中文字体的显示。 芯片&#xff1a;AIR101 LCD屏&#xff1a;ST7789 上一节&#xff0c;我们一同学习了&#xff0c;硬件引…...

c++单例模式和call_once函数

单例模式是一种常见的设计模式&#xff0c;用于确保某个类只能创建一个实例。由于单例模式是全局唯一的&#xff0c;因此在多线程中使用单例模式时需要考虑线程安全问题。 1.GetInstance()实例化一个对象 懒汉式&#xff1a;第一次用到类的时候才会去实例化。 懒汉式创建对象…...

AutoMQ 携手阿里云共同发布新一代云原生 Kafka,帮助得物有效压缩 85% Kafka 云支出!

3 月 9 日&#xff0c;“AutoMQ x 阿里云云原生创新论坛”在阿里巴巴西溪园区圆满落幕。本次论坛现场不仅重磅发布了新一代云原生 Kafka 产品&#xff08;AutoMQ On-Prem 版&#xff09;&#xff0c;还邀请了来自得物的稳定生产负责人分享 AutoMQ 在生产场景中的应用实践&…...

力扣977. 有序数组的平方

思路&#xff1a;暴力法&#xff1a;全部平方&#xff0c;然后调用排序API&#xff0c;排序算法最快是N*log(N)时间复制度。 双指针法&#xff1a;要利用好原本的数组本就是有序的数组这个条件&#xff0c; 只是有负数 导致平方后变大了&#xff0c;那么平方后的最大值就是在两…...

VSCode设置

VSCode设置 VSCode设置1.双击和点击显示设置2.快捷键设置 VSCode设置 1.双击和点击显示设置 VSCode设置双击才能打开文件、文件夹 打开文件夹&#xff1a;在设置页中搜索 expandMode,将 singleClick 改为 doubleClick 即可。 双击打开文件&#xff1a;在设置页中搜索workben…...

2.2 评估方法 机器学习

我们若有一个包含m个样例的数据集&#xff0c;若我们既需要训练&#xff0c;也需要测试&#xff0c;我们该如何处理呢&#xff1f;下面是几种方法&#xff1a; 2.2.1 留出法 “留出法”直接将数据集D划分为两个互斥的集合&#xff0c;其中一个作为训练集S&#xff0c;另一个作…...

第一类换元法(凑微分,凑狗)【高数笔记】

1.第一类换元法&#xff0c;解决的是什么类型的问题 2.不同的问题&#xff0c;应该有什么解法 3.13个基本积分公式&#xff0c;应该注意什么...

PostgreSQL数据库优化指南

默认安装下的 PostgreSQL 配置无法完全利用现有硬件&#xff0c;影响Netbox的性能。 本文章讲解了如何简单去优化。 优化 项目地址&#xff1a;https://github.com/le0pard/pgtune 首先打开&#xff1a;https://pgtune.leopard.in.ua/ (此网站会根据你的选择自动生成优化配置…...

VScode Error Lens插件

安装完成之后&#xff0c;当我们输入一些错误的语法格式的时候&#xff0c;它都会有一些提示&#xff01; 一开始是英文提示 修改为中文提示 设置搜索 typescript.local...

Fiddler抓包教程

一、Fiddler安装&#xff1a; Fiddler原理 B/S模式的工作过程&#xff0c;简单的讲述访问一个网站的过程 。 Fiddler的位置&#xff1a; Fiddler是位于浏览器和服务器之间的请求和响应代理&#xff0c;所以它可以截获浏览器和服务器之间的所有HTTP通讯&#xff0c;&#xff0…...

TypeScript编译选项

编译单个文件&#xff1a;终端 tsc 文件名 自动编译单个文件&#xff1a;终端 tsc 文件名 -w 编译整个项目&#xff1a;tsc 前提是得有ts的配置文件tsconfig.json 自动编译整个项目&#xff1a;tsc --w tsconfig.json默认文件内容&#xff1a; tsconfig.json是ts编译器的配…...

个推与华为深度合作,成为首批支持兼容HarmonyOS NEXT的服务商

自华为官方宣布HarmonyOS NEXT鸿蒙星河版开放申请以来&#xff0c;越来越多的头部APP宣布启动鸿蒙原生开发&#xff0c;鸿蒙生态也随之进入全新发展的第二阶段。 作为华为鸿蒙生态的重要合作伙伴&#xff0c;个推一直积极参与鸿蒙生态建设。为帮助用户在HarmonyOS NEXT上持续享…...

TypeScript开发100问?

开发人员在日常工作中常常需要处理各种各样的问题&#xff0c;而 TypeScript 作为 JavaScript 的一个超集&#xff0c;为我们提供了更加强大和可靠的工具来编写高质量的代码。在使用 TypeScript 进行开发时&#xff0c;我们可能会遇到各种各样的技术基础问题、开发过程中的挑战…...

数据结构和算法:栈与队列

栈 栈 &#xff08;stack&#xff09;是一种遵循先入后出逻辑的线性数据结构 把堆叠元素的顶部称为“栈顶”&#xff0c;底部称为“栈底”。 将把元素添加到栈顶的操作叫作“入栈”&#xff0c;删除栈顶元素的操作叫作“出栈”。 栈的常用操作 /* 初始化栈 */ stack<int&g…...

LeetCode(力扣)算法题_1261_在受污染的二叉树中查找元素

今天是2024年3月12日&#xff0c;可能是因为今天是植树节的原因&#xff0c;今天的每日一题是二叉树&#x1f64f;&#x1f3fb; 在受污染的二叉树中查找元素 题目描述 给出一个满足下述规则的二叉树&#xff1a; root.val 0 如果 treeNode.val x 且 treeNode.left ! n…...

Topaz DeNoise AI for Mac/Win:引领图片降噪新纪元,让你的照片焕然一新!

在数字化时代&#xff0c;摄影已成为我们记录生活、表达情感的重要方式。然而&#xff0c;随着摄影技术的不断发展&#xff0c;我们也不得不面对一个令人头疼的问题——图片噪点。无论是低光环境下的拍摄&#xff0c;还是高ISO带来的画质损失&#xff0c;噪点总是如影随形&…...

云计算OpenStack KVM迁移

动态迁移 static migration 静态迁移 cold migration 冷迁移 offline migration 离线迁移 live migration 动态迁移 hot migration 热迁移 online migration 在线迁移 衡量 整体迁移时间 服务器停机时间 性能影响(迁移后和其它客户机) 特点 负载均衡 解除硬件依赖…...

【漏洞复现】网康科技 NS-ASG 应用安全网关 SQL注入漏洞(CVE-2024-2330)

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...