深入解析分布式ID生成机制

一、概述

背景:随着数据库数据量的增长, 基于性能原因需要进行分库分表,分库分表会导致主键ID重复问题。
特点:

  1. 全局唯一性[必须];
  2. 趋势递增[非必须]。由于互联网大部分采用Mysql的Innodb引擎,因此保持有序主键ID有利于insert的效率;
  3. 单调递增[非必须]。保证下一个ID大于上一个ID,可以保证事务版本号,排序等特殊场景需求;
  4. 信息安全[非必须]。如果ID是连续的,容易被爬虫爬取数据。

二、实现方案

2.1 Java原生UUID

Universally Unique Identifie,通用唯一标识码的简称。为了保证唯一性,通用UUID规范使用MAC地址、时间戳、名字空间以及随机数等元素,保证UUID的唯一性。UUID通常由32个16进制数字,以"-"分成5段,形式为8-4-4-4-12,因此UUID理论上总数为16^32个。
优点:性能非常高,本地生成,不依赖网络;
缺点:ID是随机生成的,不连续的,影响性能。

2.2 自增ID + 步长

利用数据库自增主键,不同机器设置不同步长,步长和机器数相同(参考主键生成策略)。
优点:满足全局ID唯一性,同时利用了数据库自增主键ID,提高了性能;
缺点:

  1. 只能趋势递增,无法保证单调递增;
  2. 机器数是固定死的,一旦需要扩容,那么需要重新设置步长。

2.3 号段模式

从数据库中获取一个号段范围,比如说[1,1000]生成1到1000的自增ID加载到内存中。需要额外设置一张表记录号段相关的信息。
优点:由比较成熟的方案。类似于百度Uidgenerator,美团Leaf
缺点:依赖于数据库实现。

2.4 Redis实现

通过INCR和INCRBY类似的自增原子命令,由于Redis单线程特点,可以保证ID的唯一性和有序性。
优点:Redis性能比较好,且可以保持唯一性和有序性
缺点:

  1. 在并发请求高的情况下,需要Redis集群部署,这就要求和Mysql类似,设置步长;
  2. 需要依赖Redis实现,引入Redis组件

2.5 雪花算法(SnowFlake)

前言:是Twitter开源的由64位整数组成分布式ID,性能较高,并且在单机上递增。
在这里插入图片描述
雪花算法总共64位,具体信息为:

  1. 1bit是符号位,始终是0,表示为正数;
  2. 41bit是时间戳,单位位毫秒。41位的二进制可以使用69年,且时间是永恒递增的,所以ID总趋势是递增的
  3. 10bit是机器标识。可以全部当作机器ID,也可以标识【机房ID + 机器ID】,最多可以表示位1024台机器;
  4. 12bit是计数序列号,即在同一台机器同一时间前提下,还可以生成不同的ID,12bit理论上可以生成4096个ID。

优化点1:

由于41位是时间戳,我们的时间计算是从1970年开始的,只能使用69年。因此,可以考虑将1970修改为项目上线时间,为了不浪费,其实我们可以用【时间的相对值】,也就是以项目开始的时间为基准时间,往后可以使用69年。获取唯一ID的服务,对处理速度要求比较高,所以我们全部使用【位运算以及位移】操作,获取当前时间可以使用System.currentTimeMillis()。

优化点2:时间回拨问题
什么是时间回拨问题呢?就是服务器上的时间突然倒退到之前的时间。

  1. 人为原因,把系统环境的时间改了。
  2. 有时候不同的机器上需要同步时间,可能不同机器之间存在误差,那么可能会出现时间回拨问题。

解决方案:

  1. 回拨时间小的时候,不生成 ID,循环等待到时间点到达;
  2. 如果间隔过大,阻塞等待,肯定是不可取的,因此要么超过一定大小的回拨直接报错,拒绝服务,或者有一种方案是利用拓展位,回拨之后在拓展位上加1就可以了,这样ID依然可以保持唯一。但是这个要求我们提前预留出位数,要么从机器id中,要么从序列号中,腾出一定的位,在时间回拨的时候,这个位置+1

