前言
如果你是一位软件行业从业者,尤其是从事服务器端或者后台系统软件开发,相信近年来一定被层出不穷的商业名词所包围:NoSQL、Big Data、Web-scale、Sharding、Eventual consistency、ACID、CAP理论、云服务、MapReduce和Real-time等,所有这些其实都围绕着如何构建高效存储与数据处理这一核心主题。
过去十年,在数据库领域与分布式系统方面涌现了许多引人瞩目的进展,由此深刻地影响了如何构建上层应用系统。分析这些激动人心的变化背后,你会发现有以下几个非常重要的驱动因素:
• 互联网公司,包括Google、Yahoo! 、Amazon、Facebook、LinkedIn、Microsoft,以及Twitter等,它们每天都在面对海量数据和负载,迫使其不断创新,并改进支撑系统以更有效地处理这种量级的数据。
• 商业方面因素,如敏捷开发、测试驱动和对市场机会做出快速反应等,都要求尽量缩短产品开发周期,因此系统中的数据模型也要足够灵活以方便调整。
• 免费及开源软件现在已经非常成功,在很多领域足以取代商业或者定制软件。
• 硬件方面,CPU主频增长日趋缓慢,而多核系统成为新常态,网络速度则依旧保持快速发展,这就意味着并行分布式系统将会成为业界主流。
• 如今一个不起眼的小公司,也完全有能力构建起大型分布式系统:跨机器甚至跨地域的数据中心,因为现在有了逐渐普及的IaaS云服务(例如AWS)。
• 很多服务现在都要求高可用。道理很简单,系统失效或者维护时间越长,其损失代价越大,甚至大到无法承受。
正是由于这些技术,“数据密集型应用”(>目前已经有足够丰富的技术或者工具来辅助、帮助我们开发自己的数据密集型应用,包括存储、处理等方面,而这些技术本身也在快速演进之中。例如很多人在关注新的NoSQL系统,但实际上消息队列、缓存、搜索引擎、批处理与流处理框架等相关技术也非常重要,事实上,很多应用系统总是会集成组合上述多种技术。
开篇所罗列的那一堆商业味颇浓的名词,某种程度上也彰显了当前大时代氛围,机会多自是好事。然而,作为一名软件工程师或者架构师,仍需秉持严谨的态度,深入理解繁杂词汇背后系统设计所面临的优劣权衡,只有这样才能为我所用,构建好自己的系统。所以,抛开那些商业名词,我们要的是深入的探索。
幸好,软件千变万化,终有若干理念贯穿其中。无论你用的什么数据系统,如果可以掌握背后的设计理念,何种工具适用于何种场景,如何最佳使用,又有哪些陷阱(坑),诸如此类,自然会胸有成竹,而这也是本书写作的初衷。
所以,本书旨在帮助大家更好地驾驭处理数据和存储数据相关技术。它不是针对某个特定软件的介绍手册,也不是纯理论的习题。我们会深入探讨一些成功的数据系统案例,剖析其中的技术要点;或许在很多流行的分布式系统里都有它们的身影,正是这些关键技术有效应对了许多生产环境对扩展性、性能和可靠性的苛刻要求。
我们将对这些典型系统深入展开讨论,梳理其核心算法,探讨其设计理念和背后的权衡之道。在此过程中,尝试总结某些经验法则来重新审视系统架构。了解怎么工作自然重要,但更重要的是要思考它为什么这样工作,正所谓“知其然,知其所以然”。
读完本书之后,你应该会对哪些技术适用于哪些场景,常见工具如何搭配来构建应用系统等有所得。或许你不会马上就决定动手开发一个全新的数据库引擎(这几乎完全不需要),但是,关于系统的本质,相信你一定有新的认识与判断力:系统行为是否合理,架构设计如果权衡,个中症状如何处理等,将会更加游刃有余。
本书适合哪些读者?
首先你的应用如果包含服务器端、后台逻辑来存储、处理数据,或者你的应用需要联网,例如Web程序、移动程序以及联网的传感器等,这本书将非常适合。
本书主要针对软件工程师、软件架构师以及技术经理等,特别是那些需要对系统架构做出权衡决定的人,例如需要选择一些工具和软件来解决特定问题,或者如何最佳适用这些现有工具。退一步,如果不需要做这些决定,本书也可以帮助你更好地理解这些技术的优缺点。
当然你最好有一些Web程序或者网络程序的经验,了解一些基本的关系型数据和SQL;虽然不是必须,但如果通晓NoSQL或相关系统,那再好不过。如果有常见网络协议如TCP、HTTP等基本知识也会帮助很大。选择何种编程语言或者框架对于阅读本书没有太大影响。
如果以下若干条适用于你,可能会从本书中有所获益:
• 需要学习了解系统扩展性方面技术,例如支撑百万用户级的Web和移动程序。
• 需要构建高可用(减少宕机影响)和健壮运行的系统 。
• 需要有效方法来提高长时间运行系统的可维护性,应对规模增长、技术和需求不断发生变化等。
• 对系统如何工作有种天然的兴趣或者探索精神,特别是大型Web和在线系统。本书会例举若干典型数据库和数据处理、分析系统,对其设计亮点逐一展开分析,也是乐事一件。
当我在介绍可扩展的系统时,有人会问:“我又不是Google或者Amazon,这些高大上的扩展性太遥远,老老实实用关系数据库就得了。”在特定语境下这的确有道理,打造一个根本不需要的扩展性系统是在浪费精力,而且会丧失其他方面的灵活性,这其实是种过早的优化。然而我要说,选择何种工具也很有讲究或者说极其重要,不同的技术各有优劣,事实上正如本书将要揭示的,关系数据库很重要,但它并非解决数据问题的终极方案。
本书涵盖范围
本书不会就如何安装、配置特定软件包或者API等做太多细节介绍,这方面已有足够多的文档。我们会着重探讨不同的设计理念以及如何权衡,这些通常才是系统的核心,也会例举实践中不同的系统产品最终采用了哪些不同的理念。
本书的电子版已包含所有在线资源的链接,这些链接在书稿付梓之时都做了验证,然而大家都能理解,这些网络链接可能在一段时间之后会失效。如果不巧碰到了失效的链接,或者阅读的是纸质版本,可以随时用搜索引擎来查询相关资料。对于学术论文,推荐用Google Scholar搜索文献标题来下载PDF版本,或者随时访问https://github.com/ept/ddia-references,我们维护了所有最新的链接。
本书主要关注数据处理系统架构方面以及如何集成到数据密集型应用系统中。而关于部署、运营、安全、管理等相关方面,当然也非常重要和足够复杂,不过它们并非本书的重点,也无意做些肤浅的、聊胜于无的介绍,我们认为它们值得单独成书。
书中所涵盖的诸多技术总体都可以纳入到“大数据”的范畴。然而,大数据这个商业词汇有些过于滥用或者太模糊,不太适合在严谨的工程领域展开讨论。本书倾向于使用更加明确的用语,例如单节点、分布式系统,或者在线/交互式分析以及离线/批处理系统等。
本书更偏爱免费及开源软件(Free and Open Source Software,FOSS),主要是通过源码阅读、必要的修改,然后实地执行可以帮助理解系统究竟是如何工作的,此外开放系统也能减少对特定供应商的锁定问题。当然,我们并非局限于此,也会讨论相关商业软件,这包括闭源、软件即服务(Software as a Service)或者一些只出现在文献里但并未公开发行的一些公司内部软件等。
本书内容安排
全书分为三大部分:
1. 第一部分,主要讨论有关增强数据密集型应用系统所需的若干基本原则。首先开篇第1章即瞄准目标:可靠性、可扩展性与可维护性,如何认识这些问题以及如何达成目标。第2章我们比较了多种不同的数据模型和查询语言,讨论各自的适用场景。接下来第3章主要针对存储引擎,即数据库是如何安排磁盘结构从而提高检索效率。第4章转向数据编码(序列化)方面,包括常见模式的演化历程。
2. 第二部分,我们将从单机的数据存储转向跨机器的分布式系统,这是扩展性的重要一步,但随之而来的是各种挑战。所以将依次讨论数据远程复制(第5章)、数据分区(第6章)以及事务(第7章)。接下来的第8章包括分布式系统的更多细节,以及分布式环境如何达成一致性与共识(第9章)。
3. 第三部分,主要针对产生派生数据的系统,所谓派生数据主要指在异构系统中,如果无法用一个数据源来解决所有问题,那么一种自然的方式就是集成多个不同的数据库、缓存模块以及索引模块等。首先第10章以批处理开始来处理派生数据,紧接着第11章采用流式处理。第12章总结之前介绍的多种技术,并分析讨论未来构建可靠、可扩展和可维护应用系统可能的新方向或方法。