一、NoSQL介绍
NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。NoSQL网站:http://www.nosql-database.org
1、NoSQL数据库的四大分类
- 键值(Key-Value)存储数据库 :这一类数据库主要会使用到一个哈希表,这个表中有一个特定的键和一个指针指向特定的数据。Key/value模型对于IT系统来说的优势在于简单、易部署。但是如果DBA只对部分值进行查询或更新的时候,Key/value就显得效率低下了。 举例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.
- 列存储数据库:这部分数据库通常是用来应对分布式存储的海量数据。键仍然存在,但是它们的特点是指向了多个列。这些列是由列家族来安排的。如:Cassandra, HBase, Riak.
- 文档型数据库 :文档型数据库的灵感是来自于Lotus Notes办公软件的,而且它同第一种键值存储相类似。该类型的数据模型是版本化的文档,半结构化的文档以特定的格式存储,比如JSON。文档型数据库可 以看作是键值数据库的升级版,允许之间嵌套键值。而且文档型数据库比键值数据库的查询效率更高。如:CouchDB, MongoDb. 国内也有文档型数据库SequoiaDB,已经开源。
- 图形(Graph)数据库 :图形结构的数据库同其他行列以及刚性结构的SQL数据库不同,它是使用灵活的图形模型,并且能够扩展到多个服务器上。NoSQL数据库没有标准的查询语言(SQL),因此进行数据库查询需要制定数据模型。许多NoSQL数据库都有REST式的数据接口或者查询API。如:Neo4J, InfoGrid, Infinite Graph.
因此,我们总结NoSQL数据库在以下的这几种情况下比较适用:1、数据模型比较简单;2、需要灵活性更强的IT系统;3、对数据库性能要求较高;4、不需要高度的数据一致性;5、对于给定key,比较容易映射复杂值的环境。
2、NoSQL数据库的四大分类表格分析
3、共同特征
对于NoSQL并没有一个明确的范围和定义,但是他们都普遍存在下面一些共同特征:
- 不需要预定义模式:不需要事先定义数据模式,预定义表结构。数据中的每条记录都可能有不同的属性和格式。当插入数据时,并不需要预先定义它们的模式。
- 无共享架构:相对于将所有数据存储的存储区域网络中的全共享架构。NoSQL往往将数据划分后存储在各个本地服务器上。因为从本地磁盘读取数据的性能往往好于通过网络传输读取数据的性能,从而提高了系统的性能。
- 弹性可扩展:可以在系统运行的时候,动态增加或者删除结点。不需要停机维护,数据可以自动迁移。
- 分区:相对于将数据存放于同一个节点,NoSQL数据库需要将数据进行分区,将记录分散在多个节点上面。并且通常分区的同时还要做复制。这样既提高了并行性能,又能保证没有单点失效的问题。
- 异步复制:和RAID存储系统不同的是,NoSQL中的复制,往往是基于日志的异步复制。这样,数据就可以尽快地写入一个节点,而不会被网络传输引起迟延。缺点是并不总是能保证一致性,这样的方式在出现故障的时候,可能会丢失少量的数据。
- BASE:相对于事务严格的ACID特性,NoSQL数据库保证的是BASE特性。BASE是最终一致性和软事务。
NoSQL数据库并没有一个统一的架构,两种NoSQL数据库之间的不同,甚至远远超过两种关系型数据库的不同。可以说,NoSQL各有所长,成功的NoSQL必然特别适用于某些场合或者某些应用,在这些场合中会远远胜过关系型数据库和其他的NoSQL。
4、CAP理论
这个理论是由美国著名科学家,同时也是著名互联网企业Inktomi的创始人Eric Brewer在2000年PODC(Symposium on Principles of Distributed Computing)大会上提出的,后来Seth Gilbert 和 Nancy lynch两人也证明了CAP理论的正确性,虽然在后来近十年的时间很多人对CAP理论提出了很多异议,但是在NoSQL的世界中,它还是非常有参考价值的。它的意思是,一个分布式系统不能同时满足一致性,可用性和分区容错性这三个需求,最多只能同时满足两个。
C: Consistency 一致性
A: Availability 可用性
P:Partition Tolerance分区容错性
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
- C: Consistency 一致性
对于一致性,可以分为从客户端和服务端两个不同的视角。从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。
从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。
- A: Availability 可用性
对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。也就是,该系统使用的任何算法必须最终终止。当同时要求分区容忍性时,这是一个很强的定义:即使是严重的网络错误,每个请求必须终止。
好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。可用性通常情况下可用性和分布式数据冗余,负载均衡等有着很大的关联。
- P:Partition Tolerance分区容错性
分区容错性和扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。好的分区容错性要求能够使应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。比如现在的分布式系统中有某一个或者几个机器宕掉了,其他剩下的机器还能够正常运转满足系统需求,或者是机器之间有网络异常,将分布式系统分隔未独立的几个部分,各个部分还能维持分布式系统的运作,这样就具有好的分区容错性。
满足一致性,可用性的系统,通常在可扩展性上不太强大:传统关系型数据库。
满足一致性,分区容忍必的系统,通常用户操作响应上不太稳定:Redis、MongoDB、HBase等
满足可用性,分区容忍性的系统,通常可能对一致性要求低一些:使用在DNS上。
5、ACID和BASE的比较
传统关系型数据库系统的事务都有ACID的属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。
- 原子性: 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性: 在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
- 隔离性: 两个事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。 两个事务不会发生交互。
- 持久性: 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
由于CAP理论的存在,为了提高性能,出现了ACID的一种变种BASE:
- Basic Availability:基本可用
- Soft-state :软状态/柔性事务,可以理解为”无连接”的, 而 “Hard state” 是”面向连接”的
- Eventual consistency:最终一致性,最终整个系统(时间和系统的要求有关)看到的数据是一致的。
有趣的是,ACID的意思是酸,而BASE却是碱的意思,因此这是一个对立的东西。其实,从本质上来讲,酸(ACID)强调的一致性(CAP中的C),而碱(BASE)强调是可用性(CAP中的A)。
6、一致性模型
- 弱一致性(Weak):当你写入一个新值后,读操作在各个数据副本上不保证能读出最新值。比如:某些cache系统,网络游戏其它玩家的数据和你没什么关系。
- 最终一致性(Eventually):Eventually 是 Weak 的一种特殊情况。当你写入一个新值后,有可能读不出来,但在某个时间窗口之后保证最终能读出来。比如:DNS,电子邮件、Amazon S3,Google搜索引擎这样的系统。
- 强一致性(Strong):新的数据一旦写入,在任意副本任意时刻都能读到新值。比如:文件系统,RDBMS,Azure Table都是强一致性的。
从这三种一致型的模型上来说,我们可以看到,Weak 和 Eventually 一般来说是异步冗余的,而Strong一般来说是同步冗余的,异步的通常意味着更好的性能,但也意味着更复杂的状态控制。同步意味着简单,但也意味着性能下降。
7、数据一致性的实现技术
①Quorum 系统NWR 策略 :
NWR是一种在分布式存储系统中用于控制一致性级别的策略,应用于 Amazon Dynamo。NWR 模型将 CAP 的选择权交给了用户,由用户自己选择 CAP 中的哪两个。其中,N 代表 N 个备份,W 代表至少写 W 份才认为成功,R 代表至少要读 R 份才认为成功。
- 如果 W+R>N ,是可以保证强一致性的。因为 W+R > N, 所以 R > N-W,什么意思呢?就是读取的份数必须要大于未成功写的份数,这样至少能读到一份最新值。
- 如果 W+R<=N,则能够保证最终一致性。
- 如果我们要高可写的环境,我们可以配置 W=1 R=N。这个时候只要写任何节点成功就认为成功,但是读的时候必须从所有的节点都读出数据。
- 如果我们要求读的高效率,我们可以配置 W=N R=1。这个时候任何一个节点读成功就认为成功,但是写的时候必须写所有三个节点成功才认为成功。
②两阶段提交:
英文 Two Phase Commit,也叫 2PC。两阶段提交经常用于分布式事务,是强一致性算法。简要的说就是分两阶段:
- 第一阶段,主控节点(协调者)询问所有节点(参与者)是否可以提交操作,参与者回应 yes or no。
- 第二阶段,协调者根据收到的响应,如果所有参与者都回应 yes,则向所有参与者发送“正式提交”的命令。参与者完成后恢复“完成”消息,协调者收集齐各节点的回应后结束这个 Global Transaction。如果有一个拒绝则给所有参与者发送“回滚操作”。参与者回滚成功后回应“回滚完成”,协调者收集各结点的“回滚”回应后,取消这个 Global Transaction。
2PC说白了就是第一阶段做 Vote,第二阶段做决定的一个算法,相对于单库事务来说就是在提交之前多了准备的阶段。但是也存在着问题,其中一个是同步阻塞操作,这个事情必然会非常大地影响性能。另一个主要的问题是在TimeOut上。因此出现了 3PC,主要是将提交过程分为两步,更多描述见 Wikipedia。
③Paxos 算法
④时间戳策略
⑤向量时钟
二、MongoDB介绍
1、简介
- 是一个开源的,基于分布式的,面向文档存储的非关系型数据库。是非关系型数据库当中功能最丰富、最像关系数据库的。
- 由C++编写,其名字来源于"humongous"这个单词,其宗旨在于处理大量数据。
- 可以运行在Windows、unix、OSX、Solaris系统上,支持32位和64位应用,提供多种编程语言的驱动程序。
- 支持的数据结构非常松散,是类似json的BSON格式,通过键值对的形式存储数据,可以存储复杂的数据类型。
- 支持的数据类型有:null、boolean、String、objectId、32位整数、64位整数、64位浮点数、日期、正则表达式、js代码、二进制数据、数组、内嵌文档、最大值、最小值、未定义类型。
其中,内嵌文档我理解的并不是.doc.txt等文件,这里所指的文档是mongoDB的一个存储单元(相当于关系型数据当中的记录),在mongoDB中的表现形式为{key1:value1,key2:value2},而内嵌文档则是这样的形式{key1:value1,key2:{key2.1:value2.1,key2.2:value2.2}}。
mongoDB最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
2、mongoDB的特性
- 面向集合存储。数据被分组到若干集合,每个集合可以包含无限个文档,可以将集合想象成RDBMS的表,区别是集合不需要进行模式定义。
- 模式自由。集合中没有行和列的概念,每个文档可以有不同的key,key的值不要求一致的数据类型。
- 支持动态查询。mongoDB支持丰富的查询表达式,查询指令使用json形式表达式。
- 完整的索引支持。mongoDB的查询优化器会分析查询表达式,并生成一个高效的查询计划。
- 高效的数据存储,支持二进制数据及大型对象(图片、视频等)。
- 支持复制和故障恢复。
- 自动分片以支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器。
- 支持空间索引。
- 查询性能剖析。
3、 mongoDB的适用场景
- 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
- 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源 过载。
- 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
- 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。
- 用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。
4、mongoDB不适用场景
- 要求高度事务性的系统。例如对于银行或会计等需要大量原子性复杂事物的应用程序来说,还是需要关系型数据库的。
- 传统的商业智能应用
- 复杂的表级联查询