《数据密集型应用系统设计》章节总结 第一章 可靠、可扩展与可维护的应用系统

数据密集型系统的概念(相对于计算密集型系统),性能瓶颈通常不在于CPU的性能,而是在于数据量,复杂度,多变性。

认识数据系统

数据库、队列、缓存都可以视为数据系统,且三者之间的界限越发模糊,现有的缓存如redis,消息队列如kafka都提供了数据持久化功能,因此使得三者之间越来越接近;除此之外,多种组件可以组合使用,提供同一的对外接口,例如可以用redis作为MySql数据库的缓存。

设计数据系统时,应当着重关注的三个问题:

  • 可靠性
  • 可扩展性
  • 可维护性

可靠性

可靠性为系统容忍故障的能力,也可以称为弹性。通常来说可靠性强调“容忍”大于“预防”,不过对于防止敏感数据被窃取等场景除外。

影响系统可靠性常见的原因包括:硬件故障、软件故障、人为失误。

硬件故障

硬件故障包括:硬盘故障、内存故障、停电等,对应的解决措施通常为冗余,包括RAID、ECC校验、备用电源等具体措施。

但是由于分布式计算、云计算等场景要求,软件容错具有相对于硬件更好的优势。

软件故障

典型的软件故障有:程序bug、程序占据资源但跑飞等,软件故障通常会长时间潜伏,只在特定场景触发。

人为失误

据统计,运维人员工作失误是系统下线的主要原因,硬件问题占比较小,减少运维人员失误的方式包括:设计具有更好抽象接口的管理系统、建立模拟用沙箱、充分测试程序、建立恢复与监控系统、加强培训等。

可靠性的重要性

可靠性不仅仅是对于核电站、空管系统等敏感部门有意义,对于私人数据,例如老照片等也具有极大的意义。

可扩展性

可扩展性为系统应付负载增加的能力

描述负载

负载通常通过负载参数描述,可以具有不同的形式,例如Web服务器的qps,聊天室的在线用户数、缓存的命中率等指标;并且负载参数有时侧重平均值,有时侧重峰值或极端值。

Twitter的推文的推拉模式。

描述性能

面向两种不同场景,采用不同的性能描述方式:

  • 批处理系统:吞吐量(throughput)
  • 在线服务:响应时间(response time)

ps:响应时间大于延迟,延迟仅为程序处理请求的时间,响应时间包括延迟、网络延迟、排队延迟等

响应时间也具有不同的表示形式:

  • 平均响应时间
  • 百分位数(percentiles):包括P50(平均值)、P99、P999等

响应时间通常具有长尾效应,因此需要P99等指标监测,对于重要客户大笔交易产生的较长响应时间能够有更好的表示,从而方便优化。

排队延迟在响应时间中具有很大比例,因此在客户端监测包括延迟在内的响应时间很必要。

应对负载增加的方法

通常为特定级别设计的系统无法承载超出预期十倍的实际负载,因此需要进行扩展,主要包括:

  • 垂直扩展:提升单机性能
  • 水平扩展:增加机器数量

通常提升单机性能的成本随着性能提升指数增长,可扩展空间有限,最终水平扩展无法避免,水平扩展可以应用弹性扩展,自动检测负载增加,进行资源调配,例如k8s等。

不同类型的系统也需要设计不同的扩展策略,例如每秒钟100000次1KB请求的系统和每秒钟3次2GB系统的设计思路显然应该不同。

可维护性

软件的主要成本不在于最初开发,而在于后期的维护与修复,对于可维护性主要考虑以下方面:

  • 可运维性:易于使用
  • 简单性:易于学习
  • 可演化性:易于改进

可运维性:运维更轻松

通常运维人员工作包括:检测系统状况、寻找问题、更新系统、服务迁移等,数据系统建立时也应当考虑:提升可观测性、支持自动化、提升跨平台能力等。

简单性:简化复杂度

项目体积的增大会使得项目成为“屎山”,导致依赖更为复杂,模块之间耦合度增加等。通常解决复杂性问题的良好方式为抽象,例如高级语言作为汇编的抽象,操作系统作为IO、进程的抽象等,但是设计良好的抽象具有较大的难度。

可演化性:易于改变

系统需求经常变化,可演化性的目标就是使得数据系统易于修改,从而使其能够适应不断变化的需求。

你可能感兴趣的:(《数据密集型应用系统设计》章节总结 第一章 可靠、可扩展与可维护的应用系统)