跳转到内容

SCADS — 用户涨一万倍也不改应用的存储愿景

待复核

SCADS(Scalable Consistency Adjustable Data Storage)是 Berkeley RAD Lab 在 CIDR 2009 提出的一套面向社交网站的分布式存储愿景:用户从一千涨到一千万时,应用代码不用改、人均成本不涨、单次请求延迟也不该变——论文把这叫 data scale independence(数据规模无关)。

日常类比:像开连锁奶茶店。你不该每多开十家店就重写一遍收银系统;你该提前说清「出杯要在 90 秒内」「库存最多落后 10 分钟」,让后台按 SLA 自动加减店员和货架。SCADS 想给 Web 2.0 存储做这件事。

它不是又一个「只有 get/put」的 key-value 店,也不是完整 SQL 数据库,而是夹在中间:比 Dynamo/Bigtable 查询更丰富,比传统并行库 更敢砍 ad-hoc 查询与强一致,换可预测延迟。

论文强调:社交图是「毛球」(hairball)——人人可能连人人,很难切成互不往来的干净分片;再叠加读多写突增(万圣节后狂传照片),传统「先上更大机器、再手搓分片」会反复推倒重来。

不理解 SCADS,下面这些事都不好串起来:

  • 为什么 Facebook 一类站点宁可接受「墙贴了几秒才全网可见」,也要堆缓存和分片——性能优先于单副本一致
  • 为什么「最终一致」对开发者仍太糊:Craigslist 搜到新帖晚 5 分钟能接受,Facebook 刚发的墙贴看不见就不能忍——需要可声明的时间界
  • 为什么纯 key-value 写社交功能很痛(缺安全 join),完整 SQL 又容易写出拖垮全站的慢查询
  • 为什么云按小时计费后,缩容和扩容一样重要——闲置机器在烧钱(论文举 Animoto 三天从约 50 台冲到 3400+)

SCADS 用 三个创新 换 scale independence:

  1. 性能安全的查询语言(受限 SQL / 预计算索引):只允许「在某个索引上查一段有界连续范围」的查询;更新维护索引的工作量必须是 O(K)(K 是应用常数,比如好友上限 5000)。类比:菜单上只卖能在固定时间内做完的套餐,点不了「随便炒点什么」。

  2. 声明式一致性–性能权衡:开发者用墙钟时间、百分位延迟、可用性、read-your-writes、持久化概率等写 SLA,而不是手调 quorum。类比:你说「99.9% 读要 <100ms、副本最多落后 10 分钟」,系统自己选复制与分区参数。

  3. 用机器学习做加减机器:根据负载与性能模型,在快违反 SLA 前加副本/重分区,低谷时减机器降成本。类比:客流预测软件在周末前多排班,周一自动减人。

三条合在一起,才叫 scale independence:不是「撑得住峰值」一句话,而是应用、成本、延迟三条曲线都不该随用户数一起炸。

案例 1:生日好友查询如何变成「安全索引」

Section titled “案例 1:生日好友查询如何变成「安全索引」”

社交应用要查「我的好友里谁快过生日」。开发者先提交查询模板(不是临时 ad-hoc):

SELECT profiles.*
FROM friends f JOIN profiles p
ON ... -- 好友关系
WHERE f.user = <user_id>
ORDER BY p.birthday

逐部分解释

  • SCADS 会物化一个索引:键前缀是 user_id,后面跟好友的 birthday,指向好友 profile
  • 好友列表变了、或某人改生日,就触发对应的 O(K) 维护函数(论文 Figure 3 的 index update 表)
  • 若查询无法保证「单次更新只做常数工作」,系统直接拒绝,而不是上线后拖垮全站

案例 2:用「轴」声明一致性,而不是调 W/R

Section titled “案例 2:用「轴」声明一致性,而不是调 W/R”
Performance: 99.9% 读延迟 < 100ms
Read lag: 副本可见滞后 ≤ 10 minutes
Session: read-your-own-writes = true
Durability: 提交写入持久概率 ≥ 99.999%
Priority: availability > read-lag # 分区时先保可用

