针对高并发写,分布式ID是其业务基础,本文从一个面试题细细展开。

面试官:

1.对于Mysql的InnoDB引擎下,自增ID和UUID作为主键各自有什么优劣,对于一张表的主键你建议使用哪种ID?

2.除了UUID是否还了解其他类型的唯一ID?

对于这两个问题,我们需要深入了解的知识有两个:

1.mysql的innodb引擎的数据组织结构是什么样的

2.分布式ID都有几种各自的优劣是什么

还有这里要关注一点,为什么强调了InnoDB 引擎,还有什么引擎(MyISAM这个后续再说)?


Mysql-InnoDB 引擎

通常InnoDB为mysq的默认引擎,此引擎也是我们最熟识的B+树作为我们数据的基础组织结构,B+树作为一个“矮胖子”,通过4层高度就能组织千万数据,极大的减少了磁盘IO次数提升了数据访问效率,这也是它可以作为大多数公司数据持久化基石的原因。


(此图非原创-侵删)


对于此B+树结构,数据库的数据新增,顺序新增还是随机新增对于它的执行效率有很大影响,如果新增数据是随机的,那可能增加大量的IO,因为每次新增都可能页分裂与页合并,涉及数据挪移,而对于顺序新增,每次都会在页尾进行操作,这大大减小了磁盘IO,因此对于一个业务主键,它应该是单调递增的,这样可以大大提升数据插入效率。

自增ID和UUID作为主键对比

其实这个问题,面试官最主要就是要考察的UUID对于mysql 随机写入的影响,当然其他的了解越多越好。

特点对比

自增ID

UUID(v4)

实现方式

数据库支持

工具包支持

生成速率限制

取决于数据库的TPS,比较低

无上限

写入效率*

顺序写入,性能很高

随机写入导致数据写入性能急剧下降

查询效率

数字查询效率更高(数字比较)

36位字符(32+4个‘-’)比较效率稍低

存储空间

BigInt 8字节

Varchar(36) 1字节前缀+36字节=37字节

业务量推测

根据id相减可推测业务量

随机无法推测

其实可以看出,这两种方案都会存在一个致命性问题,自增id强依赖数据库且生成效率低,UUID对于写入效率又有很大问题。针对上面分析其实我们需要的分布式id 需要具有以下特性:全局唯一、单调递增、高效生成。很多大家熟悉的方案都是针对上面两种方案的优化产生,整理目前的解决方案如下:




分布式ID-Snowflake

先说说名字(个人猜测)之所以取雪花这个名字,是威尔逊·奥尔温·宾利(Wilson Bentley)他通过显微镜和显微摄影技术拍摄了5382张雪花照片,证实了雪花形态的独特性,因此产生观点“世界上没有两片完全相同的雪花”,美团的leaf名字异曲同工。

直接上图吧,原始snowflake 和mongo的objectId 原理相似。

而经典的雪花算法和类雪花算法,由于整体ID的组成使用了时间戳,所以都会存在一个重要的bug情况“时钟回拨”。

时钟回拨:是指一台机器的操作系统时钟,突然跳变到了一个比当前系统记录的时间更早的时刻。

一旦产生时钟回拨就可能产生致命的问题,分布式ID不能保证全局唯一,这样会对业务造成严重影响。

产生时钟回拨的原因:

NTP时间同步:一般毫秒级别回拨,当 NTP 客户端发现自己的本地时钟比时间服务器快时,为了逐步纠正这个误差,它可能会选择逐步减慢时钟(斯步进,slewing),但在某些配置或差异过大时,NTP 服务可能会认为时钟发生了严重故障,从而采取直接跳转(步进,stepping)的方式,将系统时间瞬间调回正确时间。硬件时钟(RTC)问题:回拨时间很严重,这个由CMOS电池供电(想不到吧),如果电池没电了会重置一个比较早的时间例如1970-01-01,如果这系统重启了,系统会先读取RTC时间,再NTP同步时间,在NTP同步之前时钟都是错误的。

虚拟化环境:挂起后恢复,需要同步宿主机时间。

人为误操作: 看修改情况了,谁脑子抽筋取修改系统时间或时区。

分布式ID-美团Leaf-Snowflake

