Redis之全局唯一ID

全局ID生成器

在这里插入图片描述

文章目录

  • 全局ID生成器
    • 一、全局ID生成器的定义
      • 定义
      • 核心作用
    • 二、全局ID生成器需满足的特征
      • 1. 唯一性(Uniqueness)​
      • 2. 高性能(High Performance)​
      • 3. 可扩展性(Scalability)​
      • 4. 有序性(Orderliness)​
      • 5. 可靠性(Reliability)​
      • 6. 安全性(Security)​
      • 7. 兼容性(Compatibility)​
    • 三、全局唯一ID生成策略:
      • 1. UUID
      • 2. 数据库自增ID
      • 3. Snowflake算法(Twitter开源)​
      • 4. Redis自增
      • 5. 数据库号段模式
      • 6. Leaf(美团开源)​
    • 四、策略对比
    • 五、选型建议

一、全局ID生成器的定义

定义

  • 全局ID生成器是一种在分布式系统中生成唯一标识符(ID)的机制,确保生成的ID在整个系统范围内(可能跨多个服务、数据库或数据中心)具有唯一性。它是解决分布式环境下数据唯一性、数据关联和事务协调等问题的核心技术之一。

核心作用

  • ​唯一性:确保每个生成的ID在全局范围内不重复。
  • 可识别性:通过ID快速定位资源或关联业务(如订单、用户、消息等),不能被看出太明显的规律。
  • ​扩展性:支持系统规模增长(如分库分表、多节点部署)时仍能高效生成ID,高效应对海量数据。

二、全局ID生成器需满足的特征

全局ID生成器,是分布式系统环境下生成全局唯一ID的工具,一般需要满足下列特征:

1. 唯一性(Uniqueness)​

  • 核心要求:生成的ID在全局范围内绝对唯一。
  • 意义:避免数据冲突(如主键重复、消息覆盖)。
  • 实现方式
    • 算法设计(如Snowflake通过时间戳+机器ID+序列号保证唯一)。
    • 中心化协调(如数据库自增ID依赖数据库的唯一约束)。

2. 高性能(High Performance)​

  • 要求:生成ID的速度快,延迟低,支持高并发场景。
  • 意义:避免成为系统瓶颈(如秒杀场景下每秒生成数十万ID)。
  • 实现方式
    • 本地生成(如Snowflake在内存中生成,无需网络请求)。
    • 批量预分配(如数据库号段模式一次性获取多个ID)。

3. 可扩展性(Scalability)​

  • 要求:支持系统横向扩展(如新增节点)时无需重构ID生成逻辑。
  • 意义:适应业务增长,避免单点瓶颈。
  • 实现方式
    • 分布式算法(如Snowflake允许动态增加机器ID)。
    • 去中心化设计(如UUID无需中心节点)。

4. 有序性(Orderliness)​

  • 要求:生成的ID按时间递增或可排序。
  • 意义:便于数据库索引优化、分页查询和业务排序(如按时间排序订单)。
  • 实现方式
    • 时间戳高位(如Snowflake将时间戳放在ID的高位)。
    • 数据库自增ID天然有序,但分布式下需分片步长策略。

5. 可靠性(Reliability)​

  • 要求:生成过程容错,避免单点故障。
  • 意义:保障系统高可用(如机器宕机不影响ID生成)。
  • 实现方式
    • 去中心化算法(如Snowflake无单点依赖)。
    • 冗余设计(如Leaf通过ZooKeeper管理机器ID,支持故障转移)。

6. 安全性(Security)​

  • 要求:防止ID被猜测或遍历(如避免暴露业务量或用户隐私)。
  • 意义:防止恶意攻击(如通过ID遍历批量查询数据)。
  • 实现方式
    • 加入随机性(如UUIDv4的随机部分)。
    • 加密或哈希处理(如美团的Leaf-Segment加密号段)。

7. 兼容性(Compatibility)​

  • 要求:ID格式适配现有技术栈(如数据库类型、网络传输)。
  • 意义:降低集成成本(如避免使用超长ID导致存储浪费)。
  • 实现方式
    • 数值型ID(如Snowflake的64位Long类型,兼容MySQL BIGINT)。
    • 字符串ID(如UUID的128位字符串,适配NoSQL数据库)。

三、全局唯一ID生成策略:

1. UUID

  • 原理:生成128位随机字符串(如 550e8400-e29b-41d4-a716-446655440000)。
  • 优点:简单、无需中心化协调。
  • 缺点:无序、长度长、存储和索引效率低。
  • 适用场景:非高频查询场景,如日志跟踪、临时标识。
  • 优化:使用UUIDv4(随机生成)避免隐私问题。

