SRE-谷歌运维揭秘
Created|Updated|基础设施
|Word Count:8|Reading Time:1mins|Post Views:
Author: magicliang
Link: https://magicliang.github.io/2021/09/15/SRE-%E8%B0%B7%E6%AD%8C%E8%BF%90%E7%BB%B4%E6%8F%AD%E7%A7%98/
Copyright Notice: All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Related Articles

2026-10-04
系统设计 29:排行榜的迟到修正与热点代价
如果一场比赛的第 60–120 秒排行榜在第 120 秒立刻封榜,一条第 69 秒发生、但第 121 秒才入站的得分应该去哪?忽略它能让榜单快速稳定,却会让账本与排行榜对不上。排行榜设计首先需要决定:读的是实时暂定榜,还是可纠错的最终榜。 本题假设每个被验证的得分事件 event_id 对同一窗口只计一次;窗口采用事件时间半开区间 [60,120) 秒。相同分数采用并列密集排名,展示顺序再按玩家 ID 字典序稳定排序。删除作弊得分也是修正事件,不是默默改计数。只有权限通过的已确认事件进入榜单,未验证事件不参与计算。 先把榜单合同写全 教学 SLO:暂定榜近 30 天 99% 请求在入口 200 毫秒内返回,且带 computed_through 位点;已受理得分在 5 秒内进入暂定榜(处理完成时间减本地持久化时间的 99%)。终榜在窗口结束后等待 2 分钟迟到宽限,再按相同事件集批量重算并公布版本。以上都是目标,不是实验测出的性能。更晚到达的事件放到修正队列,由业务规则决定是否发新版本。跨赛季汇总、奖金发放和反作弊算法不在本题范围内;有奖金时不能把该暂定榜当财务最终排名。 假设...

2026-10-04
系统设计 06:缓存与 CDN——命中、失效、热点与回源
把热门内容放进 CDN 能减少回源,但“缓存命中率很高”没有回答分享撤销之后谁还能看见旧内容。失效不只是一条删除命令:要先划清哪些读允许旧值、哪些读必须在确认撤销后立刻拒绝,再决定缓存键、TTL 和回源容量。 沿用网关与连接边界及前几篇的分享场景:GET /shares/{id} 读取目标、所有者 DELETE /shares/{id} 撤销、图片预览按版本读取。本篇只讨论分享元数据和已公开的不可变预览,不讨论私有对象的直连 CDN 方案、DRM 或 CDN 产品计费。此前约定“撤销确认后不能再公开返回目标”,这一要求高于缓存命中率。 先把可缓存和不能缓存的访问拆开 读路径分两类。分享目标在源站的权威状态为 ready/revoked,公开读取必须检查撤销;若一个共享缓存可直接返回旧目标,就算源站状态已经改变,访问者仍可能看见旧响应。受保护响应应避免进入共享缓存;对遵循 HTTP 规范的缓存,响应侧 Cache-Control: no-store 表示不应存储该响应(RFC 9111:no-store)。这不阻止读者已复制的内容,也不等于 CDN 供应商对撤销时限作了承诺。 对...

2026-10-04
系统设计 30:任务租约和过期持有者栅栏
一个日报任务在 10 秒到期,工作者 A 取走后停止响应;16 秒工作者 B 重领并完成。A 恰好又恢复,拿着旧结果写入数据库。如果系统只检查“任务 ID 相同”,最后保存的可能是 A 的过期数据。延时队列解决“什么时候可领”,租约和栅栏解决“谁的完成确认还有效”,两者不是同一个问题。 每个周期是独立的一次执行 教学任务 report 的周期实例键是 (task_id,slot),其中 slot 来自固定时区下的计划触发时间,不由工作者的当前时钟临时生成。同一键至多保留一个有效结果;过期工作者可以消耗计算资源,不能覆盖已被后继租约提交的结果。任务执行并不保证恰好一次;若副作用发生在邮件、账务等外部系统,仍需要那些系统支持幂等键或结果核对。误触发、超时和未执行都必须可查询。 教学 SLO:未来 30 天 99% 已到期实例在调度时间后 10 秒内被领取(只对调度器可用且下游有容量的实例,测量计划时间与数据库租约时间);99.9% 到期实例在 5 分钟内达到成功或明确的死信状态。禁止用“已经领到”替代“业务动作完成”。跨时区夏令时规则、需要人工签核的任务及任意第三方 HTTP 的恰...

