事务--04---分布式系统唯一ID

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 分布式ID
    • 一、什么是分布式系统唯一ID
    • 2. 二、分布式系统唯一ID的特点
  • 分布式ID-----实现方案
    • 1、使用UUID生成分布式ID
    • 2、基于数据库自增ID
    • 3、Redis生成ID
    • 4、号段模式
        • 滴滴的开源项目TinyId使用的就是这个原理:
    • 5、snowflake(雪花算法)方案
        • 优点:
        • 缺点:
        • 应用举例Mongdb objectID
    • 6、分布式开源项目


分布式ID

一、什么是分布式系统唯一ID

在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。

  1. 如在金融、电商、支付、等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID显然不能满足需求,此时一个能够生成全局唯一ID的系统是非常必要的。

2. 二、分布式系统唯一ID的特点

  • 全局唯一:必须保证ID是全局性唯一的,基本要求
  • 高性能:高可用低延时,ID生成响应要快,否则反倒会成为业务瓶颈
  • 高可用:100%的可用性是骗人的,但是也要无限接近于100%的可用性
  • 好接入:要秉着拿来即用的设计原则,在系统设计和实现上要尽可能的简单
  • 趋势递增:最好趋势递增,这个要求就得看具体业务场景了,一般不严格要求

分布式ID-----实现方案

在这里插入图片描述

1、使用UUID生成分布式ID

优点:

实现方式简单,本地生成,性能高,没有网络消耗。

   public static void main(String[] args) {System.out.println(UUID.randomUUID());//75a90ba3-8bc9-4b37-992f-2d205de1b704}

缺点:

1、UUID太长,占用存储空间多
2、UUID作为主键建立索引和基于索引进行查询存在性能问题,尤其是在InnoDB存储引擎下,UUID的无序性会导致索引位置频繁变动,导致分页
注:UUID可能重复吗?
UUID理论上来说是可能重复的,经过16^32+1次生成之后会产生一次重复的值。但这是一个特别大的值,需要经过很长、很长、很长时间后可能出现一次重复值,所以UUID可以看成是不可重复的值。

2、基于数据库自增ID

单节点数据库生成分布式ID
需要一台单独的数据库服务器,创建一个张表:

CREATE TABLE sequence(id bigint(20) unsigned NOT NULL auto_increment,stub char(1) NOT NULL default '',PRIMARY KEY(id),UNIQUE KEY stub(stub)
) ENGINE=MyISAM;
REPLACE INTO sequence(stub) VALUES('a');
SELECT LAST_INSERT_ID();

以MySQL举例,利用给字段设置auto_increment_increment和auto_increment_offset来保证ID自增,每次业务使用下列SQL读写MySQL得到ID号。

这种方案的优缺点如下:

优点:

  • 非常简单,利用现有数据库系统的功能实现,成本小,有DBA专业维护。
  • ID号单调自增,可以实现一些对ID有特殊要求的业务。

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

  • 强依赖DB,当DB异常时整个系统不可用,属于致命问题。
  • 配置主从复制可以尽可能的增加可用性,但是数据一致性在特殊情况下难以保证。主从切换时的不一致可能会导致重复发号。
  • ID发号性能瓶颈限制在单台MySQL的读写性能。

如果你想到了扩展数据库服务器数量,那么又会引入一个新的问题

  • 如果要增加数据库,那么之前每台数据库设置好的初始值和步长,就需要人工去修改了。这就需要停掉前面配置的所有数据库,去统一修改配制,这样是极其不方便的
  • 并且我们为了生成自增的ID去扩展很多数据库服务器,不觉得有些大材小用吗?这就需要我们从新的角度考虑生成分布式ID的方案。

在这里插入图片描述

3、Redis生成ID

当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。

这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。

比较适合使用Redis来生成每天从0开始的流水号。比如订单号=日期+当日自增长号。可以每天在Redis中生成一个Key,使用INCR进行累加。

优点:

1)不依赖于数据库,灵活方便,且性能优于数据库。

2)数字ID天然排序,对分页或者需要排序的结果很有帮助。

缺点:

1)如果系统中没有Redis,还需要引入新的组件,增加系统复杂度

2)需要编码和配置的工作量比较大。

4、号段模式

  1. 号段模式的大致意思是服务每次从数据库获取ID时,获取ID的一段范围,表示服务获取到了这段范围的所有ID的使用权,比如[1,1000],
  2. 表示当前生成的ID从这段范围内自增,每次服务从这段范围内返回一个自增的ID(可以通过AutomicLong实现)
  3. 这样就不用每次获取Id时都去请求数据库。直到ID自增到1000时,也就表示当前这段的ID使用完了,再去数据库取下一段的ID。
