哈尔滨网站建设美丽网站开发 搜索

张小明 2026/1/9 8:49:16
哈尔滨网站建设美丽,网站开发 搜索,免费制作电子贺卡的app,利用wordpress实现分类筛选在分布式系统的架构设计中#xff0c;分库分表是一个无法回避的话题。当数据量达到一定规模#xff0c;单库单表已经无法承载业务压力时#xff0c;我们就需要考虑将数据分散到多个数据库和多个表中。然而#xff0c;这种分散带来了一个新的挑战#xff1a;如何在分库分表…在分布式系统的架构设计中分库分表是一个无法回避的话题。当数据量达到一定规模单库单表已经无法承载业务压力时我们就需要考虑将数据分散到多个数据库和多个表中。然而这种分散带来了一个新的挑战如何在分库分表的场景下生成全局唯一且有序的主键。这个问题看似简单实际上却涉及数据库底层原理、分布式系统设计、并发控制等多个技术领域。这篇文章就深入探讨分库分表场景下的主键生成策略从最基础的UUID方案到经典的雪花算法再到更具创新性的主键内嵌分库分表键方案为你提供一套完整的解决方案。1. 分库分表为什么不能用自增主键在深入讨论主键生成策略之前我们需要先理解分库分表的基本概念。严格来说分库分表包含了三个层面的拆分分数据源、分库和分表。在实际生产环境中这三者往往会组合使用。举个例子某电商平台的订单表采用了分库分表策略使用了6个主从集群每个集群包含5个数据库每个数据库又拆分为64张表整体规模达到了6乘以5乘以64的拆分粒度。当然根据实际的数据规模和读写压力也可以采用更简单的拆分方式比如共享一个主从集群只进行分库或者只进行分表。当系统采用分库分表后传统数据库的自增主键就会遇到问题。在单库单表的场景下我们可以直接使用数据库的自增主键功能比如在MySQL中创建表时指定AUTO_INCREMENT属性。-- 订单表建表语句使用自增主键 CREATE TABLE order_info ( id BIGINT PRIMARY KEY AUTO_INCREMENT, -- 自增主键 buyer_id BIGINT NOT NULL, -- 买家ID order_amount DECIMAL(10,2) -- 订单金额 )然而在分库分表的场景下这种自增主键机制就会失效。假设我们按照买家ID对2取模的方式将订单表拆分为两张表分别是order_info_0和order_info_1。如果这两张表都依赖各自的自增机制生成主键那么两张表可能会生成相同的ID。比如两张表各自插入第一条记录时生成的ID都是1这就导致了主键冲突。因此在分库分表场景下我们需要设计一个能够生成全局唯一ID的机制。这个机制需要满足两个核心要求首先生成的ID必须是全局唯一的不能出现重复其次理想情况下ID应该保持递增特性因为递增与否会显著影响数据库的插入性能。此外由于采用分库分表的系统通常数据量巨大意味着并发量也很高所以主键生成方案还需要考虑如何支持高并发场景。2. 面试引导在实际的技术面试中如何将话题引导到主键生成这个技术点上也是一门学问。如果你在简历中提到了分库分表的项目经验面试官很可能会主动询问主键是如何生成的。如果在面试过程中被问及数据库自增主键的相关问题你可以主动提及自增主键在分库分表场景下的局限性这样面试官自然会追问分库分表场景下的主键生成方案。当面试官问到这些问题时如何抓住机会展现自己的技术深度呢这需要我们提前做好充分的准备。具体来说需要深入理解市面上常见的主键生成策略准备一个有亮点的、具备微创新性的主键生成方案同时还要记住一些可行的优化思路。接下来我们将逐一分析这些内容。3. 常见主键生成策略当面试官询问分库分表中如何解决主键问题或者如何设计一个发号器时他们通常期望你能够回答出几种常见的主键生成思路主要包括UUID、数据库自增和雪花算法。下面我们逐一深入分析这些方案。3.1 基础方案UUIDUUID是最直接的主键生成方案也是面试中必须能够回答出来的基础策略。虽然UUID实现简单但如果我们想在面试中脱颖而出就需要深入分析UUID的弊端。UUID主要有两个明显的缺陷。第一个是长度问题UUID通常占用36个字符存储空间较大不过在实际采用UUID的场景中这个缺点通常不是主要考虑因素。第二个缺陷更为关键那就是UUID不是递增的这个弊端是面试时需要重点阐述的内容。3.1.1 页分裂要讲清楚UUID不是递增的弊端我们需要先理解为什么数据库倾向于使用自增主键。这里的关键词是页分裂。数据库的B树索引结构中数据按照主键大小有序存储在叶子节点上。当我们需要插入一条新记录时如果这条记录的主键值恰好位于某个已满的叶子节点中间就会触发页分裂操作。比如图中所示当尝试在23之后插入25时由于叶子节点已经放满数据库不得不将这个节点分裂成两个节点分别存储2021和222325。更严重的是这种分裂可能会引发连锁反应从叶子节点一直向上分裂到根节点导致整个树结构都需要调整。因此UUID最大的缺陷在于它产生的ID不是递增的。我们倾向于在数据库中使用自增主键是因为自增主键可以迫使数据库的B树朝着一个方向增长新数据总是追加到树的末尾避免了中间节点的分裂从而获得最佳的插入性能。而UUID生成的ID在整体上可以看作是随机的这会导致数据频繁地插入到页的中间位置引起更加频繁的页分裂操作。在极端情况下这种分裂可能引发连锁反应整棵B树的结构都会受到影响严重影响插入性能。3.1.2 顺序读除了页分裂的问题我们还可以从另一个角度解释为什么要使用自增主键这个角度就是顺序读。自增主键还有一个重要优势就是数据会有更大的概率按照主键大小有序存储两条主键相近的记录在磁盘上的物理位置也是相近的。在进行范围查询时我们能够更加充分地利用磁盘的顺序读特性大幅提升查询性能。相比之下使用UUID作为主键时由于ID是随机的相近逻辑的数据在物理存储上可能相距很远无法利用顺序读的优势。3.1.3 数据的物理存储如果你希望在面试官面前展现更深入的数据库知识可以进一步解释数据库页分裂的具体机制这里可以用MySQL的InnoDB引擎来举例说明。InnoDB引擎中每个数据页按照主键大小有序存储数据行。假设现在有一个数据页存储了主键为15、16、17、19、20、21的六行数据并且这一页已经放满了。此时需要插入一条主键为18的记录InnoDB引擎会发现当前页已经无法容纳这条新记录于是不得不将原本的页分裂成两页比如将15、16、17放到一页19、20、21放到另一页然后将18插入到第一页中。这种页分裂会造成一个严重问题虽然从逻辑上看存储15、16、17的页和存储19、20、21的页是相邻的两个页但在磁盘的物理存储上它们可能相距很远。这会导致后续的范围查询需要频繁地进行磁盘寻道严重影响查询性能。3.2 数据库步长自增方案除了UUID方案还有一种常见的方案也叫做自增不过这种自增比较特殊它是设置了步长的自增。我们可以通过一个具体例子来说明这种方案。假设经过分库分表后我们有16张表那么可以让每张表按照不同的步长来生成自增ID。比如第一张表生成1、17、33、49这样的ID序列第二张表生成2、18、34、50这样的ID序列以此类推每张表的起始值不同但步长都是16。这种方案的最大优势在于实现简单应用层基本不需要做任何额外工作只需要在创建表时指定好不同的起始值和步长即可。虽然生成的ID并不是严格全局递增的但在单张表内部ID肯定是递增的这在一定程度上保证了插入性能。这个方案的性能主要取决于数据库本身的性能应用层无需过多关注。3.3 雪花算法除了UUID和数据库自增雪花算法是分布式场景下最经典的主键生成方案。需要注意的是在当前的技术面试环境中仅仅答出雪花算法可能已经不够突出我们需要在理解雪花算法的基础上找到更多的亮点。雪花算法的核心思想并不复杂关键在于分段设计。雪花算法采用64位来表示一个ID其中1位保留未使用41位表示时间戳10位作为机器ID12位作为序列号。这种设计保证了ID的唯一性时间戳是递增的不同时刻产生的ID肯定不同机器ID是不同的同一时刻不同机器产生的ID肯定不同同一时刻同一机器上可以通过序列号来区分不同的ID。基本解释清楚之后我们可以从多个方向来展现技术深度你可以根据自己掌握知识的程度来选择合适的方向。3.3.1 亮点一灵活调整分段设计第一个方向是深入讨论每个字段的含义和长度关键点是根据实际需求自定义各个字段的含义和长度。大多数情况下如果自己设计类似的算法每个字段的含义和长度都是可以灵活控制的。比如时间戳的41位可以调整得更短或更长39位也能表示十几年对于大多数业务场景来说已经足够。机器ID虽然名称上是机器ID但实际上指的是算法实例而不是物理机器。比如一台物理机器可以部署多个进程每个进程的机器ID是不同的或者进一步细分机器ID的前半部分表示物理机器后半部分可以表示该机器上用于产生ID的进程、线程或协程。甚至机器ID也可以不表示机器而是引入特定的业务含义。序列号的长度同样可以根据实际并发需求进行调整。总结来说雪花算法可以看作是一种设计思想借助时间戳和分段机制我们可以自由切割ID的不同比特位赋予其不同的含义灵活设计符合自己业务场景的ID生成算法。3.3.2 亮点二序列号耗尽的处理策略无论怎么设计雪花算法序列号长度都有可能不够用。比如标准的12位序列号在并发量极高的场景下有可能在某个特定时刻同一台机器上的序列号全部用完。显然理论上确实存在这种可能性所以我们需要准备解决方案。解决思路其实并不复杂。如果12位不够用可以增加序列号的位数这部分位数可以从时间戳中拿出来。如果还不够可以让业务方等待到下一个时间戳时间戳变化后自然又可以生成新的ID了这实际上是一种变相的限流机制。一般来说可以考虑加长序列号的长度比如缩减时间戳的位数将节省出来的位数分配给序列号。当然也可以更直接地将64位的ID扩展为128位甚至更多这样序列号就可以有三四十位即便是超大规模的系统也不可能用完。不过彻底的兜底方案还是要有的。我们可以考虑引入类似限流的做法在当前时刻的ID已经耗尽之后让业务方等待下一个时间戳。由于时间戳通常是毫秒级的业务方最多只需要等待一毫秒。这里面试官可能会继续追问让业务方等待会有什么问题确实让业务方等待确实是一个非常不妥的方案因为这可能导致大量业务线程或协程阻塞导致线程池或协程池耗尽。不过如果是偶发性的序列号不够问题不大因为阻塞的业务方很快就能拿到ID。如果序列号耗尽不是偶发性的而是长期存在的问题那么就需要考虑从业务角度进行切割不同业务使用不同的ID生成器不要共享。或者最终还是采用96位或128位的ID一劳永逸地解决问题。3.3.3 亮点三数据堆积问题的解决假设有这样一个场景你的分库分表策略是按照ID对64取模来进行的如果业务非常低频以至于每个时刻都只生成了尾号为7的ID那么是不是所有数据都会分到同一张表中呢确实会出现这种情况不过解决方案也很简单。第一种方案是在每个时刻使用随机数作为序列号的起点而不是每次都从0开始计数。第二种方案是使用上一个时刻的序列号作为起点比如上一个时刻的序列号只增长到5那么下一个时刻的序列号就从6开始。如果上一个时刻的序列号已经很大了就可以退化为从0开始。看起来第一种方案比较合理常规但是相比之下第二种实际上更加可控性能也更好。因为在低频场景下很容易出现序列号几乎没有增长的情况从而导致数据在经过分库分表后只落到某一张表中。为了解决这个问题可以让序列号部分不再从0开始增长而是从一个随机数开始增长。还有一个策略是序列号从上一时刻的序列号开始增长但如果上一时刻序列号已经很大了就可以退化为从0开始增长。这样比随机数更可控性能也更好。3.4 进阶方案主键内嵌分库分表键到这里其实前面的回答已经颇具亮点已经可以让面试官对你刮目相看了。接下来我们还可以更进一步让面试官加深印象直接把对技术深度的追求做到极致。这里秀才直接给出一个更具创新性的方案主键内嵌分库分表键。其实分库分表之后最麻烦的就是分库分表的键和主键并不是同一个。比如在C端订单的分库分表中我们可以采用买家ID来进行分库分表。但在一些业务场景中比如查看订单详情可能是根据主键或者订单编号来查找的。这里我们可以考虑借鉴雪花算法的设计思想将主键生成策略和分库分表键结合在一起也就是说在主键内部嵌入分库分表键。例如我们可以这样设计订单ID的生成策略假设分库分表使用的是买家ID的后六位。第一段依旧采用时间戳第二段换成买家ID的后六位第三段采用随机数。在一般情况下我们都是用买家ID来查询对应的订单信息。但在其他场景下比如我们只有一个订单ID这时候可以取出订单ID中嵌入的买家ID后六位来判断数据存储在哪个库、哪个表。类似的设计还有答题记录按照答题者ID来分库分表但答题记录ID本身可以嵌入这个答题者ID中用于分库分表的部分。这一类解决方案的核心思想是不拘泥于雪花算法每一段的固定含义。比如第二段可以使用具备业务含义的ID第三段可以自增也可以随机。只要我们最终能够保证ID生成大体上是全局递增的并且是独一无二的就可以。3.4.1 ID递增性假如面试官进一步追问你这个方案能够保证主键严格递增吗这个确实是保证不了的但它能够做到大体上是递增的这样效果其实并不怎么影响。比如同一时刻如果有两个用户来创建订单其中用户ID为876543的先创建用户ID为123456的后创建那么很显然用户ID为123456的会产生一个比用户ID为876543更小的订单ID。又或者同一时刻一个买家创建了两个订单但第三段是随机数第一次随机到567第二次随机到234那么显然第一次产生的ID会更大。但是这并不妨碍我们认为随着时间推移后一时刻产生的ID肯定要比前一时刻产生的ID要大。这样一来虽然性能比不上完全严格递增的主键但比完全随机的主键要好得多。3.4.2 ID唯一性如果面试官进一步追问这个方案能不能保证ID唯一又该怎么回答呢同样这个方案也不能保证00%的绝对唯一。其根本原因就在于ID的第三部分我们引入了随机数。既然是随机理论上就存在两次生成同样数字的可能。不过我们要知道这种情况在现实中发生的概率是微乎其微的。一个冲突ID的产生需要同时满足几个的条件必须是同一个用户在同一毫秒内发起了两次订单创建并且这两次请求生成的随机数部分还必须完全一致。我们可以从两个角度来分析这个概率从业务角度看一个正常用户在同一毫秒内手动下两个订单这在操作上几乎是不可能的。如果说是恶意攻击者那他们的订单失败了也无所谓。从数学角度看即便我们考虑共享账号等特殊情况真的有用户在同一毫秒发起了两个请求那也要看随机数是否会碰撞。假设我们的随机数范围是0到10万那么两次都抽到同一个数字的概率也只有十万分之一。所以这是一个概率极低、但理论上存在的问题。关键在于我们如何应对它。这个解决方案非常成熟核心就是重新生成主键。具体操作是我们依赖数据库的主键唯一性约束。当我们的程序插入数据时如果数据库返回了主键冲突的错误说明这个极小概率事件真的发生了。此时我们的代码逻辑会捕获这个特定错误立刻重新生成一个新的ID然后再次尝试插入。这个过程对用户是完全透明的。3.5 发号性能优化在掌握了前面几种主键生成策略之后如果希望进一步提升系统在极端并发下的稳定性可以将思考范围从“如何设计一个 ID”扩展到“如何让 ID 服务在大规模场景中持续高效运行”。在实际生产环境里一个发号体系往往不仅依赖于算法本身还需要在获取流程上做工程化优化以抵御瞬时流量冲击、降低网络往返次数以及减少数据库更新压力。这一类优化并不改变 ID 的结构但能够显著提升服务的整体吞吐能力通常会从以下几个方面协同组合。首先将 ID 的申请粒度从单个扩展为一段使得调用方一次拿到一整批可用区间在本地按需消耗。这样可以将原本的高频访问压缩成低频事件一个批次可能抵消数百到上千次真实请求从根本上减轻发号服务的负载。其次是将取号操作前置化。业务端在真正需要之前就准备好一定数量的可用 ID当本地余量下降到阈值时异步补齐下一段。这样在绝大多数情况下业务线程无需等待发号器响应延迟基本可视为零。只有在缓冲耗尽且新段尚未到达的极端情况业务才会短暂阻塞。此外为减少同一时刻大量线程同时访问发号器带来的资源浪费可以在客户端加入类似 singleflight 的协作逻辑某一时间窗口内如果出现多个取号需求仅由一个线程代表整个进程发起请求其他线程等待即可。进一步的优化是让代表线程在获取时“多取一点”在未来的短时间窗口内直接满足后续线程的请求。在此之上为了避免进程级缓存的锁竞争还可以为各个线程建立更细粒度的局部缓存区。当线程从全局段中领取一个较小的片段存放在自己的本地缓冲后其后续的 ID 消耗都不再涉及进程级同步结构从而避免争抢提高整体并发能力。最终形成远端服务、进程缓冲、线程缓冲的多级体系使系统在峰值流量下依然保持平稳。这一方案的核心思想是通过分层缓冲、协同调度和局部化分发将原本集中式的获取过程解耦拆分使真正与发号器交互的请求数量被压缩到极低。它并不依赖某一种具体算法而是一套兼容所有生成策略的工程机制适用于绝大多数对稳定性、低延迟和高并发具有要求的业务场景。4. 小结从单库单表的自增主键到分库分表场景下的全局ID生成这不仅是一个技术选型问题更是对系统架构理解深度的体现。UUID虽简单但牺牲了性能数据库步长自增折中实用雪花算法经典但需灵活调整而主键内嵌分库分表键的方案则将设计思维推向了极致。面试中掌握这些方案的原理只是基础真正的亮点在于你能否理解B树页分裂的底层机制能否根据业务场景灵活设计分段策略以及能否在唯一性、递增性与实现复杂度之间找到最优平衡点。记住没有完美的方案只有最适合当前业务的方案——这正是分库分表这个看似简单的主键问题却能够区分出初级与资深工程师的一个重要原因。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

