第一章:可靠、可拓展、可维护的应用
如今很多的应用都是数据密集型(data-intensive), 而非计算密集型的(compute-intensive)的。CPU很少成为这些应用的瓶颈,更大的问题在于数据的数量、复杂度以及其变化速度。
一个数据密集型的应用通常由标准组件构建而成。这些标准组件提供了普遍被需要的功能。例如:
- 存储数据(数据库(databases))
- 记住开销昂贵的计算结果以加速读取(缓存(caches))
- 允许用户通过关键字查询或通过各种方式过滤(搜索索引(search indexes))
- 向其它进程发送信息,进行一步处理(流处理(stream processing))
- 周期性处理大批量数据(批处理(batch processing))
不同的应用有着不同的需求,因此特性各异的数据库系统也是百花齐放。
关于数据系统的思考
我们通常认数据库、队列、缓存等属于区别显著的类别。虽然数据库和消息队列表面上有一些相似性——他们都存储一段时间的数据——但他们有着迥然不同的访问模型,这意味着迥异的性能特征和实现方式。
但是我们为什么仍把他们放在数据系统的总称下一起谈论呢?
(原因包含以下两点)
- 近年来出现了针对特定场景优化的数据存储、处理工具,他们不适合生硬地被归入传统类别。例如:数据存储可以被当成消息队列用(Redis),消息队列则带有类似数据库的持久保证(Apache Kafka)。
- 越来越多的应用有着严格而广泛的要求,单个工具不足以满足它们所有的数据处理和存储的需求。取而代之的是,总体工作被拆分为一系列能被单个工具高效完成的任务,并通过应用代码将他们缝合起来。
当你将多个工具组合到一起提供服务时,服务的接口或API通常会向客户端隐藏这些细节。现在,你基本上从一个小的、通用的组件创建出了个新的、专用的数据系统。
当你在设计一个数据系统或者服务时,会遇到很多棘手的问题:
- 系统内部错误时,如何保证数据的正确性和完整性
- 系统部分降级时,如何为客户提供始终如一的良好性能?
- 负载增长时,系统如果扩展从而应对
- 怎样的API是好的API
本书着重讨论三个重要概念
- 可靠性(Reliability): 系统在“困境”(软硬件故障,人为错误)中仍需正常工作。(正常完成工作,并达到预期的性能水准)
- 可扩展性(Scalability): 有合理的办法应对系统的增长(数据量、流量、复杂性)
- 可维护性(Maintainability): 随时间流逝,不同的人都应能在该系统上高效工作。
除另有声明外,本博客文章均采用 知识共享(Creative Commons) 署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 进行许可。