Java 7.3 - 分布式 id
分布式 ID 介绍
什么是 ID?
ID 就是 数据的唯一标识。
什么是分布式 ID?
分布式 ID 是 分布式系统中的 ID,它不存在于现实生活,只存在于分布式系统中。
分库分表:
一个项目,在上线初期使用的是单机 MySQL。但随着需求不断增长,单机 MySQL 已经无法满足当前的需求,我们需要进行分库分表。
分库分表后,数据分布在不同服务器的数据库上,数据库的自增主键无法满足 ID 的唯一性了。此时我们如何为不同的节点生成全局唯一的主键呢?—— 分布式 ID。
分布式 ID 需要满足哪些要求?
1、全局唯一
2、高可用:生成分布式 ID 的服务要保证可能性接近 100%
3、高性能:生成速度要快
4、方便易用
以上四点为分布式 ID 的基本要求,一个好的分布式 ID 还需要满足下列需求:
1、安全
2、有序递增
3、有具体的业务含义:生成的 ID 如果能有具体的业务含义,可以让定位问题以及开发更加透明化
4、独立部署:分布式系统专门有一个服务用来生成分布式 ID,可以和业务相关的服务解耦。
分布式 ID 常见的解决方案有哪些?
数据库
数据库主键自增
通过关系型数据库的自增主键来产生唯一 ID
以 MySQL 为例:
CREATE TABLE `sequence_id` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`stub` char(10) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `stub` (`stub`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
创建一个表,其主键自增。
BEGIN;
REPLACE INTO sequence_id (stub) VALUES ('stub');
SELECT LAST_INSERT_ID();
COMMIT;
插入数据我们使用 replace into 代替 insert into,解释如下:

这种方式的优缺点——
优点:实现简单
缺点:并发量不大,存在数据库单点问题、ID 没有业务含义、安全问题(通过 ID 自增量来判断每天的订单量)、每次获取 ID 都要访问数据库
数据库号段模式
对于数据库主键自增的方法,每有一个订单就需要访问一次数据库,性能比较差。我们可以通过批量获取,存在内存中,需要用到的时候直接从内存中取即可。
以 MySQL 为例:
1、创建一个数据库表
CREATE TABLE `sequence_id_generator` (
`id` int(10) NOT NULL,
`current_max_id` bigint(20) NOT NULL COMMENT '当前最⼤id',
`step` int(10) NOT NULL COMMENT '号段的⻓度',
`version` int(20) NOT NULL COMMENT '版本号',
`biz_type` int(20) NOT NULL COMMENT '业务类型',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
current_max_id 和 step 都是用来获取批量 ID,获取的批量 ID 为:current_max_id -- current_max_id + step
version 解决并发问题(乐观锁)
2、插入一行数据
INSERT INTO `sequence_id_generator` (`id`, `current_max_id`, `step`, `version`,
`biz_type`)
VALUES(1, 0, 100, 0, 101);
3、通过 select 获取指定业务下的批量唯一 ID
SELECT `current_max_id`, `step`,`version` FROM `sequence_id_generator` where
`biz_type` = 101
4、不够用更新后重新 select
UPDATE sequence_id_generator SET current_max_id = 0+100, version=version+1 WHERE
version = 0 AND `biz_type` = 101
SELECT `current_max_id`, `step`,`version` FROM `sequence_id_generator` where
`biz_type` = 101
优缺点 ——
优点:ID 有序递增
缺点:数据库单点问题、ID 没有业务含义、安全问题
NoSQL
一般情况下,NoSQL 方案使用 Redis 多一些。我们通过 Redis 的 incr 命令即可实现对 ID 原子顺序递增。
127.0.0.1:6379> set sequence_id_biz_type 1
OK
127.0.0.1:6379> incr sequence_id_biz_type
(integer) 2
127.0.0.1:6379> get sequence_id_biz_type
"2"
为了提高可用性和并发,我们可以使用 Redis 集群。(Redis Cluster)
优缺点 ——
优点:性能不错且 ID 有序递增
缺点:和数据库主键自增方案缺点类似
算法
UUID
UUID,Universal Unique Identifier(通用唯一标识符)。UUID 包含 32 个 16 进制数字。(8-4-4-4-12)
JDK 提供了现成的生成 UUID 的方法
UUID.randomUUID();

UUID 可以保证唯一性,因为其生成规则包括 MAC 地址、时间戳、名字空间、随机或伪随机数、时序等元素,UUID 不会重复。但虽然 UUID 可以做到全局唯一性,但是我们很少使用它。
UUID 作为 MySQL 主键的时候非常不合适:
1、主键要尽量越短越好
2、UUID 无序,InnoDB 引擎中,数据库主键的无序性会严重影响性能(B+ 树)

UUID 优缺点 ——
优点:生成速度快、简单易用
缺点:空间消耗大、不安全(MAC 地址泄露)、无序、没有具体业务含义、需要解决重复 ID 问题(机器时间不对的情况下,可能生成重复 ID)
Snowflake(雪花算法)

基于 Snowflake 算法的开源实现,比如美团的 Leaf.
优缺点 ——
优点:生成速度快,ID 有序自增、比较灵活(根据业务加入业务ID)
缺点:需要解决重复 ID 问题(机器时间不对导致重复 ID)
开源框架
UidGenerator

Leaf(团子)


Tinyid(滴滴)

相关文章:
Java 7.3 - 分布式 id
分布式 ID 介绍 什么是 ID? ID 就是 数据的唯一标识。 什么是分布式 ID? 分布式 ID 是 分布式系统中的 ID,它不存在于现实生活,只存在于分布式系统中。 分库分表: 一个项目,在上线初期使用的是单机 My…...
144. 腾讯云Redis数据库
文章目录 一、Redis 的主要功能特性二、Redis 的典型应用场景三、Redis 的演进过程四、Redis 的架构设计五、Redis 的数据类型及操作命令六、腾讯云数据库 Redis七、总结 Redis 是一种由 C 语言开发的 NoSQL 数据库,以其高性能的键值对存储和多种应用场景而闻名。本…...
基于单片机的自动浇花控制写设计任务书
一、内容要求: 任务 随着社会的进步,人们的生活质量越来越高。在家里养养盆花可以陶冶情操,丰富生活。同时盆花可以通过光合作用吸收二氧化碳,净化室内空气,在有花木的地方空气中阴离子聚集较多,所以空气…...
从零到精通:用C++ STL string优化代码
目录 1:为什么要学习string类 2:标准库中的string类 2.1:string类(了解) 2.2:总结 3:string类的常用接口 3.1:string类对象的常见构造 3.1.1:代码1 3.1.2:代码2 3.2:string类对象的遍历操作 3.2.1:代码1(begin end) 3.2.2:代码2(rbegin rend) 3.3:string类对象的…...
鸿蒙轻内核M核源码分析系列五 时间管理
往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 持续更新中…… 在鸿蒙轻内核源码分析上一篇文章中,我们剖析了中断的源码,简单提到了Tick中断。本文会继续分析Tick和时间相关的源…...
Python Opencv鼠标回调
使用 OpenCV 的 cv2.setMouseCallback() 方法来捕捉鼠标事件,并实现以下功能: 实时在鼠标指针附近显示其位置的像素坐标。通过左键双击,将像素坐标记录到数组中。通过右键点击,取消上一次添加的坐标。 下面是实现代码的示例&…...
Ubuntu环境的MySql下载安装
下载压缩包 此文章下载的mysql版本位5.7.29 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar解压缩 sudo tar -xvf mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar命令解释 -x:…...
Android系统去掉WIFI模块
先说应用场景,有些特定设备,不能连接wifi。需要隐藏的模块,QS面板模块的wifi,还有设置里面的wifi.由于QS属于SystemUI,熟悉SystemUI之后,就可以直接去SystemUi那里找,找到QSTitle 默认配置的地方。 一、…...
代码随想录 -- 二叉树 -- 翻转二叉树
226. 翻转二叉树 - 力扣(LeetCode) 递归比较简单 class Solution(object):def invertTree(self, root):if rootNone:returnnode rootif node.left or node.right:tempnode.leftnode.leftnode.rightnode.righttempself.invertTree(node.left)self.inve…...
Node.js之文件复制
1.方式一:readFile // 导入fs模块 const fs require("fs") // 导入process模块 const process require("process")// 读取文件内容 let data fs.writeFileSync(./test.txt) // 写入文件内容 fs.writeFileSync(./test1.txt, data) 2.方式二&…...
新手c语言讲解及题目分享(十六)--文件系统专项练习
在我刚开始学习c语言的时候就跳过了这一章节,但在后面慢慢发现这一章节还是比较重要的,如果你报考了计算机二级c语言的话,你应该可以看到后面的三个大题有时会涉及到这章。所以说这章还是非常重要的。 目录 前言 一.打开文件 1.Fopen( )函数返回值 2&…...
RabbitMQ本地Ubuntu系统环境部署与无公网IP远程连接服务端实战演示
文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 安装内网穿透工具3.1 安装cpolar内网穿透3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 💡 推荐 前些天发现了一个巨牛的人工智能学习网站&am…...
[C++#28][多态] 两个条件 | 虚函数表 | 抽象类 | override 和 final | 重载 重写 重定义
目录 0.引入 1.虚函数 1. 虚函数的重写/覆盖 2. 特例1:不加 virtual 关键字的重写 3. 特例2:协变(了解) 2.多态的构成和细节 1. C11 的 override 和 final 1. final 不可重写 2. override 报错检查 ⭕2. 重载、覆盖&…...
List 集合指定值升序降序排列Comparator实现
升序排序 升序排序通常是指从小到大的排序。对于数值类型来说,可以直接使用 compareTo 方法,而对于其他类型,可以根据实际需求实现比较逻辑。 示例代码 import java.util.Comparator; import java.util.List; import java.util.ArrayList;cl…...
【Day07】
目录 MySQL-DQL- 基本查询 MySQL-DQL- 条件查询 MySQL-DQL- 聚合函数 MySQL-DQL- 分组查询 MySQL-DQL- 排序查询 MySQL-DQL- 分页查询 MySQL-DQL- 案例 MySQL-多表设计-一对多 MySQL-多表设计-一对多-外键约束 MySQL-多表设计-一对一&多对多 MySQL-多表设计-案例…...
shell 控制台显示彩色文字的方法
在shell脚本中,如果我们希望在控制台能显示带颜色的文字, 那就需要使用shell中的色彩专用变量代码来进行. shell中的各种颜色代码定义 # 颜色定义 BLACK"\033[0;30m" DARK_GRAY"\033[1;30m" BLUE"\033[0;34m" LIGHT_BLUE"\033[1;3…...
Nginx: 缓存, 不缓存特定内容和缓存失效降低上游压力策略及其配置示例
概述 在负载均衡的过程中,有一个比较重要的概念,就是缓存利用缓存可以很好协调Nginx在客户端和上游服务器之间的速度不匹配的矛盾从而很好的解决整体系统的响应速度 如果用户需要通过Nginx获取某一些内容的时候,发起一个request请求这个请求…...
Python 全栈系列266 Kafka服务的Docker搭建
说明 在大量数据处理任务下的缓存与分发 这个算是来自顾同学的助攻1,我有点java绝缘体的体质,碰到和java相关的安装部署总会碰到点奇怪的问题,不过现在已经搞定了。测试也接近了kafka官方标称的性能。考虑到网络、消息的大小等因素࿰…...
集合框架,List常用API,栈和队列初识
回顾 集合框架 两个重点——ArrayList和HashSet. Vector/ArraysList/LinkedList区别 VectorArraysListLinkedList底层实现数组数组链表线程安全安全不安全不安全增删效率较低较低高扩容*2*1.5-------- (>>)运算级最低,记得加括号。 常…...
构建全景式智慧文旅生态:EasyCVR视频汇聚平台与AR/VR技术的深度融合实践
在科技日新月异的今天,AR(增强现实)和VR(虚拟现实)技术正以前所未有的速度改变着我们的生活方式和工作模式。而EasyCVR视频汇聚平台,作为一款基于云-边-端一体化架构的视频融合AI智能分析平台,可…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...