滴滴的开源项目TinyId使用的就是这个原理:

https://github.com/didi/tinyid/wiki/tinyid%E5%8E%9F%E7%90%86%E4%BB%8B%E7%BB%8D
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、snowflake(雪花算法)方案

这种方案大致来说是一种以划分命名空间(UUID也算,由于比较常见,所以单独分析)来生成ID的一种算法,这种方案把64-bit分别划分成多段,分开来标示机器、时间等,比如在snowflake中的64-bit分别表示如下图(图片来自网络)所示:
在这里插入图片描述

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

10-bit机器可以分别表示1024台机器。如果我们对IDC划分有需求,还可以将10-bit分5-bit给IDC,分5-bit给工作机器。这样就可以表示32个IDC,每个IDC下可以有32台机器,可以根据自身需求定义。12个自增序列号可以表示2^12个ID,理论上snowflake方案的QPS约为409.6w/s,这种分配方式可以保证在任何一个IDC的任何一台机器在任意毫秒内生成的ID都是不同的。

这种方式的优缺点是:

优点:
  • 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
  • 不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
  • 可以根据自身业务特性分配bit位,非常灵活。
缺点:
  • 强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务会处于不可用状态。
应用举例Mongdb objectID

MongoDB官方文档 ObjectID可以算作是和snowflake类似方法,通过“时间+机器码+pid+inc”共12个字节,通过4+3+2+3的方式最终标识成一个24长度的十六进制字符。

6、分布式开源项目

在这里插入图片描述

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

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

相关文章

【嵌入式开发 Linux 常用命令系列 14.1 -- .bashrc 定义函数】

上篇文章&#xff1a;【嵌入式开发 Linux 常用命令系列 14 – source hello.sh 和 ./hello.sh 的区别】 文章目录 .bashrc 定义函数 .bashrc 定义函数 在 .bashrc 文件中定义别名时&#xff0c;通常不能直接传递参数。别名是用于创建命令的简写形式&#xff0c;它们不支持参数…

人工智能联盟的首件神兵利器——“Purple Llama” 项目,旨为保护工智能模型安全性

Meta公司&#xff08;Meta Platform Inc&#xff09;&#xff0c;原名Facebook&#xff0c;创立于2004年2月4日&#xff0c;市值5321.71亿美元。总部位于美国加利福尼亚州门洛帕克。 Meta 公司推出了名为“Purple Llama”的项目&#xff0c;旨在保护和加固其开源人工智能模型。…

WINCC8.0脚本调试方法

前言 WINCC是西门子推出的过程可视化系统&#xff08;SCADA&#xff09;&#xff0c;是基于PC的HMI系统&#xff0c;兼容WINDOWS各种系统&#xff0c;除了强大的图形系统之外&#xff0c;WINCC还具有在线历史趋势、报警记录、用户管理、用户归档等高级功能&#xff0c;而且WINC…

华为OD机试真题-考古学家-2023年OD统一考试(C卷)

题目描述: 有一个考古学家发现一个石碑,但是很可惜,发现时其已经断成多段,原地发现n个断口整齐的石碑碎片。为了破解石碑内容,考古学家希望有程序能帮忙计算复原后的石碑文字组合数,你能帮忙吗? 输入描述: 第一行输入n,n表示石碑碎片的个数。 第二行依次输入石碑碎片上…

什么是PHP的SOLID原则?

SOLID 是面向对象编程&#xff08;OOP&#xff09;中的五个设计原则的首字母缩写&#xff0c;这些原则有助于创建可维护、灵活且可扩展的软件。以下是 SOLID 原则的概述&#xff1a; 单一职责原则&#xff08;Single Responsibility Principle - SRP&#xff09;&#xff1a; 一…

[Angular] 笔记1:开发设置 , 双向绑定

1 设置开发环境 1.1 安装 node 下载 node&#xff0c;因为要使用 npm 工具&#xff0c;教程中使用 Angualr 14, 最新版 node 20 用不了&#xff0c;安装 node 16 就可以。 1.2 安装 Angular CLI Angular CLI 是用于创建 Angular 工程的工具集&#xff0c;使用如下命令&…

(第61天)多租户架构(CDB/PDB)

背景介绍 Oracle 的 CDB 和 PDB 是 Oracle 12C 及以上版本中引入的新概念,用于管理多租户数据库环境。 Oracle 数据库是商业数据库领域中的翘楚,其强大的功能和高可靠性备受企业用户追捧。而随着云计算和大数据时代的到来,Oracle 也不断推出新的技术以适应这些变化。CDB 技…

我为什么要当程序员?

