分布式主键

news2024/11/13 16:07:12

目录

1.分布式主键的基本需求

2.常见的分布式主键生成策略

2.1UUID(128位)

2.2MySQL

2.2.1自增主键

2.2.2区间号段

2.3Redis

2.4SnowFlake雪花算法(64位)


1.分布式主键的基本需求

全局唯一:不管什么主键,都需要全局唯一。
高性能高可用:分布式主键服务本身就是一个底层的服务,很多服务都依赖于这个服务,如果底层服务都不稳定,那么上游的服务就更谈不上稳定。
递增:大部分数据存储使用MySQL存储数据,为了快速存储和检索,分布式主键生成策略总趋势要求是递增的。

2.常见的分布式主键生成策略

2.1UUID(128位)

在Java中自带的UUID就具有唯一性。如下面代码所示。生成的结果不是数字,是字符串

UUID 是由128位二进制数组成,通常表示为32个十六进制字符。

public static void main(String[] args) {
    String uuid = UUID.randomUUID().toString().replaceAll("-","");
    System.out.println(uuid);//e48126eb0e6646638b043fca85f38818
}

优点:简单,没有网络消耗。

缺点:

  • 不保证大趋势递增,不利于检索,对索引的构建和维护成本比较大。
  • 长度过长,不利于存储。
  • 没有具体的业务含义。

2.2MySQL

2.2.1自增主键

基于数据库的自增主键充当分布式ID服务器。

具体实现
1)创建一个SEQUENCE_ID表(id,value)
2)每次请求该分布式主键服务时 向SEQUENCE_ID 插入一条数据,并返回自增主键作为分布式主键

优点:实现简单,自增有序;

缺点:DB单点存在宕机风险,扛不住高并发场景。

对于MySQL集群,单点数据库方式不可取,那对上边的方式做一些高可用优化,换成主从模式集群。害怕一个主节点挂掉没法用,那就做双主模式集群,也就是两个Mysql实例都能单独的生产自增ID。(起始值+自增步长)

2.2.2区间号段

以单节点为例,在数据库中维护一个SEQUENCE_ID表。表中定义的是一个order主键生成规则和user主键生成规则。简单对表做一下解释,biz_code表示一种主键,max_id表示已经分配的最大ID,step表示步长用于每次生成一批主键

biz_code

max_id

step

desc

update_time

order

11000

1000

订单表

2022-09-06

user

1000

100

用户表

2022-09-09

在上面数据库的原始数据之上,此时上线了3个节点的订单服务。当用户创建订单时,Order_Node1节点会请求主键服务器生成一批主键,此时数据库表记录为

biz_code

max_id

step

desc

update_time

order

11000

1000

订单表

2022-09-06

[max_id + 1 , max_id + step]这批主键会返回给Order_Node1,即[11001,12000],此时会更新表的数据为

biz_code

max_id

step

desc

update_time

order

12000

1000

订单表

2022-09-07

每个节点的内存中存的是一批主键ID,当时候完毕后再去申请一批数据,效率极高

优点:

  • 并发压力不会再MySQL主键服务器侧。
  • 容灾性好,我一次给你一批,即使主键服务器挂了,Node内存中的主键可以继续使用,Node不应该order_node对外提供服务。

缺点:每当请求主键服务器申请一批主键时,TP 999数据会偶尔出现尖刺。因为当Clinet大量的请求到Order_Node时因没有主键去申请主键时会导致这一批的请求时间会hang住。

双Buffer优化

针对 区间号段 中出现尖刺的情况,使用双Buffer进行优化。

首先申请一批主键,当使用到该批次的10%时,后台起一个线程申请下一批主键,这样一种预加载的情况可以时主键串联起来,有效解决上面的请求RT抖动情况。

2.3Redis

原理就是利用redis的incr命令实现ID的原子性自增

127.0.0.1:6379>set seq_id 1 // 初始化自增ID为1 
OK 
127.0.0.1:6379> incr seq_id // 增加1,并返回递增后的数值 
(integer)2

优点:

  • 极大降低了主键服务器MySQL的流量

缺点:

  • Redis如果使用RDB进行持久化,那么数据会存在丢失的风险。即 incr 后的数据丢失,则再次生成的主键会重复
  • 依赖第三方服务,系统的复杂性会增加

2.4SnowFlake雪花算法(64位)

(雪花算法的基本思想是采用一个8字节的二进制序列来生成一个主键。为什么用8个字节呢?因为8个字节正好是一个Long类型的变量。既保持足够的区分度,又能比较自然的与业务结合。)

  • 第一个bit位(1bit):一般生成ID都为正数,所以默认为0。
  • 时间戳部分(41bit):毫秒级的时间,不建议存当前时间戳,而是用(当前时间戳 - 固定开始时间戳)的差值,可以使产生的ID从更小的值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年
  • 工作机器id(10bit):也被叫做workId,这个可以灵活配置,机房或者机器号组合都可以。
  • 序列号部分(12bit),自增值支持同一毫秒内同一个节点可以生成4096个ID

