根据CAP理论,一致性(C),可用性(A),分区容错性(P),三者不可兼得,必须有所取舍。
而传统数据库保证了强一致性(ACID模型)和高可用性,所以要想实现一个分布式数据库集群非常困难,这也解释了为什么数据库的扩展能力十分有限。
而近年来不断发展壮大的NoSQL运动,就是通过牺牲强一致性,采用BASE模型,用最终一致性的思想来设计分布式系统,从而使得系统可以达到很高的可用性和扩展性。
但是,对于CAP理论也有一些不同的声音,数据库大师Michael Stonebraker就撰文《Errors in Database Systems, Eventual Consistency, and the CAP Theorem》,表示为了P而牺牲C是不可取的。
事实上,数据库系统最大的优势就对一致性的保证,如果我们放弃了一致性,也许NoSQL比数据库更有优势。
那么,有没有可能实现一套分布式数据库集群,即保证可用性和一致性,又可以提供很好的扩展能力呢?回答是:有的。
目前,有很多分布式数据库的产品,但是绝大部分是面向DSS类型的应用,因为相比较OLTP应用,DSS应用更容易做到分布式扩展。
Michael Stonebraker提到了一种新型的数据库VoltDB,它的定义是Next-Generation SQL Database for Fast-Scaling OLTP Applications。
虽然产品还没有问世,但是从技术资料上来看,它有几个特点:1.采用Share nothing架构,将物理服务器划分为以CPU core为单位的Virtual node,采用Sharding技术,将数据自动分布到不同的Virtual node,最大限度的利用机器的计算资源;2.采用内存数据访问技术,类似于内存数据库(In-memory database),区别于传统的数据库(Disk-based database),消除了传统数据库内存管理的开销,而且响应速度非常快;3.每个Virtual node上的操作是自治的,利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销(比如Latch和Lock);4.数据同步写多个副本,不存在单点故障,而且消除了传统数据库需要记录redo log的开销。
V oltDB与传统数据库的对比,可以看到V oltDB即支持传统数据库的ACID模型,又提供了类似NoSQL产品很高的扩展能力。
这个产品,让我想到了MySQL cluster,同样是shared-nothing架构,NDB存储引擎也要求将数据存放在内存中,数据根据PK被分布到多个不同的节点上,同一份数据可以保存多个副本,防止单点故障。
MySQL cluster目前的主要问题是性能不佳,但是我认为MySQL cluster的架构是分布式数据库未来的趋势,Oracle收购MySQL后,很多人对MySQL的前途表示担忧,而我作为一个用户,除了可能会收费这件事以外,我一点也不担心MySQL的前景,反而有所期待,因为在数据库领域没有任何一个公司比Oracle更懂数据库,而Oracle也正在大力发展MySQL cluster,MySQL cluster一定会成为分布式数据库领域内最好的解决方案之一。
NoSQL数据库异军突起,随着Digg和大型应用不断采取NoSQL,NoSQL运动已经蓬勃发展,NoSQL数据库很多,如何对他们分类,以便方便地根据自己应用特色选择不同的NoSQL数据库呢?NoSQL = HVSP 无(传统关系数据库的)join或明显事务的高容量简单处理。
按照数据模型保存性质将当前NoSQL分为四种:1.Key-value stores键值存储, 保存keys+BLOBs (二进制大对象Binary Large OBjects)2.Table-oriented 面向表, 主要有Google的BigT able和Cassandra.3.Document-oriented面向文本, 文本是一种类似XML文档,MongoDB 和CouchDB4.Graph-oriented 面向图论. 如Neo4J.NoSQL一般都是分布式数据库,高性能是其特点,因此,数据是如何被分布、复制/碎片以及合成就成为关键,这其中涉及你的应用对数据一致性的要求,见CAP原理,不同一致性处理方式决定不同类型:1.基本上基于Dynamo. 核心思想就是在多个节点之间获得最终一致性就可以,即使你有时会读到脏数据. 好处是写数据时从来不会阻塞。
那种强制性节点一致性,如2PC,两段事务提交将会让你的写关闭停顿,使用Dynamo-like风格你能将数据写到多个节点中,通过一致hashing,然后你可以从这些节点读取数据,返回正确结果给用户。
2.基本基于BigT able. 这种模型中,使用常用方式保持节点充分的一致性。
比如同步复制,由数据自己活或数据所在位置来实现一致性,不同产品实现细节不一样。
比如:MongoDB有一个面向文本类型的数据模型, 它采取类似BigTable-like 复制策略;Cassandra有面向表table-like数据模型, 采取的是Dynamo-like风格.以后应该有数据是如何被持久化保存到磁盘上的区分,不同NoSQL处理策略不一样,有的是写一次保存一次;有的是定期保存,后者性能要好些。
←NoSQL数据库最终一致性/BASE VS ACID→CAP理论六月22nd, 2010 · No Comments ·存储&NoSQL作者: 阎斌| 可以转载, 但必须以超链接形式标明文章原始出处和作者信息网址: 10年前,Eric Brewer教授提出了非常著名的CAP理论,后人也论证了CAP理论的正确性。
CAP理论指出:一个分布式系统不可能同时满足一致性(Consistency),可用性(Availibility)和分区容忍性(Partition Tolerance)这三个需求。
最多只能同时满足其中的两个。
▪一致性(Consistency):对于分布式的存储系统,一个数据往往会存在多份。
简单的说,一致性会让客户对数据的修改操作(增/删/改)要么在所有的数据副本(在英文文献中常称为Replica)全部成功,要么全部失败。
即,修改操作对于一份数据的所有副本而言,是原子(Atomic)的操作。
如果一个存储系统可以保证一致性,那么则客户读写的数据完全可以保证是最新的。
不会发生两个不同的客户端在不同的存储节点中读取到不同副本的情况。
▪可用性(Availability):可用性很简单,顾名思义,就是指在客户端想要访问数据的时候,可以得到响应。
但是注意,系统可用(Available)并不代表存储系统所有节点提供的数据是一致的。
比如客户端想要读取文章评论,存储系统可以返回客户端数据,但是评论缺少最新的一条。
这种情况,我们仍然说系统是可用的。
往往我们会对不同的应用设定一个最长响应时间,超过这个响应时间的服务我们仍然称之为不可用的。
分区容忍性(Partition Tolerance):如果你的存储系统只运行在一个节点上,要么系统整个崩溃,要么全部运行良好。
一旦针对同一服务的存储系统分布到了多个节点后,整个存储系统就存在分区的可能性。
比如,两个存储节点之间联通的网络断开(无论长时间或者短暂的),就形成了分区。
对当前的互联网公司(例如Google)来说,为了提高服务质量,同一份数据放置在不同城市乃至不同国家是非常正常的。
因此节点之间形成分区也很正常。
Gilbert 和Lynch将分区容忍性定义如下:No set of failures less than total network failure is allowed to cause the system to respond incorrectly除全部网络节点全部故障以外,所有子节点集合的故障都不允许导致整个系统不正确响应。
我在另外一篇文章(BASE: An Acid Alternative)中找到了一个对分区容忍性更为恰当好理解的解释:Operations will complete, even if individual components are unavailable. (即使部分的组件不可用,施加的操作也可以完成)CAP说明:在设计一个分布式存储系统时,你不得不在三个特性中选择放弃一个。
如果选择Partition Tolerance和Consistency,那么即使坏了节点,操作必须又一致,又能顺利完成。
所以就必须100%保证所有节点之间有很好的连通性。
这是很难做到的。
最好的办法就是将所有数据放到同一个节点中。
但是显然这种设计是不满足Availability的。
如果要满足Availability和Consistency,那么,为了保证可用,数据必须要有Replica。
这样,系统显然无法容忍Partition。
当同一数据的两个副本(Replica)分配到了两个无法通信的Partition上时,显然会返回错误的数据。
最后看一下满足Availability和Partition Tolerance的情况。
满足可用,就说明数据必须要在不同节点中有replica。
然而还必须保证在产生Partition的时候仍然操作可以完成。
那么,必然操作无法保证一致性。
基于ACID的关系型数据库选择的是C和P。
因此能够提供很高的一致性,但是却在系统繁忙的时候不可用(Service Unavailable)。
但是对于大多数互联网应用来讲,强一致性对他们来说并不一定非要满足,可用性往往是更加重要的。
比如,某博客网站在北京和上海的存储服务器突然不联通,北京用户和上海用户无法看到对方的评论显然要比北京用户和上海用户访问网站都返回HTTP 500错误要好的多。
当然,对于银行这种业务来讲,一致性是不能放弃的。
这不在我们的讨论范围之内。