本周系统设计复习:

  • 扩展数据库的 7 个必知策略
  • 我们如何在失败时重试?
  • Reddit 的核心架构
  • 关于跨站脚本(XSS)你需要知道的一切

扩展数据库的 7 个策略

1. 索引(Indexing)

检查应用的查询模式并创建正确的索引。

  • 为常用查询列创建索引
  • 避免过度索引(写入开销)
  • 使用复合索引用于多列查询

2. 物化视图(Materialized Views)

预计算复杂查询结果并存储它们以更快速访问。

  • 适合复杂聚合查询
  • 需要定期刷新

3. 去规范化(Denormalization)

减少复杂连接以提高查询性能。

  • 用读取空间换时间
  • 增加数据冗余

4. 垂直扩展(Vertical Scaling)

通过添加更多 CPU、RAM 或存储提升数据库服务器。

  • 简单直接
  • 有硬件上限
  • 单点故障风险

5. 缓存(Caching)

将频繁访问的数据存储在更快的存储层以减少数据库负载。

  • Redis、Memcached
  • 应用层缓存
  • 查询结果缓存

6. 复制(Replication)

在不同服务器上创建主数据库的副本以扩展读取。

  • 主从复制
  • 读写分离
  • 提高可用性

7. 分片(Sharding)

将数据库表分成更小的片段并将它们分布在服务器上。用于扩展写入和读取。

  • 基于范围分片
  • 基于哈希分片
  • 一致性哈希

重试策略

在分布式系统和网络应用中,重试策略对有效处理瞬时错误和网络不稳定至关重要。下图显示了 4 种常见重试策略。

1. 线性回退(Linear Backoff)

线性回退涉及在重试尝试之间等待逐渐增加的固定间隔。

优点

  • 实现和理解简单

缺点

  • 在高负载或高并发环境下可能不理想,可能导致资源竞争或”重试风暴”

2. 线性抖动回退(Linear Jitter Backoff)

线性抖动回退通过向重试间隔引入随机性修改线性回退策略。此策略仍然线性增加延迟但为每个间隔添加随机”抖动”。

优点

  • 随机性帮助将重试尝试在时间上分散,减少跨实例同步重试的机会

缺点

  • 虽然比简单线性回退好,此策略仍可能导致同步重试的潜在问题,因为基础间隔仅线性增加

3. 指数回退(Exponential Backoff)

指数回退涉及指数增加重试之间的延迟。间隔可能从 1 秒开始,然后增加到 2 秒、4 秒、8 秒,依此类推,通常到最大延迟。这种方法比线性回退在间隔重试方面更激进。

优点

  • 显著减少系统负载和重试尝试碰撞或重叠的可能性,使其适用于高负载环境

缺点

  • 在快速重试可能解决问题的情况下,此方法可能不必要地延迟解决

4. 指数抖动回退(Exponential Jitter Backoff)

指数抖动回退结合指数回退与随机性。每次重试后,回退间隔指数增加,然后应用随机抖动。抖动可以是加法的(向指数延迟添加随机量)或乘法的(将指数延迟乘以随机因子)。

优点

  • 提供指数回退的所有好处,由于引入抖动,进一步减少重试碰撞的机会

缺点

  • 随机性有时可能导致比必要更长的延迟,特别是如果抖动很大

Reddit 核心架构

快速看看 Reddit 的核心架构,帮助它每月服务超过 10 亿用户。

此信息基于许多 Reddit 工程博客的研究。但由于架构不断演变,某些方面可能已变化。

Reddit 架构要点

  • Reddit 使用 Fastly 的内容分发网络(CDN)作为应用的前端
  • Reddit 在 2009 年初开始使用 jQuery。后来,他们开始使用 TypeScript,现在已转向现代 Node.js 框架。多年来,Reddit 也为 Android 和 iOS 构建了移动应用
  • 在应用栈内,负载均衡器坐在前面并将传入请求路由到适当的服务
  • Reddit 开始是基于 Python 的单体应用,但已开始转向使用 Go 构建的微服务
  • Reddit 大量使用 GraphQL 作为其 API 层。2021 年初,他们开始转向 GraphQL Federation,这是一种组合多个较小 GraphQL API(称为 Domain Graph Services,DGS)的方式。2022 年,Reddit 的 GraphQL 团队为核心 Reddit 实体添加了几个新的 Go 子图,从而拆分了 GraphQL 单体
  • 从数据存储角度看,Reddit 依赖 Postgres 作为其核心数据模型。为减少数据库负载,他们在 Postgres 前面使用 memcached。此外,他们大量使用 Cassandra 用于新功能,主要因为其弹性和可用性特性
  • 为支持数据复制和维护缓存一致性,Reddit 使用 Debezium 运行变更数据捕获(CDC)流程
  • 昂贵操作如用户投票或提交链接通过 RabbitMQ 延迟到异步作业队列并由作业 worker 处理。对于内容安全检查和审核,他们使用 Kafka 实时传输数据以运行规则
  • Reddit 使用 AWS 和 Kubernetes 作为其各种应用和内部服务的托管平台
  • 对于部署和基础设施,他们使用 Spinnaker、Drone CI 和 Terraform

跨站脚本(XSS)

XSS 是一种普遍存在的漏洞,发生在恶意脚本注入到网页时,通常通过输入字段。下图深入探讨了当用户输入处理不当并随后返回给客户端时,这种漏洞如何出现,使系统容易受到利用。

理解反射型和存储型 XSS 之间的区别至关重要。反射型 XSS 涉及注入脚本的立即执行,而存储型 XSS 随时间持续,构成长期威胁。深入图表以全面比较这些攻击向量。

想象这个场景:一个狡猾的黑客利用 XSS 秘密从用户浏览器收获用户凭据,如 cookie,可能导致未经授权的访问和数据泄露。这是一个可怕的现实。

但别担心!我们的传单还深入探讨了有效的缓解策略,使你能够加强系统抵御 XSS 攻击。从输入验证和输出编码到实施严格的内容安全策略(CSP),我们已覆盖。

本文为学习目的的个人翻译,译文仅供参考。

原文链接:EP114: 7 Must-know Strategies to Scale Your Database

版权归原作者或原刊登方所有。本文为非官方译本;如有不妥,请联系删除。