DDIA(一)

2022-04-14  本文已影响0人  冰菓_

可靠性,可扩展性,可维护性

1. 认识数据系统

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

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

  1. 存储数据,以便自己或其他应用程序之后能再次找到 (数据库,即 databases)
  2. 记住开销昂贵操作的结果,加快读取速度(缓存,即 caches)
  3. 允许用户按关键字搜索数据,或以各种方式对数据进行过滤(搜索索引,即 search indexes)
  4. 向其他进程发送消息,进行异步处理(流处理,即 stream processing)
  5. 定期处理累积的大批量数据(批处理,即 batch processing)

2. 可靠性

每个人的脑子里都有一个直观的认识,即什么意味着可靠或者不可靠.对于软件典型的期望包含:

  1. 应用程序执行用户所期望的功能'
  2. 可以容忍用户出现错误或者不正确的软件使用方法
  3. 性能可以应对典型场景,合理负载压力和数据量
  4. 系统可防止任何未经授权的访问和滥用

定义

  1. 造成错误的原因叫做故障(fault),能预料并应对故障的系统特性可称为容错(fault-tolerant)或者韧性(resilient)。讨论容错时,只有讨论特定类型的错误
  2. 故障(fault)不同于失效(failure):故障指的是一部分状态偏离标准,而失效则是系统作为一个整体停止向用户提供服务。
  3. 通常倾向于容忍错误(而不是阻止错误),但也有预防胜于治疗的情况(比如安全问题)
硬件故障
  1. 加单个硬件的冗余度
  2. 云平台的设计是优先考虑灵活性和弹性,而不是单机可靠性。
  3. 硬件冗余的基础上进一步引入软件容错机制
软件错误
  1. 这类软件故障的bug 通常潜伏很长时间,直到被异常情况触发为止。往往是某个假设出于某种原因最后不在成立了。
  2. 解决办法:仔细考虑系统中的假设和交互;彻底的测试;进程隔离;允许进程崩溃并重启;测量、监控并分析生产环境中的系统行为。
人为失误

设计并构建了软件系统的工程师是人类,维持系统运行的运维也是人类。即使他们怀有最大的善意,人类也是不可靠的。尽管人类不可靠,但怎么做才能让系统变得可靠?最好的系统会组合使用以下几种办法:

  1. 以最小化犯错机会的方式设计系统。例如,精心设计的抽象、API 和管理后台使做对事情更容易,搞砸事情更困难。但如果接口限制太多,人们就会忽略它们的好处而想办法绕开。很难正确把握这种微妙的平衡。
  2. 将人们最容易犯错的地方与可能导致失效的地方 解耦(decouple)。特别是提供一个功能齐全的非生产环境 沙箱(sandbox),使人们可以在不影响真实用户的情况下,使用真实数据安全地探索和实验。
  3. 在各个层次进行彻底的测试【3】,从单元测试、全系统集成测试到手动测试。自动化测试易于理解,已经被广泛使用,特别适合用来覆盖正常情况中少见的 边缘场景(corner case)。
  4. 允许从人为错误中简单快速地恢复,以最大限度地减少失效情况带来的影响。 例如,快速回滚配置变更,分批发布新代码(以便任何意外错误只影响一小部分用户),并提供数据重算工具(以备旧的计算出错)。
  5. 配置详细和明确的监控,比如性能指标和错误率。 在其他工程学科中这指的是 遥测(telemetry)(一旦火箭离开了地面,遥测技术对于跟踪发生的事情和理解失败是至关重要的)。监控可以向我们发出预警信号,并允许我们检查是否有任何地方违反了假设和约束。当出现问题时,指标数据对于问题诊断是非常宝贵的。
  6. 良好的管理实践与充分的培训
可靠性的重要性

3. 可扩展性

定义

可扩展性(Scalability)是用来描述系统应对负载增长能力的术语

描述负载
描述性能
  1. 当描述好负载以后,问题变成了:
    a. 增加负载参数并保持系统资源不变时,系统性能将受到什么影响?
    b. 增加负载参数并希望性能不变时,需要增加多少系统资源?
  2. 批处理系统,通常关心吞吐量(throughput);在线系统,通常更关心响应时间(response time)
  3. 对于系统响应时间而言,最好用百分位点,比如中位数、p99 等标识。
  4. 测量客户端的响应时间非常重要(而不是服务端),比如会出现头部阻塞、网络延迟等。
  5. 实践中的百分位点,可以用一个滑动的时间窗口(比如 10 分钟)进行统计。可以对列表进行排序,效率低的话,考虑一下前向衰减,t-digest 等方法近似计算。

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

百分位点通常用于 服务级别目标(SLO, service level objectives) 和 服务级别协议(SLA, service level agreements),即定义服务预期性能和可用性的合同。 SLA 可能会声明,如果服务响应时间的中位数小于 200 毫秒,且 99.9 百分位点低于 1 秒,则认为服务工作正常(如果响应时间更长,就认为服务不达标)。

应对负载的方法
  1. 纵向扩展:转向更强大的机器
  2. 横向扩展:将负载分布到多台小机器上
  3. 弹性系统:检测到负载增加时自动增加计算资源
  4. 跨多台机器部署无状态服务比较简单,但是把带状态的数据系统从单节点变成分布式配置则可能引入许多额外复杂度。因此,应该尽量将数据库放在单个节点上。

4. 可维护性

  1. 可运维性(Operability):便于运维团队保持系统平稳运行
  2. 简单性(Simplicity):从系统中消除尽可能多的 复杂度(complexity),使新工程师也能轻松理解系统(注意这和用户接口的简单性不一样)
  3. 可演化性(evolvability):使工程师在未来能轻松地对系统进行更改,当需求变化时为新应用场景做适配。也称为 可伸缩性(extensibility)、可修改性(modifiability) 或 可塑性(plasticity)
可运维性
简单性
可演化性
上一篇下一篇

猜你喜欢

热点阅读