逐步理解

  1. 写 SLA 用业务语言(墙钟、百分位),不是「W=2,R=1」
  2. 复制滞后有上界:超时则读可能阻塞或按优先级失败——「最终」不再无限期
  3. 多机房断连时,按你排的优先级在「返回旧数据」和「读失败」之间选
workload + SLA + ML performance model
→ 预测队列是否会赶不上复制截止时间
→ 提前加机器 / 重分区键与副本
→ 低谷时释放机器(utility computing 按小时计费)

跟做心智模型:把每个更新的「必须在 T 前传到所有副本」当成截止时间,进优先级队列;模型发现队列要爆,就先扩容,而不是等 SLA 已被打穿。论文评估计划里还提到用 CloudStone + 上千台 EC2,以及让 Berkeley Rails 课的新手站能否撑住合成百万用户——成功标准偏「好用且可扩」,不是再发一篇微基准。

  1. 把无界 fan-out 当普通查询:像 Twitter「被无限人关注」那种更新会炸 O(K) 假设——论文明确说需改模型才能进 SCADS。
  2. 把「最终一致」当成「随便多久」:用户能接受的是「最多 N 分钟」,不是无限期;要用声明式滞后上界。
  3. SLA 轴互相打架却没排优先级:机房分区时,可用性与读新鲜度会冲突,必须事先排序。
  4. 为了 SQL 表达力放开 ad-hoc:一次线性于用户数的查询,会让存储负载随用户数多项式爆炸。

适用

  • 社交 / UGC:查询模板事先知道,可物化索引与视图
  • 能接受秒到分钟级复制滞后,但要可量化的一致与延迟 SLA
  • 跑在可按需租机器的环境,需要随流量快速扩和缩
  • 写冲突策略可按类型分化(例如文档要可串行,评论可 last-write-wins)

不适用

  • 需要任意 ad-hoc / OLAP 分析查询的场景
  • 强依赖跨多记录 ACID 事务、单副本线性一致的业务
  • 更新扇出无法用应用常数 K 封顶的图计算型负载
  • 把存储当通用数据仓库、指望「什么 SQL 都能跑」的团队
  • 2007–2008:Dynamo、Bigtable 等证明 key-value 能撑超大站,但开发体验窄;Facebook 等靠分片 + 海量缓存 + 最终一致硬撑
  • 2009 年 1 月:Armbrust、Fox、Patterson 等在 CIDR 发表 SCADS 愿景,把 scale independence 写成一等目标
  • 同期云潮:EC2/S3 按小时计费,让「缩容省钱」第一次变成存储系统的一等需求
  • 后续:团队在 Cassandra 上叠加异步索引与自动供给的方向继续推进;PIQL 等后续工作把「性能安全查询」写得更具体(本篇 CIDR 文本身仍用「performance-safe / scale-aware」表述)
  1. 规模无关是产品目标,不是运维口号:应用不变、人均成本不变、延迟不变——三条要一起设计
  2. 砍查询比堆硬件更治本:只跑能证明 O(K) 的查询,比事后救火慢查询更稳
  3. 一致性该用业务语言声明:墙钟滞后、百分位延迟、session 保证,比裸 quorum 更贴近产品
  4. 云改变了优化函数:能缩容的系统,才配得上按小时买机器的经济模型
  • dynamo-2007 —— 有限 API + 最终一致;SCADS 要保留性能、补安全 join/索引
  • bigtable-2006 —— 单集群强一致宽表;社交「毛球图」难靠干净分区吃满
  • cassandra-2010 —— SCADS 实现计划里的存储底座之一
  • pnuts-2008 —— per-record 一致档位 vs SCADS 的多轴 SLA 声明
  • brewer-cap-2000 —— 可用性/一致性权衡的背景;SCADS 要求开发者显式排序
  • spanner-2012 —— 另一极端:用 TrueTime 追全球强一致,和 SCADS 取舍相反
  • stonebraker-2010-sqlnosql —— 同期「SQL vs NoSQL」争论的对照读物

(暂无反向链接)