第一章:可靠、可拓展、可维护的应用

如今很多的应用都是数据密集型(data-intensive), 而非计算密集型的(compute-intensive)的。CPU很少成为这些应用的瓶颈,更大的问题在于数据的数量、复杂度以及其变化速度。
一个数据密集型的应用通常由标准组件构建而成。这些标准组件提供了普遍被需要的功能。例如:

  • 存储数据(数据库(databases))
  • 记住开销昂贵的计算结果以加速读取(缓存(caches))
  • 允许用户通过关键字查询或通过各种方式过滤(搜索索引(search indexes))
  • 向其它进程发送信息,进行一步处理(流处理(stream processing))
  • 周期性处理大批量数据(批处理(batch processing))

不同的应用有着不同的需求,因此特性各异的数据库系统也是百花齐放。

关于数据系统的思考

我们通常认数据库、队列、缓存等属于区别显著的类别。虽然数据库和消息队列表面上有一些相似性——他们都存储一段时间的数据——但他们有着迥然不同的访问模型,这意味着迥异的性能特征和实现方式。
但是我们为什么仍把他们放在数据系统的总称下一起谈论呢?

(原因包含以下两点)

  1. 近年来出现了针对特定场景优化的数据存储、处理工具,他们不适合生硬地被归入传统类别。例如:数据存储可以被当成消息队列用(Redis),消息队列则带有类似数据库的持久保证(Apache Kafka)。
  2. 越来越多的应用有着严格而广泛的要求,单个工具不足以满足它们所有的数据处理和存储的需求。取而代之的是,总体工作被拆分为一系列能被单个工具高效完成的任务,并通过应用代码将他们缝合起来。

当你将多个工具组合到一起提供服务时,服务的接口或API通常会向客户端隐藏这些细节。现在,你基本上从一个小的、通用的组件创建出了个新的、专用的数据系统。

当你在设计一个数据系统或者服务时,会遇到很多棘手的问题:

  • 系统内部错误时,如何保证数据的正确性和完整性
  • 系统部分降级时,如何为客户提供始终如一的良好性能?
  • 负载增长时,系统如果扩展从而应对
  • 怎样的API是好的API

本书着重讨论三个重要概念

  • 可靠性(Reliability): 系统在“困境”(软硬件故障,人为错误)中仍需正常工作。(正常完成工作,并达到预期的性能水准)
  • 可扩展性(Scalability): 有合理的办法应对系统的增长(数据量、流量、复杂性)
  • 可维护性(Maintainability): 随时间流逝,不同的人都应能在该系统上高效工作。

除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 进行许可。