DDIA读书笔记 | 第一章:可靠性、可伸缩性、可维护性

第一章:可靠性、可伸缩性、可维护性


文章目录

  • 第一章:可靠性、可伸缩性、可维护性
  • 前言
  • 一、可靠性
    • 1. 定义
    • 2. 硬件故障
    • 3. 软件错误
      • 问题
      • 解决方案:
    • 4. 人为错误
  • 二、可伸缩性
    • 1.可伸缩性(Scalability)
      • 描述负载
      • 描述性能
      • 应对负载
  • 三、可维护性
    • 1.可维护性(Maintainability)
  • 本章总结


前言

着重讨论三个在大多数软件系统中都很重要的问题:

可靠性(Reliability)
系统在困境(adversity)(硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并能达到期望的性能水准)。

可伸缩性(Scalability)
有合理的策略应对系统的增长(数据量、流量、复杂性),主要讨论性能、负载和资源之间的关系。

可维护性(Maintainability)
许多不同的人(工程师、运维)在不同生命周期,都能高效地在系统上工作(使系统保持现有行为,并适应新的应用场景)。


一、可靠性

1. 定义

可靠性意味着即使发生故障,系统也能正常工作。故障可能发生在硬件(通常是随机的和不相关的),软件(通常是系统性的Bug,很难处理),和人类(不可避免地时不时出错)。 容错技术可以对终端用户隐藏某些类型的故障。

2. 硬件故障

①当想到系统失效的原因时,硬件故障(hardware faults) 总会第一个进入脑海。硬盘崩溃、内存出错、机房断电、有人拔错网线……任何与大型数据中心打过交道的人都会告诉你:一旦你拥有很多机器,这些事情会发生!
②为了减少系统的故障率,第一反应通常都是增加单个硬件的冗余度,例如:磁盘可以组建RAID,服务器可能有双路电源和热插拔CPU,数据中心可能有电池和柴油发电机作为后备电源,某个组件挂掉时冗余组件可以立刻接管。
③如果在硬件冗余的基础上进一步引入软件容错机制,那么系统在容忍整个(单台)机器故障的道路上就更进一步了。这样的系统也有运维上的便利,例如:如果需要重启机器(例如应用操作系统安全补丁),单服务器系统就需要计划停机。而允许机器失效的系统则可以一次修复一个节点,无需整个系统停机。

3. 软件错误

问题

①接受特定的错误输入,便导致所有应用服务器实例崩溃的BUG。例如2012年6月30日的闰秒,由于Linux内核中的一个错误,许多应用同时挂掉了。
②失控进程会用尽一些共享资源,包括CPU时间、内存、磁盘空间或网络带宽。
③系统依赖的服务变慢,没有响应,或者开始返回错误的响应。
④级联故障,一个组件中的小故障触发另一个组件中的故障,进而触发更多的故障。

解决方案:

①仔细考虑系统中的假设和交互;
②彻底的测试;
③进程隔离;
④允许进程崩溃并重启;
⑤测量、监控并分析生产环境中的系统行为。
如果系统能够提供一些保证(例如在一个消息队列中,进入与发出的消息数量相等),那么系统就可以在运行时不断自检,并在出现差异(discrepancy) 时报警

4. 人为错误

设计并构建了软件系统的工程师是人类,维持系统运行的运维也是人类。举个例子,一项关于大型互联网服务的研究发现,运维配置错误是导致服务中断的首要原因,而硬件故障(服务器或网络)仅导致了10-25%的服务中断

二、可伸缩性

1.可伸缩性(Scalability)

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

描述负载

负载可以用一些称为 负载参数(load parameters) 的数字来描述。
参数的最佳选择 取决于系统架构,它可能是每秒向Web服务器发出的请求、数据库中的读写比率、聊天室中同时活跃的用户数量、缓存命中率或其他东西。除此之外,也许**平均情况(或者中位数,百分位数等)**对你很重要,也许你的瓶颈是少数极端场景。
代码如下(示例):

描述性能

①对于Hadoop这样的批处理系统,通常关心的是吞吐量(throughput),即每秒可以处理的记录数量,或者在特定规模数据集上运行作业的总时间。

