如何设计一个数据密集型应用

184 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情 >>

一个应用除了要满足功能性需求之外,也要对一些非功能性需求进行考虑。

数据库:数据管理系统,电子化的文件柜,可以进行增删改查,典型如MySQL

消息队列:通信方式,比如RabbitMQ、RocketMQ、 Kafka、Pulsar

缓存:临时文件柜,比如Redis

通常一个系统会有数据库/消息队列/缓存,作为技术支撑。由于近几年的技术发展,这三者的界限越来越模糊——数据存储可以被当成消息队列用(Redis),消息队列则带有类似数据库的持久保证(Apache Kafka)。

设计一个数据密集型应用需要考虑以下三点:

  • 可靠性(Reliability)

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

    • 口语化:“即使出现问题,也能继续正确工作”

    • 问题被称为故障,解决这个故障被称之为“容错”。容错技术可以对东段用户隐藏某些类型的故障。

    • 典型的故障:

      • 硬件故障:硬盘崩溃、内存出错、机房断电、拔网线
      • 软件错误:错误输入,用尽资源,级联故障,错误响应
      • 人为错误:人类是不靠谱的
  • 可伸缩性(Scalability)

    • 定义:有合理的办法应对系统的增长(数据量、流量、复杂性)

    • 负载增加可能会导致服务降级

      • 纵向伸缩(scaling up,也称为垂直伸缩,即 vertical scaling,转向更强大的机器)
      • 横向伸缩(scaling out,也称为水平伸缩,即 horizontal scaling,将负载分布到多台小机器上)
  • 可维护性(Maintainability)

    • 在设计之初就尽量考虑可操作性,简单性,可演化性,尽可能减少维护期间的痛苦,从而避免自己的软件系统变成遗留系统。
    • 许多不同的人(工程师、运维)在不同的生命周期,都能高效地在系统上工作(使系统保持现有行为,并适应新的应用场景)。

参考:

数据密集型应用系统设计 中文翻译(github.com/Vonng/ddia