2026-10-04
系统设计 22:限流器的原子计数与全局配额
“每个用户每秒允许十次”还不足以实现限流。十次是自然秒内计数、任意一秒窗口,还是长期每秒十次并允许短时突发?配额由一个实例独占,还是十个网关各发十个令牌?请求到达时间、计数位置和原子边界不同,允许数量就不同。 本篇把 API 限流设计成明确的资源分配协议:令牌桶容量为 B、补充速率为 r,请求花费一个令牌;多个入口共享同一逻辑配额。目标是限制成本较高的查询,不承担账户余额、座位库存等不可超发资源的最终正确性。所有容量数字为教学假设,实验在真实 SQLite 上验证共享状态事务,不声称验证了 Redis Lua。 限流键也是授权边界 网关先鉴权,再用稳定的租户 ID 和 API 类别组成配额键。直接信任客户端提交的 user_id 会允许换键绕过限流;只按 IP 则可能惩罚共享出口的公司或学校。未认证请求可以用 IP 做粗粒度保护,但不能由此推导认证用户公平性。 限流调用可表述为 acquire(tenant, route_class, cost, request_id),返回 allowed, retry_after, remaining。业务 API 被拒绝时返回 429;R...

2026-10-04
系统设计 01:需求澄清——功能、SLO、数据不变量与范围
“做一个分享服务”不能直接变成组件清单。它还没有说明:分享给谁,链接可以撤销吗,读者缓存了旧内容怎么办,创建响应丢了还能不能重试。这些问题的答案会直接改变读写路径。 延续第 00 篇:系统设计题究竟交付什么的教学场景,本篇只处理一件事:把含混需求转成可验证的契约,不借课程题解推测真实产品架构。 先问会改变架构的问题 产品希望用户创建一条分享,接收方打开链接,创建者以后可以撤销。选择以下教学假设,而不是默许它们:只有登录的创建者能撤销;现在分享目标是 URL 元数据,非文件正文;读者无需登录,但链接转发即可能被别人读取;撤销确认之后才开始的新读取,不得返回目标。撤销确认之前已发出响应的读取,不承诺能在网络中撤回。 排除公开搜索、按创建者列举、链接到期、屏蔽恶意 URL 和隐私内容的接收者鉴权。这些是后续产品决策,不是“先不画出来就自动解决”。若用户问“这条链接必须仅让指定同事读取吗”,应先改变接口和访问控制模型,而不是把随机分享 ID 当成授权。若用户问“网页已被别人保存怎么办”,服务端撤销不能抹去接收方保存的副本;必须缩小承诺。 问题 本题确认 可观察验收 创建超...

2026-10-04
系统设计 12:短链服务:唯一创建与可撤销重定向
短链的读取看起来只是一次键值查询,但“随时可以撤销”会改变缓存和重定向选择。假如浏览器已经记住永久重定向,服务端再删除映射也不能让这个浏览器重新询问。编码长度决定碰撞空间,数据库约束决定是否覆盖,撤销契约决定读取路径,三者不能互相替代。 候选服务支持创建、访问、到期和撤销,产品名 TinyURL 只表示题型。它不复刻任何公司的内部架构。前面的 ID、缓存和数据模型基础在这里组合成一条能明确确认点的路径。 设计目标是有效短码跳转在服务端入口计时的五分钟窗口内 p99 小于 150 ms,已提交撤销后的新读取不得重定向。性能数字和严格撤销规则均是候选 SLO,不是本地实验测得的可用性或延迟;状态库不可用时本设计宁可拒绝跳转,也不以旧缓存返回目标。 创建者与访问者有不同的接口 POST /links 接受目标 URL、有效期和可选自定义别名;调用者身份来自认证上下文,幂等键放在请求头。成功返回 201 和 code;同一所有者、同一幂等键、同一请求正文再次提交返回原记录;同键不同正文返回冲突。自定义别名已存在返回 409,而不是覆盖已有用户的链接。 GET /{code...
Announcement
人生只是,守株待兔