核心思想:

多种唯一的值 进行拼接,使其更唯一
Snowflake的第二部分是时间戳,时间戳是唯一的,但是如果多个节点同时生产则会参数相同的时间戳,那怎么办?接着加唯一的值,工作机器的ID唯一呀。那么就出现了第三部分的值。但是如果在一个进程中可能两个线程同时请求,那么会产生相同的(时间戳+工作机器ID),那就继续加唯一值,在加上最后的序列号,从而保证全局唯一。

  • 第一个bit位(1bit):一般生成ID都为正数,所以默认为0。
  • 时间戳部分(41bit):保证单节点下请求唯一,但是多节点内请求会生成相同的时间戳
  • 工作机器id(10bit):时间戳 + 工作机器 保证多节点同同时请求可以生成不同的主键ID。但是多节点下多线程还是存在重复
  • 序列号部分(12bit),解决多节点下多线程生成ID重复的问题

优点:

  • 高性能,生成的主键贼多

缺点

  • 生成的主键之间跨度大,不密集,比如我想看一天的订单量,那么根据主键ID相减就没办法
  • 该算法强依赖时间,存在时钟回拨问题

时钟回拨问题常见的解决方案

其实很多大厂基于雪花算法开源的分布式ID解决方案一方面偏重于64的设计,另一方面偏重于时钟回拨出现后的解决方案优化。

  • 回拨时间很短(<100ms)
    当请求系统时如果发现这个时钟回拨的时间段很小,则可以使其睡一会到达之前最新的时间节点而继续往下执行。
  • 回拨时间适中(>100ms && < 1s)
    维护最近的一秒(1000毫秒)每毫秒请求的最大值到Redis中(time,maxId),如果发生时钟回拨则取该毫秒的最大值+1。
  • 回拨时间较长(>1s && < 5s)
    当请求Snowflake1时发现时钟回拨,则可以抛一个异常给客户端,客户端则进行其他节点的访问,负载均衡去实现

  • 回拨时间很长(>5s )
    直接报警下线吧,都不能用了

参考:

分布式主键生成设计策略_分布式主键生成策略-CSDN博客

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

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

相关文章

Linux驱动(二):模块化编程的基本操作

目录 前言一、模块化编程1.模块化驱动代码框架2.printk详解3.应用操作 二、多模块编程三、多文件编程四、函数传参 前言 没多少东西&#xff0c;就是最基础的一些Linux驱动编写操作。 一、模块化编程 驱动加载到内核中的两种方法&#xff1a; 1.静态编译&#xff1a;就是将模…

【Python百日进阶-Web开发-Feffery】Day500 - dash使用秘籍

文章目录 前言:fac是什么?“人生苦短,我用Python;Web开发,首选Feffery!”↓↓↓ 今日笔记 ↓↓↓1 dash应用使用cdn加载静态资源1.1 页面效果1.2 项目源码2 suppress_callback_exceptions=True3 阻止首次回调3.1 阻止所有回调函数的首次回调3.2 阻止单个回调函数的首次回…

《JavaEE进阶》----5.<SpringMVC②剩余基本操作(CookieSessionHeader响应)>

Cookie和Session简介。 Spring MVC的 2.请求 Cookie的设置和两种获取方式 Session的设置和三种获取方式。 3.响应 1.返回静态页面 2.返回数据 3.返回HTML片段 4.返回JSON 5.设置状态码 6.设置header 三、&#xff08;接上文&#xff09;SpringMVC剩余基本操作 3.2postman请求 …

CSAPP Data Lab

CSAPP 的第一个 Lab&#xff0c;对应知识点为书中的第 2 章&#xff08;信息的表示与处理&#xff09;&#xff0c;要求使用受限制的运算符和表达式实现一些位操作。主要分为两个部分&#xff1a;整数部分和浮点数部分。其中整数部分限制较多&#xff0c;比较偏重技巧性&#x…

Red Hat Enterprise Linux 9—Red Hat 9.4Linux系统 Mac电脑虚拟机安装【保姆级教程】

Mac分享吧 文章目录 效果一、下载软件二、安装软件与配置1、安装2、配置 三、查看基本信息安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件 地址&#xff1a;www.macfxb.cn 二、安装软件与配置 1、安装 2、配置 三、查看基本信息 安装完成&#xf…

【国考】特值法

特值法 题干中存在乘除关系&#xff0c;且对应量未知。 例3&#xff1a;甲、乙、丙三个工程队的效率比为6&#xff1a;5&#xff1a;4,现将A、B两项工作量相同的工程交给这三个工程队,甲队负责A工程,乙队负责B工程,丙队参与A工程若干天后转而参与B工程.两项工程同时开工,耗时16…

【PyQt6 应用程序】视频百叶窗效果一键生成模块