男女做暧昧试看网站做网站公司好

网络安全与NIS、NFS、RFS相关知识解析 1. 网络安全基础操作 在网络环境中,保障系统安全至关重要。以下是一些常见的网络安全操作和工具。 1.1 消息处理与日志记录 消息可以通过不同方式处理,例如发送到文件、特定用户登录的终端,或者发送到远程系统上运行的另一个syslog…

张小明 2026/1/6 3:14:49 网站建设

网站建设的品牌个人免费网页

第一章:智能Agent的Docker监控告警在现代云原生架构中,Docker容器的稳定性直接影响服务可用性。为实现对容器运行状态的实时感知与异常响应,部署具备告警能力的智能监控Agent成为关键实践。该Agent可周期性采集容器的CPU、内存、网络I/O及进程…

张小明 2026/1/6 4:13:10 网站建设

改变网站的域名查询收录

🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…

张小明 2026/1/9 0:16:15 网站建设

小说网站的网编具体做哪些工作网站备案资料查询

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个交互式学习模块,用可视化流程图展示CUDA作为GPU计算平台与cuDNN作为深度学习加速库的层级关系。包含:1) GPU硬件层 2) CUDA并行计算层 3) cuDNN优化…

张小明 2026/1/9 11:43:42 网站建设

广州门户网站建设方案如何设计与制作网页

Linly-Talker头部运动随机性增强,模拟真实人类小动作 在虚拟主播的直播间里,你有没有注意到这样一个细节:当数字人说出“你觉得呢?”时,它轻轻抬起下巴、微微歪头——那一瞬间,你真的觉得它在等你回应&…

张小明 2026/1/9 9:50:37 网站建设

营销型网站的付费推广渠道网页设计的合适尺寸是多少

我国工业机器人产量第一,应用广泛。产业规模全球领先:我国已成为全球最大机器人生产国,产量实现跨越式增长,从2015年的3.3万套跃升至2024年的55.6万套;应用深度与广度显著提升:工业机器人已覆盖国民经济71个…

张小明 2026/1/9 8:56:06 网站建设