②对于在线系统,通常更重要的是服务的响应时间(response time),即客户端发送请求到接收响应之间的时间。

注意:
①理想情况下,批量作业的运行时间是数据集的大小除以吞吐量。 在实践中由于数据倾斜(数据不是均匀分布在每个工作进程中),需要等待最慢的任务完成,所以运行时间往往更长。

延迟(latency) 和 响应时间(response time) 经常用作同义词,但实际上它们并不一样。响应时间是客户所看到的,除了实际处理请求的时间( 服务时间(service time) )之外,还包括网络延迟和排队延迟。延迟是某个请求等待处理的持续时长,在此期间它处于 休眠(latent) 状态,并等待服务。也就是:响应时间 = 网络延迟 + 排队延迟 + 处理时间

② 通常使用百分位点(percentiles) 会更好。如果将响应时间列表按最快到最慢排序,那么中位数(median) 就在正中间:举个例子,如果你的响应时间中位数是200毫秒,这意味着一半请求的返回时间少于200毫秒,另一半比这个要长。

③ 为了弄清异常值有多糟糕,可以看看更高的百分位点,例如第95、99和99.9百分位点(缩写为p95,p99和p999)

④ 响应时间的高百分位点(也称为尾部延迟(tail latencies))非常重要,因为它们直接影响用户的服务体验。例如亚马逊在描述内部服务的响应时间要求时以99.9百分位点为准,即使它只影响一千个请求中的一个。这是因为请求响应最慢的客户往往也是数据最多的客户,也可以说是最有价值的客户 —— 因为他们掏钱了。

⑤ 百分位点通常用于服务级别目标(SLO, service level objectives)和服务级别协议(SLA, service level agreements),即定义服务预期性能和可用性的合同。 SLA可能会声明,如果服务响应时间的中位数小于200毫秒,且99.9百分位点低于1秒,则认为服务工作正常(如果响应时间更长,就认为服务不达标)。这些指标为客户设定了期望值,并允许客户在SLA未达标的情况下要求退款。

排队延迟(queueing delay) 通常占了高百分位点处响应时间的很大一部分。由于服务器只能并行处理少量的事务(如受其CPU核数的限制),所以只要有少量缓慢的请求就能阻碍后续请求的处理,这种效应有时被称为 头部阻塞(head-of-line blocking) 。即使后续请求在服务器上处理的非常迅速,由于需要等待先前请求完成,客户端最终看到的是缓慢的总体响应时间。因为存在这种效应,测量客户端的响应时间非常重要。

应对负载

① 人们经常讨论纵向伸缩(scaling up)(垂直伸缩(vertical scaling),转向更强大的机器)和横向伸缩(scaling out) (水平伸缩(horizontal scaling),将负载分布到多台小机器上)之间的对立。跨多台机器分配负载也称为无共享(shared-nothing)架构。可以在单台机器上运行的系统通常更简单,但高端机器可能非常贵,所以非常密集的负载通常无法避免地需要横向伸缩。
② 现实世界中的优秀架构需要将这两种方法务实地结合,因为使用几台足够强大的机器可能比使用大量的小型虚拟机更简单也更便宜。

大规模的系统架构通常是应用特定的—— 没有一招鲜吃遍天的通用可伸缩架构(不正式的叫法:万金油(magic scaling sauce) )。应用的问题可能是读取量、写入量、要存储的数据量、数据的复杂度、响应时间要求、访问模式或者所有问题的大杂烩

举个例子,用于处理每秒十万个请求(每个大小为1 kB)的系统与用于处理每分钟3个请求(每个大小为2GB)的系统看上去会非常不一样,尽管两个系统有同样的数据吞吐量。

三、可维护性

1.可维护性(Maintainability)

可维护性有许多方面,但实质上是关于工程师和运维团队的生活质量的。良好的抽象可以帮助降低复杂度,并使系统易于修改和适应新的应用场景。良好的可操作性意味着对系统的健康状态具有良好的可见性,并拥有有效的管理手段。


本章总结

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

你可能感兴趣的:(DDIA读书总结,服务器,运维,数据库)