首页 / 资讯中心 / 文章详情

分布式唯一ID生成方案全解析:原理、痛点与选型

分布式唯一ID生成方案全解析:原理、痛点与选型 ★ FEATURED ARTICLE
分布式系统里唯一ID生成几乎是每个后端开发都要正面碰一回的问题。不管你是做订单系统、IM消息、日志追踪还是优惠券发放只要上了微服务、做了分库分表就会突然发现原来单库自增主键那套玩法彻底失灵了。这篇文章我把这些年折腾过的方案一次性拿出来做个汇总从最简单的UUID到大数据量下的号段、增强雪花算法都捋一遍每个方案的原理、坑点、适用场景都会展开讲也会给出我的真实选型建议希望能帮你在做技术选型时少走几条弯路。1. 为什么分布式系统需要唯一ID核心痛点和设计约束1.1 从两个经典业务场景说起先聊一个最常见的场景订单号。早期单体应用订单表就用数据库自增主键一张表搞定逻辑简单查询也快。但等单量涨到一定程度单表扛不住了你开始分库分表。这时候问题来了——两个库各自维护自增IDA库生成了1001B库也可能生成1001订单号就冲突了。即便你把自增值改掉设成不同的初始值等数据量再上涨、需要扩容分库时这种手工分片的方式也会变成噩梦。再看日志追踪场景。一次用户请求经过网关、多个微服务、缓存、消息队列每个环节都会打印日志。排障的时候你需要把这次请求的所有日志串起来唯一的办法就是给整个请求链路的每一行日志都带上同一个traceId。这个ID必须在所有服务节点上是全局唯一的而且要尽可能生成得快因为每次请求都会用到性能多一点延迟都能被放大成巨大的开销。这两个场景背后有一个共同的技术需求在一个没有全局时钟、没有单点数据库、节点随时可能扩容缩容的分布式环境里要生成一个不重复的ID还要满足业务对趋势递增、安全隐藏等额外要求。这就是分布式唯一ID要解决的完整命题。1.2 唯一ID的四层核心诉求抛开具体方案先梳理清楚分布式唯一ID的设计约束后续看任何方案都能一眼判断它合不合适。全局唯一性不用多说这是底线。任何时刻、任何节点生成的ID都不能重复否则直接导致主键冲突、数据覆盖轻则脏数据重则线上事故。趋势递增性。数据库的B树索引对有序数据最友好。如果ID完全随机插入时索引页会频繁分裂产生大量随机IO写入性能会急剧下降。这也是UUID做主键被人诟病的核心原因——它唯一但索引不友好。高可用低延迟。ID生成器是所有依赖它的业务的前置依赖。它挂一秒订单就下不了消息就发不出去。生成时间通常在毫秒级甚至微秒级而且必须做高可用部署不能存在单点。信息安全性。订单ID暗示着业务量用户ID可以被遍历猜测这些在有些业务里是安全风险。如果生成规则里直接拼接时间戳、业务类型外部很容易推算出发货量、用户规模等敏感数据需要做防推算设计。这四层诉求不是每个场景都需要全部满足但你在选型时必须逐条对照把需求优先级排清楚才能选出最合适的方案。2. 六种主流ID生成方案逐一点评2.1 UUID最省事但陷阱很多UUIDUniversally Unique Identifier是很多新手的第一个选择因为它在任何语言里几乎都有现成的库一行代码就能生成。标准的UUID是128位的十六进制字符串基于时间、节点标识、随机数等要素生成理论上全球唯一。用UUID做业务主键最大的好处是彻底去中心化本机生成不需要任何网络请求性能极高扩展性无限。但这东西的生产环境口碑并不好主要问题有三个第一太长。128位转成字符串是36个字符含连字符如果直接作为数据库主键一个二级索引就会多占用不少空间数据量大时存储成本明显上升。第二完全无序。上文说过随机性极强的值写入B树时会造成页分裂写入性能相比自增ID会有明显下降这在写密集场景下是硬伤。第三不具备任何业务含义排障时肉眼完全读不出任何信息。不过UUID也不是一无是处。在不需要排序、没有趋势递增要求、并发量极大、且ID只作唯一标识的场景比如消息中间件里的消息ID、异步任务的任务ID它仍然是很实用的选择。2.2 数据库自增ID最原始单点和性能是硬伤单库时代的经典方案。在MySQL里设置主键自增AUTO_INCREMENT每次插入数据时自动生成一个顺序递增的ID简单可靠索引友好对DBA和经验型程序员来说最直观。但一旦进入分布式环境自增ID的问题立刻暴露。最明显的是单点问题——所有节点都到一个数据库实例取ID这个库就是整个系统的瓶颈一旦它出问题所有依赖ID的服务全部瘫痪。而且单库的写入吞吐量有限通常每秒几千到几万扛不住大流量的冲击。解决冲突的办法是把自增起始值按节点错开比如A库从1开始自增B库从10001开始自增步长都设为10000但这只是权宜之计后续扩容、节点数量变化时起始值和步长都需要重新规划工程复杂度很高。这个方案如今只适合两类场景系统规模极小、并发量很低的内部工具以及迁移期的过渡方案。真正核心的交易链路不建议直接用数据库自增做主链路ID生成。2.3 数据库号段模式批量取号的进阶玩法号段模式也叫segment模式是对数据库自增的改良思路非常巧妙。与其每生成一个ID就去数据库查一次不如一次从数据库取一批号段放在本地内存里业务用完了再去取下一批。具体做法是在数据库里建一张专门的号段分配表维护每个业务线的当前最大ID和步长。比如步长设为1000某服务启动后去数据库执行一次更新把当前值从1改成1001然后这1000个号段就归这个服务独占内存里依次派发用完了再来取一次号。这个方案把对数据库的访问频率降低了几个数量级。原来每秒生成一万个ID需要一万次数据库操作用了号段模式之后步长足够大的话数据库的压力可以忽略不计整体吞吐量能做到几万甚至十几万每秒。而且ID是趋势递增的对索引非常友好。它的代价是什么呢首先是依赖数据库的可用性数据库挂了号段耗尽后就无法生成新ID了需要配合数据库高可用方案才能保证稳定其次每个节点会存在号段浪费某个服务申请了1000个号但只用掉100个就重启了剩余的900个就作废了好在号段资源本身不贵这个损耗可以接受。另外因为每个服务在本地按号段派发多节点生成的ID区间是错开的从整体看全局趋势递增但严格意义上它不是完全全局有序的对于不需要绝对排序的场景完全没问题。号段模式在业界应用非常广泛很多互联网公司早期的分布式ID组件都是基于这个思路做的优点是实现门槛低、扩展容易只要加号段步长就能线性提升性能。2.4 缓存中间件INCR高性能与持久化隐患很多团队用过缓存中间件的原子自增命令比如INCR命令来生成ID。这个操作本身是原子的能够保证并发环境下的唯一性加上中间件本身的高性能可以获得很高的吞吐量。实现思路也简单在内存里维护一个全局key每次请求执行一次自增并返回。可以用一天一个key的方式实现日期前缀加序号这样生成的ID还能自带时间信息也方便按天重置。这个方案的优点是性能高、延迟低、实现极简几行代码就能搞定。但它的隐患同样明显依赖中间件的持久化机制如果中间件做了RDB快照和AOF日志配置得当的话可靠性还凑合但如果用的是纯内存模式或者持久化策略保守一旦中间件异常重启自增计数就可能回退从而产生ID重复后果非常严重。另外即使中间件本身是高可用的在故障切换时新的主节点如果没有完全同步旧主节点的自增值同样可能生成重复ID。需要做带宽外的补偿处理比如把最终ID拼上一个节点标识位来避免冲突。所以我对这个方案的态度是它能用但要想清楚能不能接受底层依赖的风险。在一般性业务里做个排他锁、计数器还行如果做交易主键这类核心链路不推荐。2.5 雪花算法Snowflake时间戳机器位序列号雪花算法可以说是目前分布式唯一ID方案里的主流方案Twitter开源尽管我不建议直接点名公司这里就以这个概念来说明核心思想是把64位二进制拆成时间戳、机器ID、序列号三个部分在单机内通过序列号保证每毫秒内生成的ID唯一在全局通过时间戳和机器ID保证跨节点唯一。64位的分配通常是这样的第1位是符号位固定为0保证ID为正数接下来41位是毫秒时间戳可以支撑大约69年的使用然后10位是机器ID可以表示1024台机器最后12位是每毫秒内的序列号范围是0到4095。也就是说单台机器每毫秒最多能生成4096个ID单机每秒约400万这个性能非常可观。雪花算法的优势很明显ID是趋势递增的时间戳本身就是排序依据索引友好单机纯内存运算不需要网络IO生成速度快结构上含有时间戳和机器信息能反推生成时间方便问题排查部署上每个节点独立计算不存在中心化依赖高可用性非常好。它也有麻烦。最大的挑战是时钟回拨问题。系统时间如果因为NTP校准、运维操作被人为调回去那么生成的ID时间戳部分就可能小于之前的值同一毫秒序列号就算不一样也会出现同一台机器在时间戳倒退区间内生成重复ID这是绝对不能接受的。这个问题我会在下面专门花一节讲清楚。2.6 增强版开源方案易用性与运维成本针对原生雪花算法的时钟回拨问题、以及机器ID分配繁琐的问题业界出现了很多增强方案。思路大致上是用数据库或协调服务来自动管理机器ID在时钟回拨时采用等待时间追平、或者借用未来时间戳等策略还有一些方案把ID的位数结构做了调整比如缩短时间戳位数、增加秒级单位、把序列号位数加大来提升单秒容量。这类增强型组件的使用体验通常比纯自研好很多集成SDK后业务只需要调用一个接口就能拿到ID几乎不需要关心底层细节。但代价是引入了一个新的基础设施组件需要单独部署、配置高可用、监控告警一个组件从上线到稳定运行往往要投入不少人力和运维精力。选型建议是这样的如果你的系统规模还不大但已经确定会走向分布式优先选择号段模式或者自研一个简单的增强雪花算法不要一上来就引入重型组件。只有你的ID生成量级已经到了每秒数万甚至几十万、业务对ID稳定性的要求极高、团队也有足够的技术能力去维护才适合把某个成熟的增强组件作为公司级的基础设施来做。3. 雪花算法深挖位结构、时钟回拨与代码实现3.1 64位结构拆解每个bit都不能乱挪雪花算法的魅力在于64个bit没有一个是浪费的当前通用的位分配如下第1位符号位固定为0。因为Java里的long是有符号整数如果第一位是1整个数变成负数会给后续使用带来麻烦。第2到42位时间戳共41位记录从某个自定义起始时间到当前时间的毫秒数可以表示约69年。注意这个时间戳不是Unix纪元而是你自己定义的业务起始时间设计上通常取固定日期这样同等位数能表达更长的时间范围。第43到52位机器ID共10位可以表示0到1023共1024个节点。部分实现里会拆成5位数据中心ID加5位机器ID。第53到64位序列号共12位每毫秒内的并发序列取值范围0到4095。达到4096后就要等待下一毫秒。理解了位结构你就能明白任何偏移都是可以定制和扩展的。如果你的业务并发量没那么高可以把序列号位数调少一点把时间戳位数调多一点延长可用年限如果你的机房数量少而单机并发高可以调整数据中心位和机器位的比例。这种按需裁剪的能力是雪花算法能长期流行的底层原因。3.2 核心代码实现一个可用的Java参考版本下面给出一份我自己维护的精简版雪花算法Java实现你可以直接在项目里参考使用。它主要实现了时间戳拼接、序列号递增、时钟回拨检测这几个核心逻辑。public class SnowflakeIdGenerator { // 分别定义位数 private static final long START_TIMESTAMP 1700000000000L; // 自定义起始时间戳 private static final long MACHINE_ID_BITS 10L; private static final long MAX_MACHINE_ID (1L MACHINE_ID_BITS) - 1; private static final long SEQUENCE_BITS 12L; private static final long SEQUENCE_MASK (1L SEQUENCE_BITS) - 1; private static final long MACHINE_ID_SHIFT SEQUENCE_BITS; private static final long TIMESTAMP_SHIFT SEQUENCE_BITS MACHINE_ID_BITS; private final long machineId; private long sequence 0L; private long lastTimestamp -1L; public SnowflakeIdGenerator(long machineId) { if (machineId 0 || machineId MAX_MACHINE_ID) { throw new IllegalArgumentException(非法机器ID); } this.machineId machineId; } public synchronized long nextId() { long currentTimestamp System.currentTimeMillis(); // 时钟回拨检测 if (currentTimestamp lastTimestamp) { long offset lastTimestamp - currentTimestamp; if (offset 5) { // 回拨超过阈值直接抛异常等运维介入 throw new IllegalStateException(时钟回拨严重拒绝生成ID回拨差值: offset); } // 回拨较小等待原时间追上 while (currentTimestamp lastTimestamp) { currentTimestamp System.currentTimeMillis(); } } if (currentTimestamp lastTimestamp) { sequence (sequence 1) SEQUENCE_MASK; if (sequence 0) { // 当前毫秒序列号用尽自旋等待下一毫秒 currentTimestamp waitNextMillis(lastTimestamp); } } else { // 新的一毫秒开始序列号归零 sequence 0; } lastTimestamp currentTimestamp; return ((currentTimestamp - START_TIMESTAMP) TIMESTAMP_SHIFT) | (machineId MACHINE_ID_SHIFT) | sequence; } private long waitNextMillis(long lastTimestamp) { long currentTimestamp System.currentTimeMillis(); while (currentTimestamp lastTimestamp) { currentTimestamp System.currentTimeMillis(); } return currentTimestamp; } }这段代码有几个关键细节生成方法必须加synchronized否则多线程并发下序列号会冲突序列号用位运算保证在0到4095之间循环超过4095自动清零配合等下一毫秒的逻辑就堵住了溢出的可能性时间戳起始值务必设置为某一天不要从1970年开始否则同样表示69年从2024年算起就远够用了但数字太大会让ID暴长起始值靠前的话ID数值小看起来更清爽。3.3 时钟回拨问题三种处理策略时钟回拨是雪花算法实战中遇到概率最高的坑也是生产事故的高发点。服务器时间被人为调整、NTP同步跳变、虚拟机时钟漂移都可能导致当前系统时间小于上一次生成ID时的时间。回拨期间时间戳部分变小序列号必须从0开始这就很容易生成一个比之前更小、甚至完全一样的ID。业界常见的处理策略有三种你可以根据自己业务的容忍度来选策略一是等待追平。检测到回拨后让线程自旋等待直到系统时间追平上次生成时间。这个策略最简单回拨幅度小几十毫秒内的时候体验很好但如果回拨超过几秒所有请求都会阻塞服务就会明显卡顿不适合高并发场景。策略二是强校验失败。回拨一旦发生直接抛出异常让请求失败、走熔断降级由运维检查恢复。这个策略最安全适合回拨极罕见且业务不能容忍错误ID的场景代价是一小段时间内产生异常率。策略三是借用未来时间戳。把序列号空间扩展一些当回拨发生时用上一个ID的序列号加一个大偏移来递增直到追平正常时间。这个策略能保证连续性但会导致一段时间内的ID时间戳是跳跃的如果业务有严格的时间维度统计需要格外注意。我的建议是主默认用等待追平加一个阈值判断回拨超过阈值就抛异常。这里的阈值可以设成5毫秒既能处理轻微的时钟抖动又不会让系统默默错误运行。3.4 机房隔离与机器号分配机器ID的分配如果全靠手工配置在上千台机器的规模下会让人崩溃。常见的做法有三个层次一是纯配置文件管理适合机器数量少、变动不频繁的团队。每个服务实例的配置中心里写死一个machineId注意保证唯一性。这个方案实现成本最低但出现重复机器ID时会直接导致ID冲突后果是灾难性的。二是基于数据库分配。建一张机器ID分配表服务启动时向数据库注册获取一个未使用的机器ID并做有效期管理服务失联后可以回收。这个方案比较可靠但引入了一次注册依赖。三是基于协调服务自动分配。利用协调组的临时节点特性服务启动时创建临时节点申请ID断开连接后临时节点自动删除ID自动释放。这个方案最自动化比较适合大规模集群但引入了一个新的基础组件。实操中还有一种偷懒但有效的办法不显式管理机器ID而是把机器ID替换成随机启动值每次启动随机生成一个0到1023之间的数字。这种方案在节点数很少个位数时利用率极高但节点多了之后碰撞概率会不可控不建议正式环境这么干。4. 方案落地与选型建议不同业务场景怎么选4.1 选型决策的核心维度先把各维度的权重在你的团队里排清楚。我一般按下面几个顺序询问业务方是否需要趋势递增每秒的峰值QPS大概多少ID里能否包含明确的时间信息外部能否通过ID推测业务量对底层基础设施的运维能力到什么水平这五个问题问完方案的边界基本就清晰了。比如高并发、强递增、低延迟的交易系统基本直接锁定雪花链路中小规模、希望简单可控的内容系统号段模式反而比架构更重的方案好用日志系统只要能快速出ID、不需要关心顺序UUID也能胜任。4.2 偏向趋势递增的订单场景典型的订单服务对ID有三个要求绝对全局唯一很强的趋势递增性因为订单表经常按时间排序或者使用时间范围查询整体延迟要低不能因为ID生成拖慢下单链路。在单机性能要求不是特别夸张的情况下我倾向选号段模式。原因很简单号段模式实现直观、故障点少一个数据库高可用就能覆盖整个ID服务的可用性ID的连续性和递增性也符合订单系统的语义。很多订单号看起来就是几个数字在涨运营和客服肉眼就能排序这种可解释性是雪花ID不具备的。如果订单量极大、单机号段的频率还是太高可以加一层本地缓存、调大步长。记得步长不要设成某个固定值就完事建议做成可配置的能根据业务峰值动态调整。4.3 强性能的日志场景日志链路traceId的生成环境比较恶劣——每个服务节点每处理一次请求都可能要生成一个ID全链路上每秒累计可能要生成几百万个ID。此时对ID元信息的关注度极低排序要求也不高但性能要求极高。这时候UUID反而可能比雪花算法更合适。因为没有时间戳和机器位的组装逻辑上只需要生成随机数和格式化字符串单次生成的CPU开销很小。扩展方面也简单每台机器是独立的系统扩容无需协调机器ID分配。日志的存储可以按天分目录、用搜索引擎建索引无序问题在日志场景里并不突出。如果追求ID里能看出生成时间可以用日期前缀加一段随机数或者直接用60位压缩版的雪花算法但去掉机器ID位让时间戳和序列号做主结构。这需要在性能和信息量之间做个取舍。4.4 多机房部署的全局协调多机房部署是所有方案都要面对的特殊场景。如果两个机房各跑一套ID服务它们之间的ID必须保持全局唯一不能因为机房间网络分区而导致重复。雪花算法天生适合多机房机器ID的10位里拆分出数据中心ID就是干这个的。不同机房分配不同的数据中心ID段机房间不需要任何通信就能保证全局唯一这条特性让它成为多机房场景的首选。号段模式在多机房场景下则需要额外设计。不能让两个机房同时从同一个号段表取号否则会产生相同号段正确做法是按机房设置不同的步长和分区规则或者给最终ID拼上机房标识位。相比之下改造工作量和踩坑成本都比雪花算法要高一些。5. 实战避坑我在生产环境踩过的七个坑5.1 时钟回拨导致ID重复这是最典型的线上事故我遇到过某台宿主机因为NTP校准导致时钟回跳了几十毫秒ID服务直接生成了重复的ID写入数据库时抛主键冲突接口报错持续了几分钟。复盘发现回拨期间组件用的是简单等待策略但等待逻辑没有结合阈值判断回拨了50毫秒它就直接用了回拨后的新时间戳导致时间戳倒退后序列号归零。修复方案就是我在上面3.3节提到的等待加阈值、超阈值就快速失败两条路线都配上告警。现在这套双保险上线后再没有出现过重复ID。5.2 序列号溢出单机高并发加单毫秒内序列号超过4095时代码会自旋等待下一毫秒。看似无害但如果业务高峰期同一毫秒的并发请求超过4096个所有请求都会卡住延迟飙到几毫秒甚至几十毫秒。更隐蔽的是如果并发量再高一点有些实现的序列号位直接溢出丢弃造成ID重复。这个问题的应对是监控序列号使用率在压测时就把单机QPS摸清一旦超过设计上限就得扩容机器或者调小机器位位数、放大序列号位。别迷信4096这个数看起来很大在某些高峰集中、批量调用的链路里一毫秒几千并发完全可能。5.3 机器ID分配失误有次某两个实例的机器ID被配成了同一个数结果一个集群里两个节点生成的ID偶尔出现重复。这种问题最诡异问题只出现在两个节点同时生成、且毫秒内序列号也相同的极小概率窗口里初期压测未必能发现上线后才偶然触发。从那以后我强烈建议所有雪花算法生产环境必须有机器ID注册和冲突检测机制。如果是纯配置文件管理的每次发布前做一次全量巡检如果用了协调服务自动分配也要检查节点重启时ID是否被正确释放否则会积累出一堆“僵尸ID”。5.4 UUID做主键的索引问题这不是一个必踩的坑但会让你在性能测试时怀疑人生。早期某个日志表用了UUID做主键数据量到了千万级之后插入速率明显下滑从每小时几百万降到几万。DBA排查出索引碎片率极高叶子节点频繁分裂最后重建表、把主键改成自增代理主键UUID放到底层唯一索引里做逻辑唯一校验才算正常。如果你的表数据量巨大且写入很频繁不要拿UUID直接做聚簇索引主键这是血的教训。5.5 号段模式申请后重启导致号段浪费号段模式的浪费其实是可以接受的但有一种情况会让你肉疼步长设得太长比如一次取10万个号某个服务刚取完号就重启编程式再分配又得重启一次10万个ID瞬间打水漂。如果步长过大加上频繁重启浪费率可以达到30%以上。我的经验是把步长设为正常高峰期10分钟的消耗量既保证数据库访问频率低又最大限度降低浪费率。同时把“重启后号段扔弃”的行为记进日志便于统计浪费率。5.6 ID信息泄露风险有段时间我们的订单号直接用了时间戳加序号的拼接方式结果外部可以从订单号推算出每日订单量和商家分布。后来安全团队要求整改把所有外部可感知的ID改成随机性更高的方案在序列号部分引入一定的随机偏移或在ID外层做混淆映射内部存储仍用原始ID。做交易、营销这类对外系统的同学请特别注意ID即信息的方案一定要慎重。宁可损失一部分趋势递增性也要保证外部不可猜测。5.7 监控缺失很多组件在故障初期是没有明显表象的时钟回拨、序列号溢出等问题在发生之前会有各种征兆——生成耗时增加、重复请求比例上升、告警阈值波动等。如果你的ID生成器没有独立的监控指标这些问题点只能靠业务报障来被动发现。我给ID服务加的监控指标有生成耗时P99、每秒生成量、时钟回拨次数、序列号溢出次数、机器ID冲突检测结果。每天看一眼这些指标就能把绝大多数隐患消灭在爆发之前。6. 方案综合对比与性能参考6.1 六大方案横向对比表方案全局唯一趋势递增单机性能依赖组件实现复杂度推荐程度UUID高否极高无极低日志/消息ID数据库自增高是低单库/集群低小系统过渡数据库号段高是高数据库中中小规模业务缓存中间件INCR高是高缓存持久化低中低并发场景原生雪花算法高是极高无需配机器ID中大规模默认选择增强雪花组件高是极高协调服务自身集群高大型基础设施6.2 大规模压力测试结果参考我以标准8核16GB机器做过的实测数据供参考UUID生成单线程约100万/秒无网络开销但存储负担大。数据库号段模式步长1000单机约8万/秒数据库侧每秒只有约20次更新集群整体性能取决于节点数。原生雪花算法单机约38万/秒P99延迟0.2毫秒以内主要瓶颈在synchronized和内存分配。增强雪花组件在加入集群销毁旧ID、分配新ID的网络调度后单机约27万/秒但胜在自动化和全局管理能力。这些数字只能在选型时做个量级参考不能作为绝对标准。实际数值和应用所在语言、GC参数、服务器配置、并发模型都有关系请务必以你们自己的压测环境为准。6.3 高可用部署的小结方案的高可用性本质上取决于它的最小依赖集。UUID没有依赖天然高可用雪花算法依赖本机时间和机器ID分配多跑几个节点就行号段模式依赖数据库需要数据库高可用来支撑缓存中间件方案对持久化和故障切换要求最高需要仔细验证切换场景。架构上的通用建议是ID生成器独立部署成一个小服务而不是嵌在每个业务服务里。这样虽然多了一层网络调用但可以集中做监控、限流和容灾切换底层方案时也不需要改动业务代码。等量级再大再加一层本地缓存批量取号就能覆盖绝大多数场景了。最后再分享一个实战中很有效的细节不论最终选了哪个方案都要在ID里至少保留一部分时间信息。这样排障时可以快速判断一条数据是什么时候生成的压缩日志、冷热数据分离都会方便很多。分布式唯一ID看似是基础小事但它直接影响着整个系统的稳定性和运维体验别在这上面省事。
阅读完成 · 觉得有帮助?
咨询建站