DynamoDB十年经验:NoSQL数据库架构与优化实践
设计原则
DynamoDB是互联网上最受欢迎的NoSQL数据库服务之一,专为简单性、可预测性、可扩展性和可靠性而设计。在庆祝DynamoDB十周年之际,团队总结了以下核心经验:
可预测性优于绝对效率
系统设计应优先考虑可预测性而非绝对效率,以提高系统稳定性。虽然缓存等组件可以提高性能,但它们不应引入双模态行为(即系统对类似请求有两种截然不同的响应方式)。一致的行为确保系统始终能够处理意外情况。
适应客户流量模式
根据客户的流量模式重新分配数据可以改善客户体验。通过监控流量模式并重新分区表格,使频繁访问的项目位于不同节点上。
持续验证空闲数据
持续验证空闲数据是防止硬件故障和软件错误、满足高持久性目标的可靠方法。通过擦除过程验证复制组中所有三个副本是否具有相同数据,并确保实时副本与使用归档预写日志条目离线构建的参考副本匹配。
架构细节
数据组织方式
DynamoDB表是项目(如产品)的集合,每个项目是属性(如名称、价格、类别等)的集合。每个项目由其主键唯一标识。表格通常被分区或划分为更小的子表,分配给节点。
复制与一致性
DynamoDB在每个分区的不同可用区中存储三个副本,这使得分区具有高可用性和持久性。同一分区的三个副本称为复制组,组中有一个领导者负责复制所有客户变更并提供强一致性读取。
可预测性架构改进
MemDS系统:构建了称为MemDS的内存数据存储,显著减少了请求路由器和其他元数据客户端对本地缓存的依赖。MemDS以高度压缩的方式存储所有路由元数据,并在服务器群集中复制。
新型本地缓存:部署了避免原始缓存双模态性的新型本地缓存。所有请求(即使由本地缓存满足)都异步发送到MemDS,确保MemDS群集始终处理恒定量的流量。
分区优化
分区挑战与解决方案
热分区问题:由于客户工作负载分布不均匀,持续访问项目子集导致热分区问题。
吞吐量稀释:为处理增加负载而拆分的分区最终键太少,可能快速耗尽分配的有限容量。
解决方案演进:
- 突发容量:在分区级别吸收工作负载中的临时峰值
- 自适应容量:处理突发容量无法吸收的长期峰值
- 全局准入控制(GAC):基于令牌桶概念,每个请求路由器维护本地令牌桶并与GAC通信以定期补充令牌
数据持久性保障
预写日志机制
为提供持久性和崩溃恢复,DynamoDB使用预写日志,在数据写入发生前记录它们。预写日志存储在分区的所有三个副本中,为获得更高持久性,定期将预写日志归档到对象存储服务。
快速修复机制
检测到不健康的存储副本时,复制组的领导者会添加日志副本以确保对持久性没有影响。添加日志副本仅需几秒钟,因为系统只需从健康副本复制最新的预写日志;重建更内存密集的B树可以等待。
可用性保障
可用性测量
DynamoDB设计为全局表99.999%的可用性和区域表99.99%的可用性。通过两种客户端集测量用户感知的可用性:
- 使用DynamoDB作为数据存储的内部服务
- 从区域中每个可用区运行的DynamoDB金丝雀应用程序
读写可用性差异处理
分区写入可用性取决于其领导者和写入法定人数(来自不同可用区的三个副本中的两个)的健康状况。只要存在足够的健康副本来满足写入法定人数和领导者,分区就保持可用。
容错测试
DynamoDB定期测试对节点、机架和可用区故障的恢复能力。例如,执行断电测试,使用真实模拟流量,作业调度程序关闭随机节点。
技术创新
Paxos共识协议
引入日志副本是对系统的重大改变,但可形式化证明的Paxos共识协议提供了安全调整和试验系统以实现更高可用性的信心。
客户面向警报(CFAs)
这些警报报告任何与可用性相关的问题,并通过自动或操作员干预主动缓解。关键点是可用性不仅在服务器端测量,还在客户端测量。
这些经验教训帮助DynamoDB团队构建了一个稳定、可扩展且高度可用的数据库服务,为数以万计的客户提供服务。