00.特性

高可用系统特性

节点故障、不可靠的网络、对副本一致性,持久性,可用性和延迟的权衡,这些问题实际上是分布式系统中的基本问题。

数据系统

现今很多应用程序都是数据密集型(data-intensive)的,而非计算密集型(compute-intensive)的。因此 CPU 很少成为这类应用的瓶颈,更大的问题通常来自数据量、数据复杂性、以及数据的变更速度。

数据密集型应用通常由标准组件构建而成,标准组件提供了很多通用的功能;例如,许多应用程序都需要:

  • 数据库(Database):存储数据,以便自己或其他应用程序之后能再次找到。
  • 缓存(Cache):记住开销昂贵操作的结果,加快读取速度。
  • 搜索索引(Search Engine):允许用户按关键字搜索数据,或以各种方式对数据进行过滤。
  • 流处理(Stream Processing):向其他进程发送消息,进行异步处理。
  • 批处理(Batch Processing):定期处理累积的大批量数据。

我们通常认为,数据库、消息队列、缓存等工具分属于几个差异显著的类别。虽然数据库和消息队列表面上有一些相似性,譬如它们都会存储一段时间的数据,但它们有迥然不同的访问模式,这意味着迥异的性能特征和实现手段。但是近些年来,出现了许多新的数据存储工具与数据处理工具。它们针对不同应用场景进行优化,因此不再适合生硬地归入传统类别。类别之间的界限变得越来越模糊,例如:数据存储可以被当成消息队列用(Redis),消息队列则带有类似数据库的持久保证(Apache Kafka)。

其次,越来越多的应用程序有着各种严格而广泛的要求,单个工具不足以满足所有的数据处理和存储需求。取而代之的是,总体工作被拆分成一系列能被单个工具高效完成的任务,并通过应用代码将它们缝合起来。例如,如果将缓存(应用管理的缓存层,Memcached 或同类产品)和全文搜索(全文搜索服务器,例如 Elasticsearch 或 Solr)功能从主数据库剥离出来,那么使缓存/索引与主数据库保持同步通常是应用代码的责任。

一个可能的组合使用多个组件的数据系统架构

当你将多个工具组合在一起提供服务时,服务的接口或应用程序编程接口(API, Application Programming Interface)通常向客户端隐藏这些实现细节。现在,你基本上已经使用较小的通用组件创建了一个全新的、专用的数据系统。这个新的复合数据系统可能会提供特定的保证,例如:缓存在写入时会作废或更新,以便外部客户端获取一致的结果。现在你不仅是应用程序开发人员,还是数据系统设计人员了。

系统特性

一个应用必须满足各种需求才称得上有用。有一些功能需求(functional requirements)(它应该做什么,比如允许以各种方式存储,检索,搜索和处理数据)以及一些非功能性需求(nonfunctional)(通用属性,例如安全性,可靠性,合规性,可扩展性,兼容性和可维护性)。

  • 可靠性(Reliability):系统在困境(adversity)(硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并能达到期望的性能水准)。可靠性(Reliability)意味着即使发生故障,系统也能正常工作。故障可能发生在硬件(通常是随机的和不相关的),软件(通常是系统性的 Bug,很难处理),和人类(不可避免地时不时出错)容错技术 可以对终端用户隐藏某些类型的故障。

  • 可扩展性(Scalability):有合理的办法应对系统的增长(数据量、流量、复杂性)。可扩展性(Scalability)意味着即使在负载增加的情况下也有保持性能的策略。为了讨论可扩展性,我们首先需要定量描述负载和性能的方法。我们简要了解了推特主页时间线的例子,介绍描述负载的方法,并将响应时间百分位点作为衡量性能的一种方式。在可扩展的系统中可以添加 处理容量(processing capacity)以在高负载下保持可靠。

  • 可维护性(Maintainability):许多不同的人(工程师、运维)在不同的生命周期,都能高效地在系统上工作(使系统保持现有行为,并适应新的应用场景)。可维护性(Maintainability)有许多方面,但实质上是关于工程师和运维团队的生活质量的。良好的抽象可以帮助降低复杂度,并使系统易于修改和适应新的应用场景。良好的可操作性意味着对系统的健康状态具有良好的可见性,并拥有有效的管理手段。