分布式主键ID生成策略

news2024/11/13 10:12:14

小程序搜索“ 源码轻舟 ”后续将推出算法和面试模块

坚持学习,好文每日送达!

 

业务系统对分布式ID的要求

  • 唯一性:在分布式系统中,每个节点都需要生成唯一的标识符来确保数据的唯一性。传统的单点生成ID方式无法满足分布式环境下的需求,而分布式ID能够在整个系统中保证每个节点生成的ID都是唯一的。

  • 顺序性:某些场景下,需要生成的ID具有一定的顺序性,例如按时间顺序记录事件或日志。分布式ID生成策略能够在保证唯一性的同时,尽可能地保持ID的顺序性,方便对数据进行排序和分析。

  • 性能:分布式ID生成策略通常被设计为高性能的方案,能够在高并发的情况下快速生成ID。这对于分布式系统中大量的并行操作和高频率的请求是至关重要的,以确保系统的吞吐量和响应时间。

  • 可扩展性:在分布式系统中,节点数量可能会随着系统的扩展而增加。使用分布式ID可以避免单点生成ID的瓶颈,并且能够轻松地扩展到更多的节点,以适应系统的增长和负载的增加。

  • 无依赖性:分布式ID生成策略通常是独立于外部资源或服务的,因此不需要依赖特定的数据库或其他中心化的组件。这使得系统更加灵活和独立,减少了对外部资源的依赖性和单点故障的风险。

分布式ID生成方案

  • UUID

  • 数据库自增

  • 号段模式

  • Redis实现

  • 雪花算法(SnowFlake)

  • 美团Leaf

  • 滴滴TinyID

UUID

UUID(Universally Unique Identifier)是一种标识符,用于在分布式系统中生成唯一的标识值。它是由一组字母和数字组成的128位(16字节)的字符串,通常以连字符分隔成五段,形如:aa82878d-60cb-4a01-9719-b4af90490fbd

  • 优点:唯一性、简单易用、高性能(基于本地算法生成)

  • 缺点:长度较长,浪费存储空间、可读性差、无序性、不支持自增

数据库自增

假设在一个大型电商项目中,将订单表拆分放在db_0、db_1的两个数据库中,其中db_0数据库中有t_order_01、t_order_02两张订单表,db_1数据库中也有t_order_03、t_order_04两张订单表,如果使用数据库自增来生成分布式ID,那么t_order_01、t_order_02、t_order_03、t_order_04的默认值分别是:1、2、3、4,每次插入数据时的步长是4。如下图所示

虽然数据库的自增看起来是没问题的,但是如果继续扩容是一件很麻烦的事情,因为要重新设置步长,如一开始是4张订单表,步长为4,后面将订单表扩容为8,那么步长就变成8,并且还需要将旧数据重新迁移。

号段模式

  • 设计一个专门生成号段的ID生成器,一般是一个单独的服务或者模块,在该服务中维护生成区段号的表,表结构如下,max_id是当前id的最大值,step是步长,一次请求过来,则返回[max_id + 1,max_id + step]的区间,biz_type是业务类型
CREATE TABLE id_generator (
  id int(10) NOT NULL,
  max_id bigint(20) NOT NULL COMMENT '当前最大id',
  step int(20) NOT NULL COMMENT '号段的布长',
  biz_type  int(20) NOT NULL COMMENT '业务类型'
  PRIMARY KEY (`id`)
) 
  • 当需要ID时则向ID生成器请求一个区段,ID生成器则根据max_id和step计算一个号段返回,如[max_id + 1,max_id + step]

优点:高效性、并发性、可扩展

缺点:ID的使用不连续,造成资源浪费、号段的分配和更新需要进行协调和管理,增加了系统的复杂性和管理成本

Redis实现

在Redis中创建一个计数器,通过Redis的原子性操作来生成递增的ID

优点:由于Redis是基于内存操作的,具有高性能、高并发性、可通过搭建Redis集群来支撑更大规模和高负载的系统

缺点:单点故障、需引进Redis组件

雪花算法(SnowFlake)

