《设计数据密集型应用》读书笔记-第一章:可靠性、可伸缩性和可维护性
计算密集型(compute-intensive)应用瓶颈可能是CPU、内存或者硬盘等,但数据密集型(data-intensive)应用的瓶颈通常来自数据量、数据复杂性以及数据的变更速度。
数据系统
数据密集型应用 -> 数据系统(data system)
- 数据库 database
- 缓存 cache
- 搜索索引 search index
- 流处理 stream processing
- 批处理 batch processing
影响数据系统设计的因素:
-
可靠性 Reliability
系统在困境(adversity,比如硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功能,并能达到期望的性能水准)。
-
可伸缩性 Scalability
有合理的办法应对系统的增长(数据量、流量、复杂性)。
-
可维护性 Maintainability
许多不同的人(工程师、运维)在不同的生命周期,都能高效地在系统上工作(使系统保持现有行为,并适应新的应用场景)。
可靠性
造成错误的原因叫做故障(fault),能预料并应对故障的系统特性可称为容错(fault-tolerant)或韧性(resilient)。
故障(fault)不同于失效(failure)。故障通常定义为系统的一部分状态偏离其标准,而 失效 则是系统作为一个整体停止向用户提供服务。故障的概率不可能降到零,因此最好设计容错机制以防因故障而导致失效。
尽管比起阻止错误(prevent error),我们通常更倾向于容忍错误。但也有预防胜于治疗的情况(比如不存在治疗方法时)。安全问题就属于这种情况。例如,如果攻击者破坏了系统,并获取了敏感数据,这种事是撤销不了的。
-
硬件故障
减少单机系统故障率,通常采用增加单个硬件的冗余度,比如硬盘组成RAID等。对于分布式系统来说,优先考虑灵活性(flexibility)和弹性(elasticity),并在硬件冗余的基础上引入软件容错机制,容忍单台机器故障。
-
软件错误
系统性错误(systematic error)难以预料,会造成更多的系统失效。比如:
- 失控进程会用尽一些共享资源,包括 CPU 时间、内存、磁盘空间或网络带宽。
- 系统依赖的服务变慢,没有响应,或者开始返回错误的响应。
- 级联故障,一个组件中的小故障触发另一个组件中的故障,进而触发更多的故障。
解决办法:进程隔离、彻底地测试、允许进程崩溃并重启、测量和监测分析生产环境的系统行为。
-
人为错误
优化方式:
- 以最小化犯错机会的方式设计系统。
- 将人们最容易犯错的地方与可能导致失效的地方解耦(decouple)。
- 在各个层次进行彻底的测试,从单元测试、全系统集成测试到手动测试。自动化测试易于理解,已经被广泛使用,特别适合用来覆盖正常情况中少见的边缘场景(corner case)。
- 允许从人为错误中简单快速地恢复,以最大限度地减少失效情况带来的影响。
- 配置详细和明确的监控,比如性能指标和错误率。
- 良好的管理实践与充分的培训。
可伸缩性
可伸缩性(Scalability) 是用来描述系统应对负载增长能力的术语。
负载可以用一些称为负载参数(load parameters)的数字来描述。参数的最佳选择取决于系统架构,它可能是每秒向 Web 服务器发出的请求、数据库中的读写比率、聊天室中同时活跃的用户数量、缓存命中率或其他东西。除此之外,也许平均情况对你很重要,也许你的瓶颈是少数极端场景。
描述性能的角度
- 增加负载参数并保持系统资源(CPU、内存、网络带宽等)不变时,系统性能将受到什么影响?
- 增加负载参数并希望保持性能不变时,需要增加多少系统资源?
常用指标
- 吞吐量(throughput)
- 响应时间(response time)
响应时间是客户所看到的,除了实际处理请求的时间(服务时间(service time) )之外,还包括网络延迟和排队延迟。 - 延迟(latency)
延迟是某个请求等待处理的 持续时长,在此期间它处于休眠(latent)状态,并等待服务。
表示方式
-
算术平均值(arithmetic mean)
-
分布(distribution)
-
百分位点(percentiles)
-
中间数(median) p50
-
p95 p99 p999
为了弄清异常值有多糟糕,可以看看更高的百分位点,例如第 95、99 和 99.9 百分位点(缩写为 p95,p99 和 p999)。它们意味着 95%、99% 或 99.9% 的请求响应时间要比该阈值快,例如:如果第 95 百分位点响应时间是 1.5 秒,则意味着 100 个请求中的 95 个响应时间快于 1.5 秒,而 100 个请求中的 5 个响应时间超过 1.5 秒。
计算方法:向前衰减、tdigest、HdrHistogram
-
尾延迟 (tail latency)
-
排队延迟(queueing delay)
头部阻塞(head-of-line blocking)
-
应对负载的方法
纵向伸缩(scaling up),也称为垂直伸缩(vertical scaling)。
横向伸缩(scaling out),也称为水平伸缩(horizontal scaling)
可维护性
软件系统的三个设计原则:
-
可操作性(Operability)
便于运维团队保持系统平稳运行。
-
简单性(Simplicity)
从系统中消除尽可能多的 复杂度(complexity),使新工程师也能轻松理解系统(注意这和用户接口的简单性不一样)。
-
可演化性(evolvability)
使工程师在未来能轻松地对系统进行更改,当需求变化时为新应用场景做适配。也称为可伸缩性(extensibility)、可修改性(modifiability)或可塑性(plasticity)。
《设计数据密集型应用》读书笔记-第一章:可靠性、可伸缩性和可维护性