优点:

1. 保证了全局唯一,且在单机器上趋势是递增的,并发场景下性能依然优异;
2. 可根据自身业务特性分配bit位,比较灵活。

缺点:

1. 强依赖时钟;
2. 分布式下虽然趋势递增,但不是单调递增的

三、总结

最佳实践:一般来说,继续采用Mysql的主键ID当作逻辑主键ID,没任何含义;使用分布式全局ID当做业务主键ID,定义为no_null和unique。

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

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

相关文章

KKVIEW远程: TODESK退出了还能远程吗

Todesk退出了还能远程吗 当我们谈论Todesk或其他远程桌面软件时,一个经常被提及的问题是:当我退出Todesk后,是否仍然可以远程访问我的计算机?为了回答这个问题,我们首先需要了解Todesk的工作原理和远程访问的基本条件…

【视觉语言大模型+LLaVA1.0】大语言模型视觉助手(视觉指令调优)GPT4-Vision丐版

官方资源汇总: 项目主页 || https://huggingface.co/liuhaotian 23.04.LLaVA1.论文: Large Language and Vision Assistant(Visual Instruction Tuning) 23.10 LLaVA-1.5论文: Improved Baselines with Visual Instruction Tuning 23.11 LLaVA-Plus项目&…

李畑受邀出席第20届“韩国品牌大奖”颁奖典礼

2024年3月14日,第20届“韩国品牌大奖”颁奖典礼在韩国国家新闻中心举行。李畑女士受邀出席,和与会嘉宾一同见证这一年度盛事。 “韩国品牌大奖”是由政府主管的品牌奖项,旨在奖励在品牌经营方面作出突出贡献的企业和机构。该奖项依据公信力&a…

1.python安装

1.检查是否已经安装python 打开cmd 输入 python --version查看是否有返回版本,没有返回则环境变量未设置好,或者未安装 2.下载安转python https://www.python.org/downloads/windows/ 勾选配置环境变量路径 安装成功

外贸网站常用的wordpress模板

零件配件WordPress外贸建站模板 汽车行业零配件WordPress外贸建站模板,卖配件、零件的外贸公司可以使用的WordPress主题。 https://www.jianzhanpress.com/?p4912 WordPress外贸独立站主题 简洁实用的WordPress外贸独立站主题,适合时尚服装行业搭建w…

Java使用itextpdf往pdf中插入图片

引入maven依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.9</version> </dependency>java代码 import cn.hutool.extra.qrcode.QrCodeUtil; import com.itextpdf.text.*; i…

UE5中各类型的英文名称缩写(直接用于文件前缀)

真正开发项目时用到的素材文件是相当巨量的&#xff0c;在资产中查找时由于不区分文件夹&#xff0c;因此查找是比较头疼的&#xff0c;所以很多同类型的文件名命名时要加入缩写。 本文提供初学者内容包中的缩写&#xff0c;并会在此后陆续加入自定义的缩写&#xff08;本部分…

抖音视频批量提取软件|无水印视频下载

抖音视频批量提取软件&#xff0c;让您高效下载精彩内容&#xff01; 您是否经常需要下载抖音视频&#xff0c;但传统的下载方式繁琐且低效&#xff1f;别担心&#xff0c;我们为您提供了一款强大而智能的抖音视频批量提取软件&#xff0c;让您轻松实现下载无水印的精彩内容&am…

【好书推荐2】AI提示工程实战:从零开始利用提示工程学习应用大语言模型

【好书推荐2】AI提示工程实战&#xff1a;从零开始利用提示工程学习应用大语言模型 写在最前面AI辅助研发方向一&#xff1a;AI辅助研发的技术进展方向二&#xff1a;行业应用案例方向三&#xff1a;面临的挑战与机遇方向四&#xff1a;未来趋势预测方向五&#xff1a;与法规的…

深入理解模板进阶:掌握C++模板的高级技巧