雪花算法是Sharding-jdbc默认的分布式ID生成算法,由64bit的整数组成,结构如下图所示,可分成4部分

  • 第一部分的1bit是符号位,0表示是正数,1表示负数,一般都是0

  • 第二部分41bit是时间戳,记录生成ID的时间戳,精确到毫秒级。可以有2的41次方种组合,可以使用时间大概是59年。

  • 第三部分的10bit是工作节点ID,表示在同一毫秒内生成的ID的节点标识。可以分配给不同的节点,最多可以有1024个不同的节点。

  • 第四部分的12bit是序列号,表示同一毫秒内生成的自增序列号。如果在同一毫秒内生成的ID超过了4096个,会等到下一毫秒再继续生成。

  • 优点:雪花算法生成的ID是趋势递增,不依赖数据库等第三方系统,生成ID的效率非常高,稳定性好,可以根据自身业务特性分配bit位,比较灵活

  • 缺点:雪花算法强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。如果恰巧回退前生成过一些ID,而时间回退后,生成的ID就有可能重复。

美团(Leaf)

Leaf提供两种生成ID的模式,分别是号段模式(Leaf-segment)和snowflake模式(Leaf-snowflake)

  • 号段模式

美团Leaf的号段模式对上面讲的号段模式做了优化,在服务端与数据库之间增加了Leaf中间层,由Leaf中间层事先向数据库获取一批ID段缓存起来,当服务端需要获取ID时,直接从Leaf中间层的内存中获取即可。虽然增加了Leaf中间层解决了数据库压力问题,但是当Leaf缓存中的ID用完时,就需要向数据库获取新的号段,这次请求会显得很耗时,为了解决这个问题,美团 Leaf 采用了「双 Buffer + 预加载」的策略,即在内存中维护两个 ID 段,并在上一个 ID 段使用达到 10% 的时候去预加载。

  • Leaf­snowflake方案

Leaf­snowflake是美团基于SnowFlake雪花算法设计的,解决了雪花算法的时钟回拨问题。美团 Leaf 引入了 zookeeper 来解决时钟回拨问题,其大致思路为:每个 Leaf 运行时定时向 zk 上报时间戳。每次 Leaf 服务启动时,先校验本机时间与上次发 ID 的时间,再校验与 zk 上所有节点的平均时间戳。如果任何一个阶段有异常,那么就启动失败报警。

滴滴TinyID

Tinyid是基于号段模式实现,再简单啰嗦一下号段模式的原理:就是从数据库批量的获取自增ID,每次从数据库取出一个号段范围,例如 (1,1000] 代表1000个ID,业务服务将号段在本地生成1~1000的自增ID并加载到内存。

Tinyid会将可用号段加载到内存中,并在内存中生成ID,可用号段在首次获取ID时加载,如当前号段使用达到一定比例时,系统会异步的去加载下一个可用号段,以此保证内存中始终有可用号段,以便在发号服务宕机后一段时间内还有可用ID。

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

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

相关文章

音视频技术开发周刊 | 300