2. 数据库自增ID

  • 原理:利用数据库自增主键生成唯一ID。
  • 优点:简单、天然有序。
  • 缺点:单点瓶颈、横向扩展困难。
  • 优化
    • 分库分表:为每个分片设置不同步长(如库1步长=2,起始值=1;库2步长=2,起始值=2)。
    • 批量获取:一次性申请多个ID(如 INSERT … SELECT MAX(id)+N)。

3. Snowflake算法(Twitter开源)​

  • ID结构​(64位):
    | 符号位(1) | 时间戳(41) | 机器ID(10) | 序列号(12) |
    
  • 优点:有序、高性能、去中心化。
  • 缺点:依赖系统时钟(时钟回拨需处理)。
  • 实现
    public class Snowflake {private final long machineId;   // 机器ID(0~1023)private long lastTimestamp = -1L;private long sequence = 0L;public synchronized long nextId() {long timestamp = System.currentTimeMillis();if (timestamp < lastTimestamp) throw new RuntimeException("时钟回拨");if (timestamp == lastTimestamp) {sequence = (sequence + 1) & 0xFFF; // 序列号自增,溢出则等待下一毫秒if (sequence == 0) timestamp = waitNextMillis();} else {sequence = 0;}lastTimestamp = timestamp;return ((timestamp - TWEPOCH) << 22) | (machineId << 12) | sequence;}
    }
    