在现代的多媒体创作中,音频和视频的结合是提升作品感染力的关键因素之一。尤其是短视频的制作,往往需要根据音频的节奏进行精细的剪辑和特效添加。PyQt6 作为一个功能强大的 Python GUI 库,为我们提供了极大的便利,使得我们可以轻松地创建功能丰富的应用程序。 本教程将一…

J.U.C并发工具集实战及原理分析

​在J.U.C里提供了很多的并发控制工具类&#xff0c;这些工具类可以使得线程按照业务的某种约束来执行。本节包含CountDownLatch、Semaphore、CyclicBarrier等工具类。目的是了解他们基本使用、原理及实际应用。 1. CountDownLatch主题 1.1 CountDownLatch简介 CountDownLat…

ShardingSphere-JDBC实现数据加解密

一、什么是ShardingSphere&#xff1f; ShardingSphere定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库&#xff0c;以 jar 包形式提供服务&#xff0c;无需额外部署和依赖&#xff0c;可理解为增强版的 JDBC 驱动&#xff0c;完…

最优化理论(一)

什么是最优化问题 最优化问题是决策问题&#xff0c;选择一下可以执行的策略来使得目标最优。 一个最优化问题包括&#xff1a; 决策变量一个或多个目标函数一个由科兴策略组成的集合&#xff0c;可由等式或者不等式刻画 最优化问题的基本形式&#xff1a; 最优化问题的分类…

upload-labs通关攻略

Pass-1 这里上传php文件说不允许上传 然后咱们开启抓包将png文件改为php文件 放包回去成功上传 Pass-2 进来查看提示说对mime进行检查 抓包把这里改为image/jpg; 放包回去就上传成功了 Pass-3 这里上传php文件它说不允许上传这些后缀的文件 那咱们就可以改它的后缀名来绕过…

Guitar Pro 8.2.1 Build 32+Soundbanks Win/Mac音色库 开心激活版 音乐软件Guitar Pro 8中文破解版

音乐软件Guitar Pro 8中文破解版是一个受吉他手喜爱的吉他和弦、六线谱、BASS 四线谱绘制、打印、查看、试听软件&#xff0c;它也是一款优秀的 MIDI 音序器&#xff0c;MIDI 制作辅助工具&#xff0c;可以输出标准格式的 MIDI。GP 的过人之处就在于它可以直接用鼠标和键盘按标…

过滤器 与 拦截器

文章目录 过滤器 与 拦截器一、过滤器&#xff08;Filter&#xff09;1、特点2、生命周期3、实现4、过滤器链1&#xff09;配置 order2&#xff09;执行顺序 二、拦截器 Inteceptor1、特点2、生命周期3、实现4、拦截器链1&#xff09;配置 order2&#xff09;执行顺序&#xff…

【Linux】保姆级 Linux 常见命令使用

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. Linux 是什么1.1 Linux 是什么1.2 关于 Linux 我们需要学什么 2. 需提前准备的东西2.1 环境 —— 如何获取…

关于PowerDesigner的使用

1.PowerDesigner概述&#xff1a; 1.PowerDesigner是一款开发人员常用的数据库建模工具&#xff0c;用户利用该软件可以方便地制作 数据流程图、概念数据模型 、 物理数据模型 &#xff0c;它几乎包括了数据库模型设计的全过程&#xff0c;是Sybase公司为企业建模和设计提供的…

蓝色炫酷碎粒子HTML5导航源码

源码介绍 蓝色炫酷碎粒子HTML5导航源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果预览 源码获取 蓝色炫酷碎粒…

火焰传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 三、程序设计 main.c文件 IR.h文件 IR.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 火焰传感器是一种常用于检测火焰或特定波长&#xff08;760nm-1100nm&#xff09;红外光的传感器。探测角度60左右&am…

MQTT学习:MQTT vs AMQP,mosquitto安装,调试工具mqttfx mqttx

前言 物联网vs互联网? 数据量/数据源:物联网的数据多是设备的自动采集,其数量远远超过互联网,互联网的数据更多是人工生成的 MQTT 协议(Message Queuing Telemetry Transport)vs AMQP 协议(Advanced Message Queuing Protocol)是两种在物联网中广泛使用的协议。 物联网…

推荐一款灵活,可靠和快速的开源分布式任务调度平台

今天给大家推荐一款灵活&#xff0c;可靠和快速的开源分布式任务调度平台——SnailJob。 前言 什么是任务调度&#xff1f; 任务调度&#xff0c;是指在多任务的环境下&#xff0c;合理地分配系统资源&#xff0c;调度各个任务在什么时候&#xff0c;由哪一个处理器处理&…

【简单】 猿人学web第一届 第15题 备周则意怠,常见则不疑

数据接口分析 数据接口 https://match.yuanrenxue.cn/api/match/15 请求时需要携带 page 页码&#xff0c;m为加密参数 cookie中没有加密信息&#xff0c;携带 SessionId请求即可 加密参数还原 查看数据接口对应的 requests 栈 m参数 是通过 window.m() 方法执行后得到的 打上…