现在的应用程序大多是数据密集型的,而非计算密集型的。因此 CPU 很少成为这类应用的瓶颈,更大的问题通常来自数据量、数据复杂性、查询性能、数据类型的支持以及数据的变更速度。
下面是一个常见的数据密集型的系统架构,系统中包含了缓存、主数据库、全文索引和消息队列等组件。任何一个组件出问题都会对整个系统有影响。
设计上面的系统会遇到许多棘手的问题,例如缓存、主数据库、全文索引的一致性、不同组件的容错能力、消息队列的时延、负载增加如何扩容等一系列问题。可以将问题抽象为三类:
- 可靠性(reliability)
系统在困境「硬件故障、软件错误、人为错误等」中仍可以正常工作「正确完成功能,并能达到期望的性能水平」。
- 可伸缩性(scalability)
有合理的方法应对系统的增长(数据量、流量、复杂性)。系统可以可靠运行,并不意味着一直可以可靠运行。当系统的负载增加「用户从一万增长到一百万」,系统会变得不可靠。
常见应对负载的方法有纵向伸缩「转向配置更高的机器」和横向伸缩「将负载分布到多台机器上」。使用纵向伸缩的优点在于操作简单,无需引入额外的复杂度;缺点则是需要面对高昂的机器成本,且机器的配置是存在上限的。横向伸缩的优点是降低了机器成本;缺点则是从单点到分布式引入了额外的复杂度,系统维护成本变高。
- 可维护性(maintainability)
许多不同的人(工程师、运维)在不同的生命周期,都能高效地在系统上工作(使系统保持现有行为,并适应新的应用场景)。
随着软件的不断迭代,会修复漏洞、为新的场景增加修改、兼容接口增加 hack 逻辑、为了性能写一些不可读的代码。种种这些操作都会使系统的可维护性变差。
在后续的文章中,将会介绍不同的数据库是如何保证可靠性、可伸缩性、可维护性的。