4. Redis自增

  • 原理:利用Redis的原子操作 INCR 或 INCRBY 生成自增ID。使用Java的Long类型存储,为了增加ID的安全性,我们可以不直接只用Redis自增的数值,而是拼接一些其他信息:

    ID的组成部分(Java Long类型存储,占用8个字节,也就是64个比特位):0  - 0000000 00000000 00000000 00000000 - 00000000 00000000 00000000 00000000↑                  ↑                                     ↑符号位 |<------- 时间戳(31 bit)-------->|  |<-------- 序列号(32 bit)-------->|
    
    • 符号位: 1 bit,永远为0(表示正数)
    • 时间戳:31 bit,以秒为单位,以2000年1月1日00时作为参照系,用当前时间 - 参照时间 = 时间戳,2^31 秒 约等于69年。
    • 序列号:31 bit,Redis自增的值,该方式理论上支持每秒产生 2^32 个不同ID。
  • ​优点:高性能、简单。

  • 缺点:依赖Redis可用性,需处理持久化问题。

  • 优化:集群模式 + 多Key分片(如 order_id:shard_1)。

  • 实现

    @Component
    public class RedisIdGenerator {/*** 开始时间戳 2000年1月1日零时零分零秒*/private static final long BEGIN_TIMESTAMP = 946684800L;/*** 序列号位数*/private static final int COUNT = 32;private StringRedisTemplate stringRedisTemplate;@Autowiredpublic RedisIdGenerator(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.生成序列号String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd")); // 使用冒号分割,方便统计Long increment = stringRedisTemplate.opsForValue().increment("icr:" + keyPrefix + ":" + date); // 加入日期,防止超出2^32上限(Redis自增上限为2^64)long incrementUnbox = 0L;if (increment != null) {incrementUnbox = increment;}// 3.拼接并返回return timestamp << COUNT | incrementUnbox; // 左移 32位,拼接时间戳和序列号}public static void main(String[] args) {// 2000年1月1日零时零分零秒 的秒数LocalDateTime time = LocalDateTime.of(2000, 1, 1, 0, 0, 0);long second = time.toEpochSecond(ZoneOffset.UTC);System.out.println("second = " + second); // second = 946684800}
    }
    

5. 数据库号段模式

  • 原理:从数据库批量获取号段(如一次分配1000个ID),缓存在本地使用。
  • 表设计
    CREATE TABLE id_segment (biz_tag VARCHAR(32) PRIMARY KEY,  -- 业务标识max_id BIGINT NOT NULL,           -- 当前最大IDstep INT NOT NULL                 -- 每次步长
    );
    
  • 优点:减少数据库压力、可扩展性强。
  • 缺点:需维护号段表,处理并发冲突。

6. Leaf(美团开源)​

  • 混合模式
    • 号段模式:类似数据库号段,依赖数据库。
    • Snowflake模式:依赖ZooKeeper分配机器ID。
  • 优点:高可用、灵活切换模式。
  • 实现:通过ZooKeeper管理机器ID,支持号段预分配。

四、策略对比

策略唯一性有序性性能可靠性典型场景
UUID日志跟踪、临时标识
​数据库自增ID❌(单点)中小规模分库分表
Snowflake极高✅(去中心化)高并发订单、消息队列
Redis INCR❌(依赖Redis)短期唯一ID(如会话ID)
​Leaf(美团)​✅(混合模式)大规模分布式系统

五、选型建议

场景推荐方案关键考虑
高性能、有序IDSnowflake处理时钟回拨(NTP同步、异常等待)
简单、无序UUID v4适合临时标识
依赖RedisRedis INCR需保障Redis高可用
数据库友好、可控数据库号段模式适合中小规模分布式系统
企业级复杂场景Leaf结合号段和Snowflake优势

实际选型建议

  1. 高并发有序ID:优先选择Snowflake或其变种(如美团的Leaf-Segment)。
  2. ​简单临时标识:使用UUID v4(如用户临时Token)。
  3. 数据库友好场景:数据库号段模式(如分库分表的预分配ID)。
  4. 强一致性需求:结合Redis或ZooKeeper的分布式锁生成ID。

常见问题处理

  1. 时钟回拨
    • 方案:记录上次时间戳,发现回拨时抛出异常或等待时钟追上。
    • 优化:使用NTP同步服务器时间,或扩展Snowflake增加时间戳位数。
  2. 机器ID分配
    • 方案:ZooKeeper/配置中心动态分配,或按数据中心+机器ID编码。

根据业务规模、一致性要求及运维成本选择合适的策略,必要时可组合使用多种方案。

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

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

相关文章

nginx中的代理缓存

1.缓存存放路径 对key取哈希值之后&#xff0c;设置cache内容&#xff0c;然后得到的哈希值的倒数第一位作为第一个子目录&#xff0c;倒数第三位和倒数第二位组成的字符串作为第二个子目录&#xff0c;如图。 proxy_cache_path /xxxx/ levels1:2 2.文件名哈希值

静态时序分析STA——8.1 时序检查(建立时间检查)

文章目录 一、时序路径组二、建立时间检查1. 触发器到触发器路径1&#xff09;时钟单元UCKBUF0的延迟计算2&#xff09;时钟源延迟&#xff08;clock source latency&#xff09; 2. 输入到触发器路径1) 虚拟时钟的输入路径2) 具有实际时钟的输入路径 3. 触发器到输出路径4. 输…

了解高速设计的信号完整性仿真

高速设计需要精确的信号传输&#xff0c;以确保最佳性能。信号完整性差会导致关键应用中的误码、数据损坏甚至系统故障等问题。介电常数、损耗角正切和插入损耗等因素会显著影响信号质量。通过使用信号完整性仿真&#xff0c;您可以及早发现并解决这些挑战。这种主动方法有助于…

RAGFlowwindows本地pycharm运行

Python环境准备 1. 安装pipx。如已经安装&#xff0c;可跳过本步骤&#xff1a; python -m pip install --user pipxpython -m pipx ensurepath## 验证安装pipx --version2. 安装 uv。如已经安装&#xff0c;可跳过本步骤&#xff1a; pipx install uv ## 设置为阿里云 PyPI…

STM32-FreeRTOS的详细配置

配置FreeRTOS 原文链接&#xff1a;https://ydamooc.github.io/posts/c9defcd/ 1.1 下载FreeRTOS 打开FreeRTOS官网&#xff1a;https://www.freertos.org/ 点击下载&#xff0c;并且选择"FreeRTOS 202212.01"版本&#xff0c;再点击Download按钮下载官方的资源包…

Linux笔记---动静态库(原理篇)

1. ELF文件格式 动静态库文件的构成是什么样的呢&#xff1f;或者说二者的内容是什么&#xff1f; 实际上&#xff0c;可执行文件&#xff0c;目标文件&#xff0c;静态库文件&#xff0c;动态库文件都是使用ELF文件格式进行组织的。 ELF&#xff08;Executable and Linkable…

HVV-某田相关经历

一、背景 本次项目为期两周&#xff0c;由集团主导招募攻击队员对集团下属及其子公司进行的攻防演练。本次项目主导研判分析应急排查内部Nday发掘。 二、研判分析 2.1、帆软V10 漏洞概述 帆软 V10 及 V11 版本报表软件存在反序列化漏洞&#xff0c;攻击者可利用该漏洞使用…

AI与物联网的深度融合:开启智能生活新时代

在当今数字化时代&#xff0c;人工智能&#xff08;AI&#xff09;和物联网&#xff08;IoT&#xff09;作为两大前沿技术&#xff0c;正在加速融合&#xff0c;为我们的生活和工作带来前所未有的变革。这种融合不仅提升了设备的智能化水平&#xff0c;还为各行各业带来了新的机…

Linux `init` 相关命令的完整使用指南

Linux init 相关命令的完整使用指南—目录 一、init 系统简介二、运行级别&#xff08;Runlevel&#xff09;详解三、常用 init 命令及使用方法1. 切换运行级别2. 查看当前运行级别3. 服务管理4. 紧急模式&#xff08;Rescue Mode&#xff09; 四、不同 Init 系统的兼容性1. Sy…

UNet 改进(12):UNet with ECA (Efficient Channel Attention) 网络

详解 下面将详细解析这个实现了ECA注意力机制的UNet网络代码。 1. 代码概述 代码实现了一个带有Efficient Channel Attention (ECA)模块的UNet网络架构。 UNet是一种常用于图像分割任务的编码器-解码器结构网络,而ECA模块则是一种轻量级的通道注意力机制,可以增强网络对重…

视频监控EasyCVR视频汇聚平台接入海康监控摄像头如何配置http监听功能?

一、方案概述 本方案主要通过EasyCVR视频管理平台&#xff0c;实现报警信息的高效传输与实时监控。海康监控设备能通过HTTP协议将报警信息发送至指定的目的IP或域名&#xff0c;而EasyCVR平台则可以接收并处理这些报警信息&#xff0c;同时提供丰富的监控与管理功能&#xff0…

人工智能与网络安全:AI如何预防、检测和应对网络攻击?

引言&#xff1a;网络安全新战场&#xff0c;AI成关键角色 在数字化浪潮不断推进的今天&#xff0c;网络安全问题已经成为每一家企业、每一个组织无法回避的“隐形战场”。无论是电商平台、金融机构&#xff0c;还是政府机关、制造企业&#xff0c;都可能面临数据泄露、勒索病毒…

3D人脸扫描技术如何让真人“进入“虚拟,虚拟数字人反向“激活“现实?

随着虚拟人技术的飞速发展&#xff0c;超写实数字人已经成为数字娱乐、广告营销和虚拟互动领域的核心趋势。无论是企业家、知名主持人还是明星&#xff0c;数字分身正在以高度还原的形象替代真人参与各类活动&#xff0c;甚至成为品牌代言、直播互动的新宠。 3D人脸扫描&#…

递归函数详解

定义 递归是指一个函数在其定义中直接或间接地调用自身的方法。通过这种方式&#xff0c;函数可以将一个复杂的问题分解为规模更小的、与原问题相似的子问题&#xff0c;然后通过不断地解决这些子问题来最终解决整个问题。 组成部分 递归主体 这是函数中递归调用自身的部分…

ASP.NET Core Web API 配置系统集成

文章目录 前言一、配置源与默认设置二、使用步骤1&#xff09;创建项目并添加配置2&#xff09;配置文件3&#xff09;强类型配置类4&#xff09;配置Program.cs5&#xff09;控制器中使用配置6&#xff09;配置优先级测试7&#xff09;动态重载配置测试8&#xff09;运行结果示…

在生信分析中,从生物学数据库中下载的序列存放在哪里?要不要建立一个小型数据库,或者存放在Gitee上?

李升伟 整理 在Galaxy平台中使用时&#xff0c;从NCBI等生物学数据库下载的DNA序列的存储位置和管理方式需要根据具体的工作流程和需求进行调整。以下是详细的分步说明和建议&#xff1a; 一、Galaxy中DNA序列的默认存储位置 在Galaxy的“历史记录”&#xff08;History&…

SDK游戏盾如何接入?复杂吗?

接入SDK游戏盾&#xff08;通常指游戏安全防护类SDK&#xff0c;如防DDoS攻击、防作弊、防外挂等功能&#xff09;的流程和复杂度取决于具体的服务商&#xff08;如腾讯云、上海云盾等&#xff09;以及游戏类型和技术架构。以下是一般性的接入步骤、复杂度评估及注意事项&#…

通过类似数据蒸馏或主动学习采样的方法,更加高效地学习良品数据分布

好的&#xff0c;我们先聚焦第一个突破点&#xff1a; 通过类似数据蒸馏或主动学习采样的方法&#xff0c;更加高效地学习良品数据分布。 这里我提供一个完整的代码示例&#xff1a; ✅ Masked图像重建 残差热力图 这属于自监督蒸馏方法的一个变体&#xff1a; 使用一个 预…

【课题推荐】多速率自适应卡尔曼滤波(MRAKF)用于目标跟踪

多速率自适应卡尔曼滤波(Multi-Rate Adaptive Kalman Filter, MRAKF)是一种针对多传感器异步数据融合的滤波算法,适用于传感器采样率不同、噪声特性时变的目标跟踪场景。本文给出一个多速率自适应卡尔曼滤波框架,以无人机跟踪场景为例,融合IMU和GPS数据 文章目录 背景多速…

软考 系统架构设计师系列知识点之杂项集萃(49)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;48&#xff09; 第76题 某文件管理系统在磁盘上建立了位视图&#xff08;bitmap&#xff09;&#xff0c;记录磁盘的使用情况。若磁盘上物理块的编号依次为&#xff1a;0、1、2、……&#xff1b…