简历_使用优化的Redis自增ID策略生成分布式环境下全局唯一ID,用于用户上传数据的命名以及多种ID的生成

devtools/2025/1/19 16:40:02/

系列博客目录


文章目录

  • 系列博客目录
  • Why
  • Redis自增ID策略


Why

我们需要设置全局唯一ID。原因:当用户抢购时,就会生成订单并保存到tb_voucher_order这张表中,而订单表如果使用数据库自增ID就存在一些问题。
问题:id的规律性太明显、受单表数据量的限制。所以在自己的项目中,针对上传的数据的ID的生成也可以使用全局唯一ID。表中有ID,属性类型(文本、音频、图像)以及存储位置,文件名(文件名由ID+原始文件名作为后缀组成)。
多种ID比如用户ID,订单ID。

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

Redis自增ID策略

为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其它信息:
在这里插入图片描述

ID的组成部分:

  • 符号位:1bit,永远为0
  • 时间戳:31bit,以秒为单位,可以使用69年
  • 序列号:32bit,秒内的计数器,支持每秒产生2^32个不同ID
package com.hmdp.utils;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 {/*** 开始时间戳*/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 nowSecond = now.toEpochSecond(ZoneOffset.UTC);long timestamp = nowSecond - 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.拼接并返回return timestamp << COUNT_BITS | count;}
}

使用的示例代码如下:

// 7.创建订单
VoucherOrder voucherOrder = new VoucherOrder();
// 7.1.订单id
long orderId = redisIdWorker.nextId("order");
voucherOrder.setId(orderId);
// 7.2.用户id
voucherOrder.setUserId(userId);
// 7.3.代金券id
voucherOrder.setVoucherId(voucherId);
save(voucherOrder);// 7.返回订单id
return Result.ok(orderId);

每天一个key,方便统计订单量
ID 的构造是 :时间戳 + 计数器


http://www.ppmy.cn/devtools/151859.html

相关文章

DeviceNet转Profinet网关+FANUC机器人:打造工业界的灭霸手套,掌控无限可能

在某车厂项目中&#xff0c;客户需将甲方的FANUC机器人接入自身Profinet网络系统。因机器人采用DeviceNET协议&#xff0c;所以选用稳联技术研发的Profinet转DeviceNET网关&#xff08;WL-DVN-PN&#xff09;实现通讯转换。 新建项目并导入稳联技术DeviceNET转Profinet网关&…

[苍穹外卖] 1-项目介绍及环境搭建

项目介绍 定位&#xff1a;专门为餐饮企业&#xff08;餐厅、饭店&#xff09;定制的一款软件产品 功能架构&#xff1a; 管理端 - 外卖商家使用 用户端 - 点餐用户使用 技术栈&#xff1a; 开发环境的搭建 整体结构&#xff1a; 前端环境 前端工程基于 nginx 运行 - Ngi…

element表格有横向滚动条时产生错位或者偏移(火狐浏览器)

问题图 解决方法&#xff1a;给表头增加竖向滚动条的宽度 // 解决拖拽表格滚动条&#xff0c;错位问题 ::v-deep .el-table__header-wrapper{padding-right: 20px!important; // 滚动条宽度 }效果图如下&#xff1a;

分频器code

理论学习 数字电路中时钟占有非常重要的地位。时间的计算都依靠时钟信号作为基本单元。一般而言&#xff0c;一块板子只有一个晶振&#xff0c;即只有一种频率的时钟&#xff0c;但是数字系统中&#xff0c;经常需要对基准时钟进行不同倍数的分频&#xff0c;进而得到各模块所需…

Codeforces Round 997 (Div. 2)

文章目录 A. Shape Perimeter思路代码 B. Find the Permutation思路代码 C. Palindromic Subsequences思路代码 小记 A. Shape Perimeter 思路 这个题题目说的很复杂但其实不难&#xff0c;一直一开始正方形的边长是m&#xff0c;每次移动x&#xff0c;y个单位&#xff0c;求…

牛客----mysql

用where过滤空值练习_牛客题霸_牛客网 题目&#xff1a;现在运营想要对用户的年龄分布开展分析&#xff0c;在分析时想要剔除没有获取到年龄的用户&#xff0c;请你取出所有年龄值不为空的用户的设备ID&#xff0c;性别&#xff0c;年龄&#xff0c;学校的信息。 示例&#xf…

蓝桥杯算法日常|枚举[*找到最多的数]

**找到最多的数** 重点疑问总结&#xff1a; 1、数组输入输出c一般会采用那种方便的方式&#xff1f;&#xff1f; 用的就是我想的那种&#xff0c;就是用的最大范围定义的。 2、怎样方便给数组中每个数出现的次数计数&#xff1f;&#xff1f; 刚开始想的是&#xff1a;每个数…

HTML5 教程(下)

HTML5 Video(视频) HTML5 Video(视频) 在本节内容中&#xff0c;你将了解到在HTML5中视频是如何工作的、主流浏览器支持的视频格式以及如何对网页中的视频进行控制。 很多站点都会使用到视频. HTML5 提供了展示视频的标准。 检测您的浏览器是否支持 HTML5 视频&#xff1a; …