美团leaf的雪花模式,针对于雪花算法做了两处优化:

1.workerId 不手动分配使用zookeeper(弱依赖)获取。

2.解决时钟回拨问题(所有以雪花模式生成分布式ID都会去解决时钟回拨)。

workerId 分配原理

对于workerId,当系统节点数过多的时候,很难手动维护,因此选择启动时通过zookeeper加载,在加载后会本地持久化一个workerId,当zooKeeper挂了了时则采用本地数据,提升SLA。



如何解决时钟回拨问题

1.启动时时间校准

如果启动时校验失败,则此机器启动失败,不接入发号集群。

(1)连接zookeeper

(2)判断是否节点已存在(Ip:port)本机时间>存在节点以前上报的时间

(3)存在则直接返回,不存在则新建

(4)获取leaf_temporary下所有其他机器ip:port

(5)RPC 请求所有其他机器的时间abs( 本机时间-sum(time)/nodeSize ) < 阈值,如果大于预置则直接失败

(6)成功后3s定时上报当前机器时间


2.发号过程等待或失败

做一层自旋等待重试,然后上报报警系统,自动摘除或者人工接收报警处理。


总结:美团leaf的雪花算法通过检测两个方面保证生成分布式ID单调递增,1.在启动时依赖zookeeper存储数据校验,失败则不允许加入集群,2.在每次发号时比较上次发号时间,小于5ms 则等待10ms再次校验,失败则报警或自动摘除。

分布式ID-百度uid-generator

百度主要实现了两种generator:

DefaultUidGenerator

雪花算法(以秒位单位)+时钟回拨报异常(没有自旋等待)

  • sign(1bit)
    固定1bit符号标识,即生成的UID为正数。
  • delta seconds (28 bits)
    当前时间,相对于时间基点"2016-05-20"的增量值,单位:秒,最多可支持约8.7年
  • worker id (22 bits)
    机器id,最多可支持约420w次机器启动。内置实现为在启动时由数据库分配,默认分配策略为用后即弃,后续可提供复用策略。
  • sequence (13 bits)
    每秒下的并发序列,13 bits可支持每秒8192个并发。

CachedUidGenerator

解决时钟回拨

它不是每次实时获取当前时间而是只启动加载一次,之后通过原子自增实现

那如果启动加载的时间有问题就是老时间呢,它通过每次重启的自增ID解决

所以此方案通过自增的workerID +原子自增时间戳 解决了时钟回拨问题

数据填充时机:

通过异步预生成uid环,提升整体tps性能。

初始化预填充:RingBuffer初始化时,预先填充满整个RingBuffer。

即时填充:Take消费时,即时检查剩余可用slot量(tail - cursor),如小于设定阈值,则补全空闲slots。阈值可通过paddingFactor来进行配置,请参考Quick Start中CachedUidGenerator配置。

周期填充:通过Schedule线程,定时补全空闲slots。可通过scheduleInterval配置,以应用定时填充功能,并指定Schedule时间间隔。

总结:百度CachedUidGenerator 通过于每次启动自增workerID和原子自增时间戳解决了时钟回拨问题;采用离线预生成的方案提升了整体生成的性能。

分布式ID-snowflake小结

主流的基于snowflake的从原理到实现与优化基本介绍完成,简单做下小结。

方案

依赖

峰值TPS

优化方案

原生snowflake

409.6w

无,存在时钟回拨问题

美团leaf-snowflake

zookeeper

409.6w

自动化workerID分配,自旋等待时钟,回拨则报错

百度uid-generator

mysql

600w+

自动化workerId分配,解决时钟回拨问题,缓存环提升了生成性能

其实,目前基于雪花方式两种优化方案基本上可以解决99.99%我们的分布式ID生成了,无论你要业务订单号,还是业务唯一标识;当然从原理角度,我们还有另一种方案号段模式,

再回顾下这个图,此文详细描述了基于UUID的模式下的主流方案及原理,下一篇会讲上半部分“自增ID”模式。

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

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

相关文章

2025年大数据专业证书报考指南:专科学历必看的8大选择​

