十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
NoSQL太火,冒出太多产品了,保守估计也成百上千了。
创新互联-成都网站建设公司,专注成都网站设计、成都做网站、网站营销推广,申请域名,虚拟主机,绵阳服务器托管有关企业网站制作方案、改版、费用等问题,请联系创新互联。
互联网公司常用的基本集中在以下几种,每种只举一个比较常见或者应用比较成功的例子吧。
1. In-Memory KV Store : Redis
in memory key-value store,同时提供了更加丰富的数据结构和运算的能力,成功用法是替代memcached,通过checkpoint和commit log提供了快速的宕机恢复,同时支持replication提供读可扩展和高可用。
2. Disk-Based KV Store: Leveldb
真正基于磁盘的key-value storage, 模型单一简单,数据量不受限于内存大小,数据落盘高可靠,Google的几位大神出品的精品,LSM模型天然写优化,顺序写盘的方式对于新硬件ssd再适合不过了,不足是仅提供了一个库,需要自己封装server端。
3. Document Store: Mongodb
分布式nosql,具备了区别mysql的最大亮点:可扩展性。mongodb 最新引人的莫过于提供了sql接口,是目前nosql里最像mysql的,只是没有ACID的特性,发展很快,支持了索引等特性,上手容易,对于数据量远超内存限制的场景来说,还需要慎重。
4. Column Table Store: HBase
这个富二代似乎不用赘述了,最大的优势是开源,对于普通的scan和基于行的get等基本查询,性能完全不是问题,只是只提供裸的api,易用性上是短板,可扩展性方面是最强的,其次坐上了Hadoop的快车,社区发展很快,各种基于其上的开源产品不少,来解决诸如join、聚集运算等复杂查询。
Hadoop
文件系统:文件系统是用来存储和管理文件,并且提供文件的查询、增加、删除等操作。
直观上的体验:在shell窗口输入 ls 命令,就可以看到当前目录下的文件夹、文件。
文件存储在哪里?硬盘
一台只有250G硬盘的电脑,如果需要存储500G的文件可以怎么办?先将电脑硬盘扩容至少250G,再将文件分割成多块,放到多块硬盘上储存。
通过 hdfs dfs -ls 命令可以查看分布式文件系统中的文件,就像本地的ls命令一样。
HDFS在客户端上提供了查询、新增和删除的指令,可以实现将分布在多台机器上的文件系统进行统一的管理。
在分布式文件系统中,一个大文件会被切分成块,分别存储到几台机器上。结合上文中提到的那个存储500G大文件的那个例子,这500G的文件会按照一定的大小被切分成若干块,然后分别存储在若干台机器上,然后提供统一的操作接口。
看到这里,不少人可能会觉得,分布式文件系统不过如此,很简单嘛。事实真的是这样的么?
潜在问题
假如我有一个1000台机器组成的分布式系统,一台机器每天出现故障的概率是0.1%,那么整个系统每天出现故障的概率是多大呢?答案是(1-0.1%)^1000=63%,因此需要提供一个容错机制来保证发生差错时文件依然可以读出,这里暂时先不展开介绍。
如果要存储PB级或者EB级的数据,成千上万台机器组成的集群是很常见的,所以说分布式系统比单机系统要复杂得多呀。
这是一张HDFS的架构简图:
client通过nameNode了解数据在哪些DataNode上,从而发起查询。此外,不仅是查询文件,写入文件的时候也是先去请教NameNode,看看应该往哪个DateNode中去写。
为了某一份数据只写入到一个Datanode中,而这个Datanode因为某些原因出错无法读取的问题,需要通过冗余备份的方式来进行容错处理。因此,HDFS在写入一个数据块的时候,不会仅仅写入一个DataNode,而是会写入到多个DataNode中,这样,如果其中一个DataNode坏了,还可以从其余的DataNode中拿到数据,保证了数据不丢失。
实际上,每个数据块在HDFS上都会保存多份,保存在不同的DataNode上。这种是牺牲一定存储空间换取可靠性的做法。
接下来我们来看一下完整的文件写入的流程:
大文件要写入HDFS,client端根据配置将大文件分成固定大小的块,然后再上传到HDFS。
读取文件的流程:
1、client询问NameNode,我要读取某个路径下的文件,麻烦告诉我这个文件都在哪些DataNode上?
2、NameNode回复client,这个路径下的文件被切成了3块,分别在DataNode1、DataNode3和DataNode4上
3、client去找DataNode1、DataNode3和DataNode4,拿到3个文件块,通过stream读取并且整合起来
文件写入的流程:
1、client先将文件分块,然后询问NameNode,我要写入一个文件到某个路径下,文件有3块,应该怎么写?
2、NameNode回复client,可以分别写到DataNode1、DataNode2、DataNode3、DataNode4上,记住,每个块重复写3份,总共是9份
3、client找到DataNode1、DataNode2、DataNode3、DataNode4,把数据写到他们上面
出于容错的考虑,每个数据块有3个备份,但是3个备份快都直接由client端直接写入势必会带来client端过重的写入压力,这个点是否有更好的解决方案呢?回忆一下mysql主备之间是通过binlog文件进行同步的,HDFS当然也可以借鉴这个思想,数据其实只需要写入到一个datanode上,然后由datanode之间相互进行备份同步,减少了client端的写入压力,那么至于是一个datanode写入成功即成功,还是需要所有的参与备份的datanode返回写入成功才算成功,是可靠性配置的策略,当然这个设置会影响到数据写入的吞吐率,我们可以看到可靠性和效率永远是“鱼和熊掌不可兼得”的。
潜在问题
NameNode确实会回放editlog,但是不是每次都从头回放,它会先加载一个fsimage,这个文件是之前某一个时刻整个NameNode的文件元数据的内存快照,然后再在这个基础上回放editlog,完成后,会清空editlog,再把当前文件元数据的内存状态写入fsimage,方便下一次加载。
这样,全量回放就变成了增量回放,但是如果NameNode长时间未重启过,editlog依然会比较大,恢复的时间依然比较长,这个问题怎么解呢?
SecondNameNode是一个NameNode内的定时任务线程,它会定期地将editlog写入fsimage,然后情况原来的editlog,从而保证editlog的文件大小维持在一定大小。
NameNode挂了, SecondNameNode并不能替代NameNode,所以如果集群中只有一个NameNode,它挂了,整个系统就挂了。hadoop2.x之前,整个集群只能有一个NameNode,是有可能发生单点故障的,所以hadoop1.x有本身的不稳定性。但是hadoop2.x之后,我们可以在集群中配置多个NameNode,就不会有这个问题了,但是配置多个NameNode,需要注意的地方就更多了,系统就更加复杂了。
俗话说“一山不容二虎”,两个NameNode只能有一个是活跃状态active,另一个是备份状态standby,我们看一下两个NameNode的架构图。
两个NameNode通过JournalNode实现同步editlog,保持状态一致可以相互替换。
因为active的NameNode挂了之后,standby的NameNode要马上接替它,所以它们的数据要时刻保持一致,在写入数据的时候,两个NameNode内存中都要记录数据的元信息,并保持一致。这个JournalNode就是用来在两个NameNode中同步数据的,并且standby NameNode实现了SecondNameNode的功能。
进行数据同步操作的过程如下:
active NameNode有操作之后,它的editlog会被记录到JournalNode中,standby NameNode会从JournalNode中读取到变化并进行同步,同时standby NameNode会监听记录的变化。这样做的话就是实时同步了,并且standby NameNode就实现了SecondNameNode的功能。
优点:
缺点:
严格的说,Hbase 和它的支持系统源于著名的Google BigTable和Google文件系统设计(GFS的论文发于2003年,BigTable的论文发于2006年)。而 Cassandra 则是最近Facebook的数据库系统的开源分支,她在实现了BigTable的数据模型的同时,使用了基于Amazon的Dynamo的系统架构来存储数据(实际上,Cassandra的最初开发工作就是由两位从Amazon跳槽到Facebook的Dynamo工程师完成的)。
【备注1】Dynamo是亚马逊的key-value模式的存储平台,可用性和扩展性都很好,性能也不错:读写访问中99.9%的响应时间都在300ms内。
在Dynamo的实现中提到一个关键的东西,就是数据分区。假设我们的数据的key的范围是0到2的64次方(不用怀疑你的数据量会超过它,正常甚至变态情况下你都是超不过的,甚至像伏地魔等其他类Dynamo系统是使用的 2的32次方),然后设置一个常数,比如说1000,将我们的key的范围分成1000份。然后再将这1000份key的范围均匀分配到所有的节点(s个节点),这样每个节点负责的分区数就是1000/s份分区。
如图二,假设我们有A、B、C三台机器,然后将我们的分区定义了12个。
图二:三个节点分12个区的数据的情况
因为数据是均匀离散到这个环上的(有人开始会认为数据的key是从1、2、3、4……这样子一直下去的,其实不是的,哈希计算出来的值,
【备注2】DHT(Distributed Hash Table,分布式哈希表),它是一种分布式存储寻址方法的统称。就像普通的哈希表,里面保存了key与value的对应关系,一般都能根据一个key去对应到相应的节点,从而得到相对应的value。
【备注3】Consistency(一致性):即数据一致性,简单的说,就是数据复制到了N台机器,如果有更新,要N机器的数据是一起更新的。
Availability(可用性):好的响应性能,此项意思主要就是速度。
Partition tolerance(分区容错性):这里是说好的分区方法,体现具体一点,简单地可理解为是节点的可扩展性。
定理:任何分布式系统只可同时满足二点,没法三者兼顾
这个理论说明,分布式(或共享数据)系统的设计中,至多只能够提供三个重要特性中的两个——一致性、可用性和容忍网络分区。简单的说,一致性指如果一个人向数据库写了一个值,那么其他用户能够立刻读取这个值,可用性意味着如果一些节点失效了,集群中的分布式系统仍然能继续工作,而容忍分区意味着,如果节点被分割成两组无法互相通信的节点,系统仍然能够继续工作
对比关系型数据库,NoSQL的优点在哪里看NoSQL具有高性能、良好的扩展性以及高可靠性等优点。然而,没有一个产品可以在所有的方面都达到完美。当你仔细审视NoSQL的产品,完全可以找到一些弱点,就像那些杰出的优点一样逗鲜明出众地。基于此原因,选择经过验证的NoSQL产品就是关键。在本文中,作者从运行方面分析Cassandra,HBase以及MongoDB等产品的扩展性和可靠性。
Cassandra故障恢复以及数据一致性
Cassandra在数据的分布式和可靠性方面展示了自身卓越的性能。首先,作者检测了它的分布能力,Cassandra通过一致性哈希算法来实现数据的分配处理。
Cassandra的一致性哈希算法
通过一致性哈希算法,用户可以不经过查询元数据就能搜索并发现key存储在哪个节点上。用户通过计算key的哈希值就能发现key,同样只通过Hash值就可以找到节点所在。你可以想像一致性哈希被作为哈希值顺序的放在圆环上,每个节点处理环上的一个部分。如果环上增加了一个节点,那么某个拥有很大体积数据的特定节点就会被拆分然后分配给新的节点;如果某个节点被移除,分配给该节点的资源就会转移到邻节点上。利用这种方式,Cassandra使增加或者移除节点带来的影响降到了最小。
Cassandra的运行中不需要主服务器,换句话说:并没有特定的服务器来管理数据的分配或者故障恢复。这就意味着,Cassandra并不存在单点故障(Single Point Of Failure,SPoF)。取代主服务器,每个节点都和其他节点周期性地分享元数据,这个也被称之为Gossip协议。使用Gossip协议,节点可以对其他节点的运行状态进行查询。
Cassandra通过提供一致性级别来实现系统的可靠性。如果使用一个很低的一致性级别,即使一个节点宕掉也可能导致整个服务的停滞。例如,3个节点中的某一个节点在存储副本数据的过程中宕掉了,一个通用的写操作,就不能立刻返回成功信息,这是因为故障节点不能完成写入数据的请求。然而,如果一致性级别被定义成一个约定值或者是1,而存活的节点数大于或者等于设定值,这样的话就能立刻返回成功。如果是这样的话,只有在所有的3个节点都同时宕掉,才会发生请求错误。
但是,读/写操作真的没有受到节点出错的影响吗看
为了证明这点,当有新节点添加时,作者在不断的服务器请求下故意让一个节点发生故障。结果如下所示:
移除一个节点和增加一个新的节点
以下是移除一个节点和增加一个新的节点的结果:
在管理工具中明确移除一个节点,存储在此节点中的数据就被迁移到剩余的节点中,然后该节点被移除。
当一个新节点被增加,这个被称之为引导指令,增加的节点就会向种子节点(seed nodes)报告它已经添加完毕。基于配置信息,新节点会被添加在环上配置信息中指定的范围,或者环上资源被占用最高的节的附近—— 当然这是在没有其它节点被引导在这个范围上。
数据从那个节点迁移到到新节点上。
一旦数据迁移进程结束,新节点就能进行使用。
节点失败后增加一个新节点
下面是节点失败后新增节点的结果:
当一个节点宕掉之后,存储在节点上的数据并没有迁移到其他的节点上,服务在于两个副本(节点)共舞。换句话说,并没有返回任何错误信息,即使在这段时间里又收到服务请求。
当一个新节点被增加的时候,该节点会被分配到环上的一个特定区域。然而,引导指令并没有执行,因为引导指令只有系统中存在3份副本的时候才会被执行!
新增的节点并没有数据,但是它能处理请求,这是因为它可以提供服务。如果此时接受到一个读请求,节点并不会对key返回数据。如果备份因子是3而读一致性的级别是1,那么1/3的读请求可能不会返回数据。如果一致性级别被设置为约定值,1/6的读请求可能会返回空数据。简单来讲,这没有读一致性的保证,除非故障节点已经恢复。实际上在级别1中,协调节点是最有可能第一个接受来自新节点的响应。出现这种情况是因为没有来自新节点的I/O请求——因为它没有数据。出于这个原因,新的节点比现有节点有更大的机率返回空数据。
当通过管理工具对新节点做Read Repair时,节点通过读其他节点的同步数据才能得以建立。此时读一致性就被破坏了,只到Read Repair完成。
即使节点失败,Cassandra也能提供无错的服务。尽管Cassandra在写数据的时候,展示了自身强大的性能,但是在读数据的时候并非如此,因为Read Repair的延迟必然导致数据的非一致性的延迟。因此,为了在节点故障中保持读一致性,需要使用以下的方法:
设置读一致性水平为逗all地然后执行读操作。在这种情况下,就能获得所有来自副本的最新数据。
一旦读请求失败,Cassandra会再次进行尝试。这是因为在第一次读写的时候Read Repair可能会作为第二次读写时的恢源数据源。然而,这种方法能确保Rread Repair在二次读之前完成。(当一致性的水平较低,那么读修复就会在后台执行,这是一个独立的线程,区别于读操作过程的线程)
HBase的失败因子和恢复方法
HBase包含以下几个组件:
HRegionServer负责数据的分布处理,由HMaster进行监控。HDFS存储和复制数据,Zookeeper存储了HMaster以及备选HMaster的储存单元信息。如果没有为每个组件建立冗余,所有的组件都会成为SPoF。
HRegionServer主要负责响应用户I/O请求,向HDFS文件系统中读写数据,是HBase中最核心的模块。HRegionServer内部管理了一系列HRegion对象,每个HRegion对应了Table中的一个Region,HRegion中由多个HStore组成。每个HStore对应了Table中的一个Column Family的存储,可以看出每个Column Family其实就是一个集中的存储单元,因此最好将具备共同IO特性的column放在一个Column Family中,这样最高效。(百度百科)
HRegionServer把数据分布到一些称之为逗region地的单元中,region就是将一张大表格通过指定字段对数据进行排序,然后针对排序键的范围拆分出的结果(就像大表中的一小块)。每个region排序字段的值范围存储在一个单独的region中,被称为meta region。而region和meta region的对应关系被存储在root region中。长话短说,region服务器存储着一个层次树中,包含了root region、meta region以及data region。如果一个region服务器宕机,这个region服务器包含的region都不可以被访问直到被分配给了其它region服务器。因此产生了服务器宕机时间,直到那个region被恢复。
2. 什么是NoSQL?
2.1 NoSQL 概述
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,
泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。
(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
2.2 NoSQL代表
MongDB、 Redis、Memcache
3. 关系型数据库与NoSQL的区别?
3.1 RDBMS
高度组织化结构化数据
结构化查询语言(SQL)
数据和关系都存储在单独的表中。
数据操纵语言,数据定义语言
严格的一致性
基础事务
ACID
关系型数据库遵循ACID规则
事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的
D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
3.2 NoSQL
代表着不仅仅是SQL
没有声明性查询语言
没有预定义的模式
键 - 值对存储,列存储,文档存储,图形数据库
最终一致性,而非ACID属性
非结构化和不可预知的数据
CAP定理
高性能,高可用性和可伸缩性
分布式数据库中的CAP原理(了解)
CAP定理:
Consistency(一致性), 数据一致更新,所有数据变动都是同步的
Availability(可用性), 好的响应性能
Partition tolerance(分区容错性) 可靠性
P: 系统中任意信息的丢失或失败不会影响系统的继续运作。
定理:任何分布式系统只可同时满足二点,没法三者兼顾。
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。
而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。
所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。
说明:C:强一致性 A:高可用性 P:分布式容忍性
举例:
CA:传统Oracle数据库
AP:大多数网站架构的选择
CP:Redis、Mongodb
注意:分布式架构的时候必须做出取舍。
一致性和可用性之间取一个平衡。多余大多数web应用,其实并不需要强一致性。
因此牺牲C换取P,这是目前分布式数据库产品的方向。
4. 当下NoSQL的经典应用
当下的应用是 SQL 与 NoSQL 一起使用的。
代表项目:阿里巴巴商品信息的存放。
去 IOE 化。
ps:I 是指 IBM 的小型机,很贵的,好像好几万一台;O 是指 Oracle 数据库,也很贵的,好几万呢;M 是指 EMC 的存储设备,也很贵的。
难点:
数据类型多样性。
数据源多样性和变化重构。
数据源改造而服务平台不需要大面积重构。
如何选择数据库
柳树
公众号:柳树的絮叨叨
关注他
30 人赞同了该文章
我们正在做一个电子书小程序。
1.0 层次模型数据库
用户购买,生成订单,订单详情里有用户购买的电子书:
一层一层铺开,一对多,这是「层次模型数据库」(Hierarchical Database)。
2.0 网状模型数据库
一笔订单可以购买多本电子书,一本电子书也可以被多笔订单购买:
这就形成了「多对多」的「网状模型数据库」(Network Database)。
上面讲的两种数据库,也许你听都没听过。
我们用的,是「关系模型」,而非上面的「层次模型」或者「网状模型」。
为什么?
你会说,这样不方便遍历所有订单。
并不会,再加一个根节点就好:
你会说,这样查找效率很低。
也不会,因为可以优化下数据结构,比如换成 B+ 树。
为什么我们从一开始就在用「关系模型数据库」?
3.0 关系模型数据库
无论是层次模型还是网状模型,程序员看到的,都是实实在在的物理存储结构。
查询时,你要照着里面的数据结构,用对应的算法来查;
插入时,你也要照着数据结构,用对应算法来插入,否则你就破坏了数据的组织结构,数据也就坏掉了。
因为我们都没用过前面两种数据库,所以觉得「关系模型数据库」(以下简称 RDB)的一切都理所当然,但其实,它做出了一个革命性的变革:
用逻辑结构(logical representation of data)代替物理结构(physical representation of data)
所谓「逻辑结构」,也就是我们经常看到的「表格」,User 是一张表格,Order 是一张表格,Book 又是一张表格,它们之间的关系,用 id 来关联,这些 id,可能是 number 类型,也可能是 string 类型
但你看到的,不一定就是实际的,你看到的只是让你方便理解的「逻辑结构」,真实数据自然不是这样按表格来存储,表格无异于一个数组,数组查询是很慢的。
真实的「物理结构」,也许还是像「层次模型」和「网状模型」一样,是复杂的数据结构。
但到底是怎样的数据结构,你都无需关心,你只需把它想象成一张「表」去操作,就连可视化工具,都会帮你把数据可视化成表,来方便你理解。
这个观念的提出,来自于 1970 年 Codd 的一篇论文,A Relational Model of Data for Large Shared Data Banks:
Future users of large data banks must be protected from having to know how the data is organized in the machine (the internal representation).
Activities of users at terminals and most application programs should remain unaffected when the internal representation of data is changed and even when some aspects of the external representation are changed.
—— Codd
Codd 的这种思想,其实就是经济学里提到的:分工产生效能。
程序员们不需要直接和物理结构打交道,只负责告诉数据库,他想做什么,至于数据是如何存储、如何索引,都交给数据库,最终他们看到的就是一张张特别直观、特别好理解的 excel 表格。
而数据库则把维护物理结构的复杂逻辑,交给了自己, 对程序员屏蔽了复杂的实现细节。
开发时写的代码少了,耦合性降低了,数据也不容易损坏,也就提高了生产效率(productive)。
一切能用同样的耗能,带来更多效能的技术,都会被广泛使用。
NoSQL
那后来为什么又有了 NoSQL 呢?
在 RDB 被发明的时代,软件多用于大型企业,比如银行、金融等等,人们对数据的要求非常纯粹:准确、可靠、安全,让数据按照期望,正确的写入,不要给老子算错钱就好,于是有了具有 ACID 特性的事务:原子性、一致性、隔离性和持久性。
那时候用网络的人很少,通过终端来访问客户端的人,更少,自然的,数据库的数据量和访问量都跟现在没法比,一台机器,足矣,最多再来个一主多从:
后来,你知道的,每个人手里都有个手机,每分每秒,都有成千上万的数据,写入你的数据库、从你的数据库被查出,于是有了「分布式」,有了 BASE 和 CAP。这时候,RDB 就会发现,自己之前的那一套 ACID,竟然有点作茧自缚了:
为了保证事务的隔离性,要进行加锁,在分布式的环境下,就要对多台机器的数据进行加锁;
为了保证事务的原子性,在机器 A 的操作和在机器 B 的操作,要么一起成功,要么一起失败;
…...
这些都要去不同节点的机器进行通讯和协调,实现起来非常复杂,而且要付出更多的网络 IO,影响性能。
ACID 在分布式系统上实现起来就会变得难以实现,即使实现了,也要付出很大的性能成本,于是才有了后来的各种「分布式一致性协议」,Paxos、Raft、2PC …… 而 Mysql 也提供了各种方案来实现分布式,当然,这些方案自然是很复杂的,比如 「NDB Cluster」 :
而 NoSQL 则没有这么多承诺,它的一致性,一般都是最终一致性,当然你可以选择强一致,那自然就要付出点性能作为代价,当然你还可以弱一致,这样会更不安全,但是更快,一切取决于你对数据的要求。
除此之外,RDB 的「数据库范式」(Database Schema),也成了限制扩展性的瓶颈。为了避免数据冗余导致的各种问题(占用空间、删除异常、更新异常等等),我们在设计关系模型时,通常都是按照最小单位来设计的。
什么叫最小单位,比如用户有地址和爱好,那么在正确设计的关系模型(比如 3NF)里,这就是三张表:
如果这三张表被分散在不同的机器,那进行关联查询时,就需要多次跨机器的通讯;
而对于 NoSQL,这三类信息,都可以利用 Json 格式的数据,将它们存放在一起:
完整的存储进去,完整的取出来,不需要额外的操作。
NoSQL 比 RDB 有更强的扩展性,可以充分利用分布式系统来提升读写性能和可靠性。
这不是谁设计好坏的问题,而是跟他们要解决的问题有关:RDB 诞生于互联网萌芽的时代,那时数据的准确、可靠是最重要的,而 NoSQL 诞生于互联网快速发展普及的时代,大数据、分布式、扩展性成了数据库的另一个重要特性。
总结一下:
RDB 首先得是准确、可靠,然后才向更高的「可拓展性」发展;
而 NoSQL 生而分布式,可拓展性强,然后才向更高的「准确性」发展。
NoSQL ,not only SQL,其实就是对那种打破了 RDB 严格事务和关系模型约束的那些数据库的泛指,而随着要解决的问题的不同,又诞生了各种各样的 NoSQL。
首先是「列式数据库」(Column-oriented DBMS),数据量上去了,我们想分析网站用户的年龄分布,简单说,就是你需要对同一个特征进行大数据量的分析统计,于是把原来 RDB 的「按行存储」的范式打破,变成了「按列存储」,比如 HBase;
然后你发现有些数据变动不是很大,但是经常需要被查询, 查询时还要关联很多张表,于是你把这些来自不同表的数据,揉成一个大对象,按 key-value 的格式存起来,比如 Redis;
再后来你需要对博客内容进行相关性搜索,传统 RDB 不支持相关性搜索,最重要的,还是扩展性差,增加机器的带来边际效益有限,于是有了「全文搜索引擎」,比如 Elasticsearch;
除此之外,还有「文档数据库」、「图形数据库」……
没有一种数据库是银弹。
总结
这篇文章的题目是「如何选择数据库」,这是困扰很多人的问题,那么多数据库,到底要选什么好?
可是当你问出这样一个问题时,其实你是在问一种「手段」。我现在要做这样一个需求,用什么数据库可以帮我实现它?
但其实你需要的不只是一种「手段」,因为如果对方甩给你一个冷冰冰的名字,Mysql、Elasticsearch、MongoDB,你肯定会问,凭什么?
你需要的,是一种「解决方案」。如果你需要数据十分严格准确,分毫不差,那我会推荐你采用「事务」和「关系模型」来处理数据;如果你需要数据能够被大量读取和写入,那我会推荐你扩展性强的「分布式」;如果你的数据经常是整个读取、整个更新的,那「关系模型」就没有「文档模型」适合你。
「事务」、「关系模型」、「分布式」、「文档模型」等等,这些就是「解决方案」,知道用什么「解决方案」,用哪个数据库,自然水到渠成。
正如一位大牛说的:
设计实践中,要基于需求、业务驱动架构。无论选用 RDB/NoSQL,一定是以需求为导向,最终数据存储方案必然是各种权衡的综合性设计。
用户不会因为你用了 Mysql 或者 MongoDB 而使用你的软件,毕竟绝大多数用户都不知道 Mysql 和 MongoDB 是什么玩意。
特点:
它们可以处理超大量的数据。
它们运行在便宜的PC服务器集群上。
PC集群扩充起来非常方便并且成本很低,避免了“sharding”操作的复杂性和成本。
它们击碎了性能瓶颈。
NoSQL的支持者称,通过NoSQL架构可以省去将Web或Java应用和数据转换成SQL友好格式的时间,执行速度变得更快。
“SQL并非适用于所有的程序代码,” 对于那些繁重的重复操作的数据,SQL值得花钱。但是当数据库结构非常简单时,SQL可能没有太大用处。
没有过多的操作。
虽然NoSQL的支持者也承认关系数据库提供了无可比拟的功能集合,而且在数据完整性上也发挥绝对稳定,他们同时也表示,企业的具体需求可能没有那么多。
Bootstrap支持
因为NoSQL项目都是开源的,因此它们缺乏供应商提供的正式支持。这一点它们与大多数开源项目一样,不得不从社区中寻求支持。
优点:
易扩展
NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。
大数据量,高性能
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用 Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的 Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了。
灵活的数据模型
NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的web2.0时代尤其明显。
高可用
NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如Cassandra,HBase模型,通过复制模型也能实现高可用。
主要应用:
Apache HBase
这个大数据管理平台建立在谷歌强大的BigTable管理引擎基础上。作为具有开源、Java编码、分布式多个优势的数据库,Hbase最初被设计应用于Hadoop平台,而这一强大的数据管理工具,也被Facebook采用,用于管理消息平台的庞大数据。
Apache Storm
用于处理高速、大型数据流的分布式实时计算系统。Storm为Apache Hadoop添加了可靠的实时数据处理功能,同时还增加了低延迟的仪表板、安全警报,改进了原有的操作方式,帮助企业更有效率地捕获商业机会、发展新业务。
Apache Spark
该技术采用内存计算,从多迭代批量处理出发,允许将数据载入内存做反复查询,此外还融合数据仓库、流处理和图计算等多种计算范式,Spark用Scala语言实现,构建在HDFS上,能与Hadoop很好的结合,而且运行速度比MapReduce快100倍。
Apache Hadoop
该技术迅速成为了大数据管理标准之一。当它被用来管理大型数据集时,对于复杂的分布式应用,Hadoop体现出了非常好的性能,平台的灵活性使它可以运行在商用硬件系统,它还可以轻松地集成结构化、半结构化和甚至非结构化数据集。
Apache Drill
你有多大的数据集?其实无论你有多大的数据集,Drill都能轻松应对。通过支持HBase、Cassandra和MongoDB,Drill建立了交互式分析平台,允许大规模数据吞吐,而且能很快得出结果。
Apache Sqoop
也许你的数据现在还被锁定于旧系统中,Sqoop可以帮你解决这个问题。这一平台采用并发连接,可以将数据从关系数据库系统方便地转移到Hadoop中,可以自定义数据类型以及元数据传播的映射。事实上,你还可以将数据(如新的数据)导入到HDFS、Hive和Hbase中。
Apache Giraph
这是功能强大的图形处理平台,具有很好可扩展性和可用性。该技术已经被Facebook采用,Giraph可以运行在Hadoop环境中,可以将它直接部署到现有的Hadoop系统中。通过这种方式,你可以得到强大的分布式作图能力,同时还能利用上现有的大数据处理引擎。
Cloudera Impala
Impala模型也可以部署在你现有的Hadoop群集上,监视所有的查询。该技术和MapReduce一样,具有强大的批处理能力,而且Impala对于实时的SQL查询也有很好的效果,通过高效的SQL查询,你可以很快的了解到大数据平台上的数据。
Gephi
它可以用来对信息进行关联和量化处理,通过为数据创建功能强大的可视化效果,你可以从数据中得到不一样的洞察力。Gephi已经支持多个图表类型,而且可以在具有上百万个节点的大型网络上运行。Gephi具有活跃的用户社区,Gephi还提供了大量的插件,可以和现有系统完美的集成到一起,它还可以对复杂的IT连接、分布式系统中各个节点、数据流等信息进行可视化分析。
MongoDB
这个坚实的平台一直被很多组织推崇,它在大数据管理上有极好的性能。MongoDB最初是由DoubleClick公司的员工创建,现在该技术已经被广泛的应用于大数据管理。MongoDB是一个应用开源技术开发的NoSQL数据库,可以用于在JSON这样的平台上存储和处理数据。目前,纽约时报、Craigslist以及众多企业都采用了MongoDB,帮助他们管理大型数据集。(Couchbase服务器也作为一个参考)。
十大顶尖公司:
Amazon Web Services
Forrester将AWS称为“云霸主”,谈到云计算领域的大数据,那就不得不提到亚马逊。该公司的Hadoop产品被称为EMR(Elastic Map Reduce),AWS解释这款产品采用了Hadoop技术来提供大数据管理服务,但它不是纯开源Hadoop,经过修改后现在被专门用在AWS云上。
Forrester称EMR有很好的市场前景。很多公司基于EMR为客户提供服务,有一些公司将EMR应用于数据查询、建模、集成和管理。而且AWS还在创新,Forrester称未来EMR可以基于工作量的需要自动缩放调整大小。亚马逊计划为其产品和服务提供更强大的EMR支持,包括它的RedShift数据仓库、新公布的Kenesis实时处理引擎以及计划中的NoSQL数据库和商业智能工具。不过AWS还没有自己的Hadoop发行版。
Cloudera
Cloudera有开源Hadoop的发行版,这个发行版采用了Apache Hadoop开源项目的很多技术,不过基于这些技术的发行版也有很大的进步。Cloudera为它的Hadoop发行版开发了很多功能,包括Cloudera管理器,用于管理和监控,以及名为Impala的SQL引擎等。Cloudera的Hadoop发行版基于开源Hadoop,但也不是纯开源的产品。当Cloudera的客户需要Hadoop不具备的某些功能时,Cloudera的工程师们就会实现这些功能,或者找一个拥有这项技术的合作伙伴。Forrester表示:“Cloudera的创新方法忠于核心Hadoop,但因为其可实现快速创新并积极满足客户需求,这一点使它不同于其他那些供应商。”目前,Cloudera的平台已经拥有200多个付费客户,一些客户在Cloudera的技术支持下已经可以跨1000多个节点实现对PB级数据的有效管理。
Hortonworks
和Cloudera一样,Hortonworks是一个纯粹的Hadoop技术公司。与Cloudera不同的是,Hortonworks坚信开源Hadoop比任何其他供应商的Hadoop发行版都要强大。Hortonworks的目标是建立Hadoop生态圈和Hadoop用户社区,推进开源项目的发展。Hortonworks平台和开源Hadoop联系紧密,公司管理人员表示这会给用户带来好处,因为它可以防止被供应商套牢(如果Hortonworks的客户想要离开这个平台,他们可以轻松转向其他开源平台)。这并不是说Hortonworks完全依赖开源Hadoop技术,而是因为该公司将其所有开发的成果回报给了开源社区,比如Ambari,这个工具就是由Hortonworks开发而成,用来填充集群管理项目漏洞。Hortonworks的方案已经得到了Teradata、Microsoft、Red Hat和SAP这些供应商的支持。
IBM
当企业考虑一些大的IT项目时,很多人首先会想到IBM。IBM是Hadoop项目的主要参与者之一,Forrester称IBM已有100多个Hadoop部署,它的很多客户都有PB级的数据。IBM在网格计算、全球数据中心和企业大数据项目实施等众多领域有着丰富的经验。“IBM计划继续整合SPSS分析、高性能计算、BI工具、数据管理和建模、应对高性能计算的工作负载管理等众多技术。”
Intel
和AWS类似,英特尔不断改进和优化Hadoop使其运行在自己的硬件上,具体来说,就是让Hadoop运行在其至强芯片上,帮助用户打破Hadoop系统的一些限制,使软件和硬件结合的更好,英特尔的Hadoop发行版在上述方面做得比较好。Forrester指出英特尔在最近才推出这个产品,所以公司在未来还有很多改进的可能,英特尔和微软都被认为是Hadoop市场上的潜力股。
MapR Technologies
MapR的Hadoop发行版目前为止也许是最好的了,不过很多人可能都没有听说过。Forrester对Hadoop用户的调查显示,MapR的评级最高,其发行版在架构和数据处理能力上都获得了最高分。MapR已将一套特殊功能融入其Hadoop发行版中。例如网络文件系统(NFS)、灾难恢复以及高可用性功能。Forrester说MapR在Hadoop市场上没有Cloudera和Hortonworks那样的知名度,MapR要成为一个真正的大企业,还需要加强伙伴关系和市场营销。
Microsoft
微软在开源软件问题上一直很低调,但在大数据形势下,它不得不考虑让Windows也兼容Hadoop,它还积极投入到开源项目中,以更广泛地推动Hadoop生态圈的发展。我们可以在微软的公共云Windows Azure HDInsight产品中看到其成果。微软的Hadoop服务基于Hortonworks的发行版,而且是为Azure量身定制的。
微软也有一些其他的项目,包括名为Polybase的项目,让Hadoop查询实现了SQLServer查询的一些功能。Forrester说:“微软在数据库、数据仓库、云、OLAP、BI、电子表格(包括PowerPivot)、协作和开发工具市场上有很大优势,而且微软拥有庞大的用户群,但要在Hadoop这个领域成为行业领导者还有很远的路要走。”
Pivotal Software
EMC和Vmware部分大数据业务分拆组合产生了Pivotal。Pivotal一直努力构建一个性能优越的Hadoop发行版,为此,Pivotal在开源Hadoop的基础上又添加了一些新的工具,包括一个名为HAWQ的SQL引擎以及一个专门解决大数据问题的Hadoop应用。Forrester称Pivotal Hadoop平台的优势在于它整合了Pivotal、EMC、Vmware的众多技术,Pivotal的真正优势实际上等于EMC和Vmware两大公司为其撑腰。到目前为止,Pivotal的用户还不到100个,而且大多是中小型客户。
Teradata
对于Teradata来说,Hadoop既是一种威胁也是一种机遇。数据管理,特别是关于SQL和关系数据库这一领域是Teradata的专长。所以像Hadoop这样的NoSQL平台崛起可能会威胁到Teradata。相反,Teradata接受了Hadoop,通过与Hortonworks合作,Teradata在Hadoop平台集成了SQL技术,这使Teradata的客户可以在Hadoop平台上方便地使用存储在Teradata数据仓库中的数据。
AMPLab
通过将数据转变为信息,我们才可以理解世界,而这也正是AMPLab所做的。AMPLab致力于机器学习、数据挖掘、数据库、信息检索、自然语言处理和语音识别等多个领域,努力改进对信息包括不透明数据集内信息的甄别技术。除了Spark,开源分布式SQL查询引擎Shark也源于AMPLab,Shark具有极高的查询效率,具有良好的兼容性和可扩展性。近几年的发展使计算机科学进入到全新的时代,而AMPLab为我们设想一个运用大数据、云计算、通信等各种资源和技术灵活解决难题的方案,以应对越来越复杂的各种难题。