每周一期,纵览音视频技术领域的干货。 新闻投稿:contributelivevideostack.com。 著名数据和AI企业Databricks,收购类ChatGPT开源平台MosaicML 6月27日,Databricks在官网宣布,以13亿美元(约94亿元&#xff…

浅析便捷生活的新选择——抖音本地服务

抖音是一款风靡全球的短视频分享平台,其本地服务功能的发展也逐渐引起了广泛关注。本地服务是指抖音平台上的用户可以通过平台直接查找并使用周边的各种服务,比如美食外卖、快递配送、家政服务等。本地服务的发展对用户和商家都带来了很多便利和机遇。 首…

Spring Boot 中的 Spring Cloud Hystrix 是什么,原理,如何使用

Spring Boot 中的 Spring Cloud Hystrix 是什么,原理,如何使用 简介 在分布式系统中,服务之间的调用是不可避免的。但是,当一个服务调用另一个服务时,如果被调用的服务出现了故障或者延迟,那么调用者也会…

发布/上传Jar包到Maven中央仓库

1.注册Sonatype账号 2.项目申请,创建工单 2.1回复 groupId 域名 可以使用github, io.github.账号 创建工单根据评论回复,需要创建临时仓库,验证账户所有权。 3.gpg4win 地址:https://www.gpg4win.org/download.html &…

电子时钟制作(瑞萨RA)(5)----定时器驱动数码管

概述 要想让每个数码管显示不同的数字,但是数码管必须依次地被持续驱动,数码管之间的刷新速度应该足够快,这样就看不出来数码管之间在闪烁。刷新频率可以设置为2ms刷新一次,这样人眼就看不出闪烁了。 硬件准备 首先需要准备一个…

2011年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题——纯享题目版

🏠个人主页:fo安方的博客✨ 💂个人简历:大家好,我是fo安方,考取过HCIE Cloud Computing、CCIE Security、CISP、RHCE、CCNP RS、PEST 3等证书。🐳 💕兴趣爱好:b站天天刷&…

生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价及拓展

近年来,国内外学者在生态系统的敏感性、适应能力和潜在影响等方面开展了大量的生态脆弱性研究,他们普遍将生态脆弱性概念与农牧交错带、喀斯特地区、黄土高原区、流域、城市等相结合,评价不同类型研究区的生态脆弱特征,其研究内容…

C++ STL --List

1. list的介绍及使用 1.1 list的介绍 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 2. list 的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指…

云原生之深入解析MySQL在K8S环境中部署与监控

一、准备工作 MySQL是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL 是最好的 RDBMS (Relational Database Management System&am…

Spring Boot的Maven插件Spring Boot Maven plugin详解

1.Spring Boot的Maven插件Spring Boot Maven plugin详解 2.Maven插件之git-commit-id-plugin

vue3+ts+elementui制作精美的课表

使用vue3tselementui 如何制作出精美的课表呢&#xff0c; 最终效果图如下: 直接上代码&#xff1a; 这里直接把封装成一个课表的组件&#xff1a; <script setup lang"ts"> import { ref, watch, onMounted } from "vue"; import IconText from …

Fortinet FortiOS 7.4.0 (FortiGate VM deployment Images) - 混合架构防火墙

Fortinet FortiOS 7.4.0 (FortiGate VM deployment Images) - 混合架构防火墙 下一代防火墙 (NGFW)、虚拟化 NGFW 和云原生防火墙 请访问原文链接&#xff1a;https://sysin.org/blog/fortios-7/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&…

MySQL表的增删改查(数据库系列3)

目录 前言&#xff1a; 1.CRUD的解释 2.表的基本操作 2.1查看数据表 2.2创建表 2.3查看指定表的表结构 2.4删除表 2.5注释 3.新增&#xff08;Create&#xff09; 4.查询&#xff08;Retrieve&#xff09; 4.1全列查询 4.2指定列查询 4.3查询字段为表达式 4.4指定…

Linux_Linux基本指令(1)

目录 一、ls指令 二、pwd命令 三、cd指令 四、touch指令 五、mkdir指令 六、rmdir指令&&rm指令 一、ls指令 语法&#xff1a;ls [选项][目录或文件] 对于目录&#xff0c;ls指令是用来列出目录下的所有子目录与文件。对于文件&#xff0c;则是列出文件名及其他信…

zabbix 安装 踩坑记录与解决方案

博主首次安装 zabbix 时&#xff0c;出现了一些错误&#xff0c;特此记录一下&#xff0c;希望帮助到一些 Zabbix freshman. 参考其他博客安装 zabbix 时&#xff0c;运行到如下command 安装zabbix 相关组件出现如下Error: apt installzabbix-server-mysql zabbix-frontend-p…

154个Bug!

持续测试了一个月的H5项目&#xff0c;终于迎来了上线日&#xff0c;在测试H5的过程中&#xff0c;遇到了一些坑&#xff0c;积累了些许经验&#xff0c;想着分享一下&#xff0c;希望对大家有所启发。 主要从以下一个方面展开&#xff1a; 一、项目背景 二、测试环境准备 三…

专项练习18

目录 一、选择题 1、下列选项中&#xff0c;&#xff08;&#xff09;不是网页中的事件 2、下面有关浏览器中使用js跨域获取数据的描述&#xff0c;说法错误的是&#xff1f; 3、请问以下程序的输出是 4、以下哪一项不属于浏览器Response Headers字段&#xff1a; 一、选择题 …

IDEA中集成zookeeper的插件

IDEA中集成zookeeper的插件 一、IDEA中集成插件 搜索插件并安装&#xff1a; 安装完成&#xff0c;重启IDEA 配置zk集群 连接成功

beego 跨域问题处理

这几台在搞前端与后端分离设计&#xff08;之前没接触过&#xff0c;前端vueelementUI&#xff0c; 后端Beego框架&#xff09;&#xff0c;前端要使用到后端数据时&#xff0c;向发送对应的请求&#xff0c;发现提示跨域访问失败&#xff0c;于是需要配置后端支持跨域访问&…

@RequestBody接收不到前端传递过来的json数据

uniRequest.post(/orderParking,{parkingRecord:this.ParkingRecord})我刚开始只是写RequestBody ParkingRecord parkingRecord 一直获取的都是null, 直到用了Map标签才终于获取到参数了 RequestMapping(value "/orderParking",produces"application/json"…