对于大专学历的同学来说&#xff0c;2025年进入大数据行业是一个充满机遇的选择。大数据领域发展迅速&#xff0c;各类证书能够帮助求职者提升专业能力、增强就业竞争力。其中最推荐的是CDA数据分析师&#xff0c;这个证书适应了未来数字化经济和AI发展趋势&#xff0c;难度不高…

Python爬虫实战:研究Axis Artist模块,构建电商数据采集和分析系统

1. 引言 1.1 研究背景与意义 在大数据时代,互联网上蕴藏着海量有价值的信息,这些信息涵盖了社会、经济、科技等各个领域。高效地从互联网获取数据并进行深度分析,对于企业决策、学术研究、市场分析等都具有重要意义。Python 作为一种功能强大的编程语言,凭借其丰富的库支…

突破大语言模型推理瓶颈:深度解析依赖关系与优化策略

突破大语言模型推理瓶颈&#xff1a;深度解析依赖关系与优化策略当ChatGPT需要5秒才能生成一个回答&#xff0c;当企业级大模型每秒只能处理3个用户请求——这些性能瓶颈的背后&#xff0c;隐藏着大语言模型推理计算中复杂的依赖关系网。在大语言模型推理过程中&#xff0c;依赖…

整理了几道前端面试题

1. 若是有两个数组ar1和ar2&#xff0c;求它们的并集和交集&#xff0c;要怎么做&#xff1f; const ar1 [1, 2, 3, 4]; const ar2 [3, 4, 5, 6];一、求并集 (Union) 目标&#xff1a; 把两个数组合并成一个新数组&#xff0c;新数组包含所有出现过的元素&#xff0c;但每个…

Mac M4环境下基于VMware Fusion虚拟机安装Ubuntu24.04 LTS ARM版

Mac M4环境下基于VMware Fusion虚拟机安装Ubuntu24.04 LTS ARM版 1 下载Ubuntu镜像 在Ubuntu官网下载Ubuntu24.04 LTS的arm版镜像&#xff0c;这里选择ubuntu-24.04-live-server-arm64.iso&#xff0c;支持arm的似乎没有合适的desktop版本&#xff0c;Server版本默认是不带图…

开源与定制化对比:哪种在线教育系统源码更适合教育培训APP开发?

如今&#xff0c;“在线教育系统源码”已经成为许多教育培训机构、创业者甚至传统学校的高频关键词。无论是打造一款在线教育APP&#xff0c;还是开发企业内部培训平台&#xff0c;源码选择都决定了后续的开发效率、产品体验与商业化潜力。 在实际开发中&#xff0c;常见的源码…

中间件的日志分析

将日志文件access.log复制到kali中进行分析使用命令查看文件中各IP的访问次数&#xff0c;依次分析其行为awk { print $1 } access.log | sort | uniq -c |sort -nr172.16.3.189cat access.log | grep 172.16.3.198行为模式分析使用固定弱密码进行身份验证 几乎所有请求都使用用…

【Big Data】云原生与AI时代的存储基石 Apache Ozone 的技术演进路径

目录 一、Apache Ozone是什么&#xff1f; 二、Ozone的诞生背景 三、Ozone的架构设计 1. 分层架构设计 2. Ozone Manager (OM) 3. Storage Container Manager (SCM) 4. DataNode 5. Raft协议应用 四、Ozone解决的关键问题 1. 元数据管理瓶颈 2. 小文件性能问题 3. …

抖音直播礼物弹幕抓取工具:技术实现与功能解析

基于Python的直播间数据采集技术实践一、项目概述基于Python开发的直播间数据采集方案&#xff0c;采用最新签名算法(dysign)实现稳定连接&#xff0c;实时获取直播间各类互动数据&#xff0c;为直播数据分析和互动应用开发提供技术支持。二、核心功能实时消息监控用户进入提醒…

添加地址页面,可以添加复制粘贴,自动识别地址的功能uniapp实现方式

主要用uni.getClipboardData(OBJECT)&#xff0c;更多信息可以到uniapp官网查看以下实现方式 1利用api, 2针对判断优化方案&#xff0c;在线APIhandleConfirm2(){let that this;promisRequest({url: https://wangzc.wang/smAddress,data: {"address": that.…

ESP32 驱动 PWM 舵机为什么必须共地?——从原理到实践全解析