&#x1f389;个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名乐于分享在学习道路上收获的大二在校生 &#x1f648;个人主页&#x1f389;&#xff1a;GOTXX &#x1f43c;个人WeChat&#xff1a;ILXOXVJE &#x1f43c;本文由GOTXX原创&#xff0c;首发CSDN&…

Reactor线程模型

线程模型 一、背景1.socket网络通信2.IO模型与线程模型3.线程模型分类3.1 阻塞模型3.2 Reactor模型3.3 Proactor模式 二、阻塞模型1.代码示例 三、Reactor模型1.单Reactor单线程1.1 处理过程1.2 优缺点1.3 代码示例 2.单Reactor多线程2.1 处理机制2.2 优缺点 3.主从Reactor3.1 …

Ubuntu Desktop 设置 gedit

Ubuntu Desktop 设置 gedit 1. View2. Editor3. Font & Colors4. keyboard shortcut5. Find and ReplaceReferences gedit (/ˈdʒɛdɪt/ or /ˈɡɛdɪt/) is the default text editor of the GNOME desktop environment and part of the GNOME Core Applications. Desig…

[蓝桥杯 2015 省 B] 生命之树

水一水的入门树形DP #include<iostream> #include<algorithm> #include<vector> using namespace std; using ll long long; #define int long long const int N 2e610; const int inf 0x3f3f3f3f; const int mod 1e97;int n; int w[N]; vector<vecto…

Unity双击全屏UI按钮、长按UI按钮

1.长按按钮 将下面的代码挂载到按钮上&#xff0c;去掉按钮本射的Button组件 using System.Collections; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems;public class LongPressButton : MonoBehaviour, IPointerDownHandler, IPointerUpHand…

递推与递归

92. 递归实现指数型枚举 - AcWing题库 #include <bits/stdc.h> using namespace std; const int N17; int n; bool vis[N];//记录某一个数是否出现过 void dfs(int dep){// if(vis[dep])continue;//没有这一句 因为一定不会有已经选过的数if(depn1){//对于每个数都做完了…

NCP1031DR2G集成DC-DC转换器 为以太网供电设备提供低成本、高可靠性解决方案

NCP1031DR2G是微型高电压单片 DC-DC 转换器&#xff0c;带有片上电源开关和启动电路。使用极少的外部部件&#xff0c;将实施若干开关稳压器应用所需的所有有源电源、控制逻辑和保护电路相结合&#xff0c;这些应用有辅助侧偏置电源和低功率 DC-DC 转换器。此控制器系列适用于 …

Learn OpenGL 17 立方体贴图

立方体贴图 我们已经使用2D纹理很长时间了&#xff0c;但除此之外仍有更多的纹理类型等着我们探索。在本节中&#xff0c;我们将讨论的是将多个纹理组合起来映射到一张纹理上的一种纹理类型&#xff1a;立方体贴图(Cube Map)。 简单来说&#xff0c;立方体贴图就是一个包含了…

OpenCV Steger算法提取条纹中心线

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 Steger 算法是一种常用的图像边缘检测算法,可以用于提取图像中的中心线或边缘信息。它的理论假设是:条纹的亮度是按照高斯分布呈现的,即中心亮两侧渐暗。 其计算过程如下所述: 1、首先,我们需要计算每个点Hess…

Kali Linux结合cpolar内网穿透实现公网环境SSH远程访问

文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过[cpolar 内网穿透](cpolar官网-安全的内网穿透工具 | 无需公网ip | 远程访问 | 搭建网站)软件实现ssh 远程连接kali! …

鸿蒙开发实战案例—QQ联系人开发教程

本次案例挑选了QQ4个tab中相对较难的一个页面进行开发 先看一下本次案例的最终效果图&#xff1a; 这个页面的难点在于在List组件又嵌套了一个可以左右滑动的联系人分类&#xff0c;以及好友分组的展开和收起。 现在我们从上到下来开发这个界面&#xff0c;首先是导航栏&…