存算分离实践:写路径、副本归属与缓存一致性的架构解析
大家好,我是数据库小学妹👋 我踩过的坑,你别再踩。
有个项目我印象很深。业务量涨上来,评审会上两拨人吵了起来。一拨说该上存算分离,云原生都这么干。一拨说这就是换个说法,盘还是那块盘。吵到最后谁也没说清一件事。这两层一旦拆开,数据库里到底哪几件事变了。我当时站后者,我一度当存算分离是营销词。
直到一次扩容。我把存储和计算一起加。加完才发现,卡的从来不是计算,是存储的扩容节奏跟不上业务的读写节奏。那次之后我才去认真拆这套架构。也才明白,当初两拨人各自说对了一半。
先把"分离"的两种说法分开
很多人嘴里的存算分离,其实只是把盘从本机挪到网络存储。盘不在了,数据库还是那一个。这种挪窝解决的是磁盘的可靠性,节点之间该协调还得协调。它和本地盘主从,是同一个问题的两种答案。
真正的存算分离是架构层的事。存储被抽出来,做成一个独立、多副本、分布式的服务。计算节点变成无状态的,随时能销毁重建。这才是云原生数据库那套东西的命题。
判据一条就够。那个计算节点上,还有没有"必须保存、丢了就完蛋"的东西。有,它就不是无状态。没有,才叫真分离。
第一变:日志成了唯一真源
本地盘的写路径是这样的。改一页,先在内存里改,同时写日志。脏页攒着,等下次刷盘,再写回本机磁盘。这套模型里页是主角,日志是配角,用来兜住崩溃。
存算分离把主次调了个个儿。写入时先把日志送到存储层,等多数派确认。页慢慢回放就行,用到的时候再物化。日志成了唯一真源,页只是它算出来的一份投影。
这里有个反直觉的结果。计算节点的本地缓冲池,从"权威数据"降级成了"缓存"。它哪天丢了不致命,重新回放就能长回来。
本地盘: 写内存页 -> 写日志 -> 后台刷脏页到本机磁盘
存算分离: 写日志到存储层 -> 多数派确认 -> 后台回放成页(可延迟物化)
第二变:副本从数据库挪到了存储层
传统做主从,复制是数据库自己干的。主库把 binlog 或 redo 传出去,从库回放。副本保几份、要不等确认,都是数据库层的参数。
存算分离之后,这件事被上移了。存储层自己做多副本和共识。写入要等到多数派落盘,才算提交成功。副本保几份、跨几个可用区,成了存储服务的策略。
结果就是,RPO 和 RTO 的边界挪了位置。你还在翻数据库的复制参数,可决定丢不丢、切多快的,已经不在那儿了。我第一次找这个问题,方向就错了半天。
第三变:缓存一致性成了新瓶颈
两层拆开,就多出一道缝。计算节点本地缓存里那份页,和存储层里那份,可能不一致。怎么判断本地这份还能不能信,就成了绕不开的一步。
主流做法靠一个位点。本地页记着自己对应到哪条日志。只要这条日志已被存储层确认落盘,这份页就可信。省事,但每个节点都要维护这套追踪。
读的代价也跟着变。点查如果本地缓存没命中,就得回存储层取。这一步把延迟从微秒级推到毫秒级。数据量一大,问题会被放大。
| 对比维度 | 本地盘主从 | 存算分离 |
|---|---|---|
| 数据真源 | 本机数据页 | 日志 + 存储层 |
| 提交路径 | 本地写日志 + 刷脏 | 日志跨网络到多数派 |
| 写延迟 | 微秒到毫秒 | 由网络往返决定下限 |
| 读放大 | 命中内存即返回 | 未命中要回存储取页 |
| 副本归属 | 数据库层复制 | 存储层共识 |
| 扩容粒度 | 计算存储一起加 | 计算、存储各扩各的 |
| 单点风险 | 本机磁盘 | 存储服务与网络 |
这张表想说一件事。分离不是白拿的,它拿跨网络的延迟,换两层各自伸缩的自由。
第四变:伸缩从一件事变成两件事
本地盘时代,扩容是一个动作。加机器,存储和计算一起加。便宜在这里,浪费也在这里。你只想多几个只读副本扛查询,却被迫连盘一起买。
拆开之后,伸缩变成两件事。计算层无状态,加只读副本是秒级的。存储层按容量和 IOPS 单独扩,跟计算节点解耦。读多写少的业务只加计算,数据涨了只扩存储。
天下没有单向的好处。两层之间多一根网络,它就成了硬约束。存储层一抖,计算层跟着抖。跨可用区部署时,这段网络延迟必须算进 SLO,不能只算机房内那点。
什么时候不该拆
先说结论,三种情况别拆。延迟极度敏感的别拆,本地 NVMe 是微秒级,网络存储是毫秒级,差一个数量级,对延迟抠到骨头的交易未必值。单机够用、计算与存储同频增长的别拆,两层一起长一起扩,拆开只多一层网络。团队没有平台能力的更别拆,存储层出事,你得看得懂它的日志和副本状态,看不懂等于把命门交给黑盒。
所以判断的核心就一句。看这两层的伸缩节奏,是不是同频。
避坑清单
别把"存算分离"和"分布式"混着讲。分布式切的是数据,存算分离拆的是两层。评审时混用这两个词,方案很容易走偏,最后扩容方向和真实瓶颈对不上。
跨可用区部署前,先把网络延迟算进延迟预算。我见过方案只在同机房测延迟,跨区上线后 P99 直接翻倍。这个数要提前算,不能上线后拿业务去试。
最后一条是我自己搞错的。我第一次做分离架构的容量规划,还是按"计算存储一起加"的老习惯算。我看存储够用,就把计算节点加多了,配额和成本都超了。后来才反过来,先看两层的增长曲线同不同频,再决定各扩各多少。
写在最后
存算分离不是先进性,是一道算术题。收益来自两层伸缩节奏不同频,代价是跨网络的延迟。同频的系统拆开,只多一层损耗。
现实里也不是二选一。像金仓这类国产库,同时有读写分离集群、共享存储集群和分布式形态,路线按业务的伸缩节奏挑就行,不用在阵营之间站队。
你现在这套库,计算和存储的伸缩节奏,是同频还是差着拍?评论区聊聊。
我是数据库小学妹,帮你少走弯路少踩坑,咱们下篇见👋
- 点赞
- 收藏
- 关注作者
评论(0)