在使用 ESP32 控制 PWM 舵机 的过程中,新手经常遇到一个常见问题:舵机不动、乱动、甚至烧坏芯片。 其中最典型的原因,就是没有正确共地。 很多初学者会疑惑:“外接电池只是给舵机供电,为什么还要把电池的地线接到 ESP32 的 GND 上呢?” 本文将从 信号逻辑、闭合回路、…

细菌基因组genome二代测序数据分析

kraken2去除污染conda create -n kraken2 conda activate kraken2 conda install kraken2 -c bioconda mkdir kraken2_outputkraken2 --db ../../kraken2_db/k2_pluspf_20250402/ --threads 8 --paired 250811_HS67EV0804_R1.fastq.gz 250811_HS67EV0804_R2.fastq.gz --use-nam…

工业网络架构的未来:智慧化工厂中的低延迟与高可靠性设计

1. 引言工业网络正经历从传统有线到无线、从低速到高速的全面升级。某铝箔智慧工厂专注于新能源铝箔的生产&#xff0c;依赖低延迟、高可靠的网络支持实现生产控制与智能管理。本文将探讨某铝箔智慧工厂网络架构设计的关键点及其实施策略。2. 某铝箔智慧工厂的网络挑战多终端接…

Android14 init.rc中on boot阶段操作4

Android14 init.rc中on early-init, init, late-init, early-fs, post-fs阶段详解1 Android14 init.rc的on late-fs, post-fs-data阶段主要操作详解2 Android14 init.rc中启动Zygote详解3 Android14 init.rc中on boot阶段操作4 1 on boot和低内存设备的启动优化 仅在ro.con…

CodeSandbox Desktop:零配置项目启动工具,实现项目环境隔离与Github无缝同步

你有没有过为了跑一个简单的 Demo&#xff0c;花半小时配置环境还失败的经历&#xff1f;比如想测试一个 Vue3 组件&#xff0c;先装 Node.js&#xff0c;结果版本太高和项目依赖不兼容&#xff1b;换低版本又提示 “找不到 python 环境”&#xff1b;好不容易装完依赖&#xf…

人工智能-python-深度学习-经典神经网络AlexNet

AlexNet&#xff08;详解&#xff09;——从原理到 PyTorch 实现&#xff08;含训练示例&#xff09; 文章目录AlexNet&#xff08;详解&#xff09;——从原理到 PyTorch 实现&#xff08;含训练示例&#xff09;1. 发展历史与比赛成绩2. AlexNet 的核心思想&#xff08;一句话…

《sklearn机器学习——指标和评分1》

3个不同的API可供评估模型预测质量&#xff1a; 评估器评分方法&#xff1a;评估器有一个score方法&#xff0c;它给计划解决的问题提供一个初始评估标准。这部分内容不在这里讨论&#xff0c;但会出现在每一个评估器的文件中。 评分参数&#xff1a;使用交叉验证&#xff08;…

人工智能中的线性代数总结--简单篇

numpy库中的dot函数来计算矩阵和向量的点积def matrix_vector_dot_product(a, b):import numpy as npif (len(a[0]) ! len(b)):return -1# 使用tolist()将结果转换为列表return np.dot(a, b).tolist()原始方法def matrix_vector_dot_product(matrix, vector):if len(matrix[0])…

又是全网首创/纯Qt实现28181设备模拟器/rtp视频点播/桌面转28181/任意文件转28181/跨平台

一、前言说明 这个工具前前后后也算是废了不少功夫&#xff0c;最开始是因为28181服务端的组件已经完美实现&#xff0c;对照国标文档看了很多遍&#xff0c;逐个实现需要的交互协议&#xff0c;整体上比onvif协议要难不少&#xff0c;主要是涉及到的东西比较多&#xff0c;有…

安卓逆向(一)Ubuntu环境配置

一、Ubuntu 1、虚拟机 首先准备一个Ubuntu的虚拟机&#xff0c;就随便新建一个就行&#xff0c;我这里使用的是Ubuntu21.04&#xff0c;但是内存跟硬盘大小最好设置的稍微大一点。 2、基础环境 &#xff08;1&#xff09;解决apt-get update报错问题 apt-get是Linux系统中一个管…