阿七毕业于上海一所大学的管理学院&#xff0c;在读期间没写过一行 Java 代码。 管理学院&#xff0c;你出来能干啥呀&#xff1f;什么公司&#xff0c;会让你一个刚毕业的学生当管理呢&#xff1f;所有我们学院的同学&#xff0c;很多都跨科目考研、出国、创业。 家里没钱的…

【leetcode】链表总结

说明&#xff1a;本文内容来自于代码随想录 链表基本操作 https://leetcode.cn/problems/design-linked-list/ 删除节点 https://leetcode.cn/problems/remove-linked-list-elements/description/&#xff0c;删除节点&#xff0c;虚拟头节点。定义两个节点&#xff0c;分别…

『OPEN3D』1.5.2 动手实现点云栅格/体素最近邻

本专栏地址: https://blog.csdn.net/qq_41366026/category_12186023.html?spm=1001.2014.3001.5482 NEARBY6实现的voxel可视化 一种NEARBY14实现的可视化voxel

【LeetCode每日一题】152. 乘积最大子数组

题目&#xff1a; 给你一个整数数组 nums &#xff0c;请你找出数组中乘积最大的非空连续子数组&#xff08;该子数组中至少包含一个数字&#xff09;&#xff0c;并返回该子数组所对应的乘积。 思路 由于做了53. 最大子数组和 下意识觉得求出所有元素的以该元素结尾的连续…

QuPath学习 ② HE scripts

文献中详细介绍了处理H&E scripts的详细过程&#xff0c;计算H&E染色的全切片中的肿瘤基质百分比。 步骤&#xff1a; 1.将相关幻灯片添加到QuPath项目中。 2.对于项目中的每张幻灯片&#xff0c;围绕一个有代表性的肿瘤区域绘制一个注释。 3.运行“Estimate _ bac…

LeetCode190. Reverse Bits

文章目录 一、题目二、题解 一、题目 Reverse bits of a given 32 bits unsigned integer. Note: Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They sho…

【Flink-Sql-Kafka-To-ClickHouse】使用 FlinkSql 将 Kafka 数据写入 ClickHouse

【Flink-Sql-Kafka-To-ClickHouse】使用 FlinkSql 将 Kafka 数据写入 ClickHouse 1&#xff09;需求分析2&#xff09;功能实现3&#xff09;准备工作3.1.Kafka3.2.ClickHouse 4&#xff09;Flink-Sql5&#xff09;验证 1&#xff09;需求分析 1、数据源为 Kafka&#xff0c;定…

每日一博 - Cache Miss Attack

文章目录 概述解决思路缓存空值键并设置短期 TTL&#xff08;生存时间&#xff09;使用布隆过滤器 伪代码1. 缓存空值键并设置短期 TTLa. 缓存空值键b. 设置短期 TTL 2. 使用布隆过滤器a. 集成布隆过滤器b. 查询布隆过滤器 进一步优化系统性能的建议 概述 在缓存管理中&#x…

基于VGG-16+Android+Python的智能车辆驾驶行为分析—深度学习算法应用(含全部工程源码)+数据集+模型(三)

目录 前言总体设计系统整体结构图系统流程图 运行环境模块实现1. 数据预处理2. 模型构建3. 模型训练及保存1&#xff09;模型训练2&#xff09;模型保存 4. 模型生成1&#xff09;模型导入及调用2&#xff09;相关代码&#xff08;1&#xff09;布局文件&#xff08;2&#xff…

bug-ku--计算器

F12 maxlength"1" 限制的是你能输入几位数 改成3就行 来那个数相相加就能输入了 flag{464f5f406e7e182014500fc49f7aedfc}

Mysql和Oracle的区别

MySQL 和 Oracle 是两种常用的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它们有许多相似之处&#xff0c;也有一些显著的不同点。 相同点&#xff1a; 关系型数据库&#xff1a; MySQL 和 Oracle 都是关系型数据库&#xff0c;采用表&#xff08;table&a…

Vue3+Ts项目——登录页面跳转到首页

前言&#xff1a;根据我上篇所实现的左边菜单栏之后&#xff0c;需要登录成功跳转home页面。主要分为三步。 第一步&#xff1a;创建三个ts文件结合pinia缓存登录信息和token src\api\userTypes.ts 就是个接口类方便页面和另一个ts文件数据传递&#xff0c;其实也可以不用 …

【异步绘制】UIView刷新原理 与 异步绘制

快捷目录 壹、 iOS界面刷新机制贰、浅谈UIView的刷新与绘制概述一.UIView 与 CALayer1. UIView 与 CALayer的关系2. CALayer的一些常用属性contents属性contentGravity属性contentsScale属性maskToBounds属性contentsRect属性 二.View的布局与显示1.图像显示原理2.布局layoutSu…