关系型数据库到底有什么问题?数据库
正如不少人可能已经知道的,关系型数据库(RDB)技术自从1970年代就已经存在,直到1990年代末一直是结构化存储的事实标准。RDB几十年来很出色地支持了高度一致性事务的工做负载,并依然保持强劲。随着时间的推移,该项古老的技术为应对客户的需求得到了新的能力,好比BLOB存储、XML/文档存储、全文检索、在数据库中执行代码、使用星形数据结构的数据仓库、以及地理空间扩展。网络
只要一切都能挤进关系型数据结构的定义中,而且适合于单机,就能够在关系型数据库中实现。数据结构
然而,互联网的商业化发生了,而且完全改变了一切,使得关系型数据库再也不可以知足全部的存储需求。相比于一致性,可用性、性能和扩展正在变得一样重要——有时甚至更重要。异步
性能一直很重要,可是随着互联网商业化的出现,改变的是规模。事实证实,要达到规模化的性能,要求的技巧和技术是前互联网时代没法接受的。关系型数据库围绕着ACID(原子性Atomicity、一致性Consistency、隔离性Isolation和持久性Durability)的概念而创建,实现ACID最简单的方法就是把一切保持在单机上。所以,传统的RDB规模化的方法是垂直扩展(scale up),用白话说,就是使用更大的机器。分布式
哦-哦,我想我须要一台更大的机器。oop
使用一台更大的机器的解决方案一直很好,直到互联网带来的负载大到单机没法处理。这迫使工程师们想出巧妙的技术来克服单机的限制。有许多不一样的方法,各有其优缺点:主—副、集群、表联合与分区(table federation and partitioning)、水平分区(sharding,能够认为是分区的特例)。性能
致使数据存储选项增长的另一个因素是可用性。大数据
前互联网时代的系统,其用户一般是来自组织的内部,这就有可能在非工做时段设置有计划的停机时间,甚至计划外的宕机也只会形成有限的影响。商业化互联网也改变了这一点:如今每一个可以访问互联网的人都是潜在用户,因此计划外的宕机会形成极可能更大的影响,并且互联网的全球性致使很难肯定非工做时段,并安排有计划的停机。优化
我曾探讨了冗余在实现高可用性中所起的做用。不过,当应用到数据存储层时,冗余带来了一系列新的有趣的挑战。在数据库层应用冗余最经常使用的方式是主/副配置。网站
这个看似简单的设置,在与传统的单机关系型数据库比较时,有一个巨大的差别:咱们如今有网络隔离的多台机器。当数据库的写操做发生时,咱们如今要决定什么时候认为它完成了:只要保存到主数据库,或者只要保存到副数据库(或者甚至是n个副数据库,若是咱们想要得到更高的可用性--欲知增长另外一台机器对整个可用性的影响,请参看本博客系列的第一部分)。若是咱们决定保存到主数据库就足够了,在复制数据以前若是主数据库失效,咱们要承担丢失数据的风险。若是咱们决定等到数据复制完成,咱们就要接受延迟的代价。在副数据库宕机的罕见状况下,咱们须要决定是继续接受写操做的请求,仍是拒绝它。
所以,咱们从一个默认一致性的世界,进入了一个一致性是一种选择的世界。在这个世界里,咱们能够选择接受所谓的最终一致性,即,状态在多个节点之间复制,可是并不是每一个节点都有整个状态的完整视图。在咱们上面的示例配置中,若是咱们选择认为达到主数据库就是写操做完成(或者到达主数据库和任一副数据库,但不必定是两个副数据库),那么咱们就是选择了最终一致性。最终,由于每一个写操做会被复制到每一个副数据库。可是在任一时间点,若是咱们查询某一个副数据库,咱们没法保证它包含截止到那个时刻为止的全部写操做。
CAP理论
总而言之,当数据存储被复制(也称为分隔(partitioned))时,系统的状态被分散。这意味着咱们离开了温馨的ACID领域,进入CAP的美丽新世界。CAP理论是由加州伯克利分校的Eric Brewer博士在2000年提出的。它最简单的形式是这样的:一个分布式系统必须在一致性、可用性和分隔容忍度(Partition Tolerance)之间取舍,而且只能作到三者中的二者。
CAP理论把关于数据存储的讨论扩展到超出ACID的范围,激发了许多非关系型数据库技术的诞生。在提出他的CAP理论的10年以后,Brewer博士发表了一份声明,澄清他最初的“三选二”的观点被极大地简化,是为了引发讨论,并有助于超越ACID。不过,这种极大的简化,引起了无数的曲解和误会。在对CAP更精细的解释中,全部三个维度应当理解为范围,而不是布尔值。此外,应当理解,分布式系统大部分时间工做在非分隔模式,在这种状况下,须要作出一致性和性能/延迟之间的折中。在分隔真的发生的罕见状况下,系统必须在一致性和可用性之间作出选择。
联系到咱们以前的主/副例子,若是选择认为只有当数据在全部地方被复制(也称做同步复制)以后写操做才算完成,咱们就是以写操做延迟为代价选择了一致性。另外一方面,若是选择认为一旦数据保存到主数据库中,就认为写操做完成,并让复制在后台进行(也称做异步复制),咱们就是以牺牲一致性为代价选择了性能。
当网络分隔发生时,分布式系统进入特殊的分隔模式,在一致性和可用性之间取舍。回到咱们的例子:多个副数据库在失去与主数据库的链接以后,可能仍然继续提供查询服务,就是以牺牲一致性为代价选择了可用性。要么,咱们能够选择,主数据库若是失去与副数据库的链接,就应当中止接受写操做的请求,所以就是以牺牲可用性为代价选择了一致性。在商业化互联网时代,选择一致性一般意味着收入的损失,因此不少系统选择可用性。在这种状况下,当系统恢复到正常状态时,它能够进入恢复模式,全部积累的不一致性获得解决和复制。
趁咱们还在谈论恢复模式,值得说一说一种称为主—主(或主动—主动)的分布式数据存储配置。在这种设置中,写操做能够发送到多个节点,而后再互相复制。在这样的系统中,即便是正常的模式也变得复杂了。由于,若是对同一条数据的两个更新在大体相同的时间发生在两个不一样的主节点上,要如何协调呢?不只如此,若是这样的系统不得不从一个分隔的状态恢复,事情就变得更糟了。虽然有可能存在可行的主—主配置,并且也有一些产品使之更容易,个人建议是除非绝对必要,不然尽可能避免。有不少方法能够实现性能和可用性的良好平衡,而没必要须要负担主—主配置的高复杂度性的成本。
许多现代数据存储的常见模式
提供的性能/规模和可用性良好搭配的一种常见方法,是结合分隔和复制造成一种配置(或者说是模式)。这有时被称为分隔的副本集合(partitioned replica set)。
不管是Hadoop、Cassandra或者MongoDB集群,全部这些基本上都符合这种模式,许多AWS数据服务也是如此。让咱们了解一下分隔的副本集合的一些共同特征:
数据是跨多个节点(或者多个节点集群)分隔的(即,分开的)。没有单一分区拥有全部的数据。单个写操做只发送到一个分区。多个写操做有可能发送到多个分区,所以应当彼此独立。复杂的、事务性、多条记录(所以可能涉及多分区)的写操做应当避免,由于这样可能影响整个系统。
单个分区可以处理的最大数据量可能成为潜在的瓶颈。若是一个分区达到它的带宽上限,增长更多的分区以及拆分横跨其间的流量,有助于解决该问题。所以,能够经过增长更多的分区来扩展这种类型的系统。
一个分区的索引(key)用来分配各个分区的数据。你须要当心选择分区的索引,这样让读操做和写操做尽量平均“分布”在全部的分区。若是读/写操做发生汇集,这些操做可能超出某个分区的带宽,进而影响整个系统的性能,而其它分区则并未充分利用。这被称为“热分区”问题。
数据在多台主机之间复制。这能够是,每一个分区是彻底分开的副本集合,或者在同一组主机之上的多个副本集合。一条数据被复制的次数一般被称为复制因子。
这样的配置拥有内置的高可用性:数据被复制到多个主机。理论上,若干小于复制因子数量的主机发生故障,不会影响整个系统的可用性。
全部这些好处,以及内置的可扩展性和高可用性,伴随着相应的代价:这再也不是你的瑞士军刀,单机的关系型数据库管理系统(RDBMS)了。这是复杂的系统,有不少须要管理的可变更的部分和须要微调的参数。须要专业知识来设置、配置和维护这些系统。此外,须要监测和报警的基础设施来确保它们的正常运做。你固然能够本身作,但不容易,你可能短期没法搞定。
丰富的数据存储,虽然引发一些选择困难,但实际上是好事。咱们只需超越传统的整个系统只有单个数据存储的想法,接受系统中使用多种数据存储、每一个为它最适合的工做负载提供服务这样的思惟方式。例如,咱们可使用下面的组合:
高性能摄入队列,来获取输入点击流量
基于Hadoop的点击流量处理系统
基于云的对象存储,用来低成本、长期地存储通过压缩的平常点击流量摘要
保存元数据的关系型数据库,可供咱们用于充实点击流量的数据
用于分析的数据仓库集群
用于天然语言查询的搜索集群
上面全部这些均可以是某个单一子系统的组成部分,好比叫作网站分析平台。
总结
商业化互联网带来扩展和可用性的需求,而RDBMS这样的瑞士军刀再也没法知足这样的需求。
对数据存储增长水平扩展和冗余加大了系统复杂度,使得ACID更加难以保证,迫使咱们按照CAP理论考虑取舍,创造了许多优化和专业化的有趣机会。
在系统中使用多个数据存储,每一个为与其最适当的工做负载提供服务。
现代数据存储是复杂的系统,要求特殊的知识和管理开销。