NoSQL前传
1.1. 什么是NoSQL
在云计算时代,我们谈及打数据量的处理需求时必谈NoSQL,以HBase、Cassandra、MongoDB为代表的NoSQL产品以高扩展性、高可用性为业内所推崇,并在数据存储和分析领域得到了广泛的使用。
那么什么才是NoSQL呢?对于这个问题有各种各样的定义,很多人认为其是”Not only SQL”的缩写,这样的话其意义就是:在关系型数据库(DBMS)适合的场景下使用关系型数据库,在关系型数据库不适用的场景下使用其它的数据存储方案,这就是NoSQL。在[1]中的NoSQL的定义如下:下一代非关系、分布式、开源、水平扩展的数据库解决方案,其主要特征是:模式自由(schema-free)、容易复制、API简单、最终一致性(BASE)。
上面的这些官方定义都比较拗口,我们在第三阶会尝试给出一个自己的定义。现在随着其技术的发展,NoSQL慢慢的增加了一些关系型数据库的特性,而关系型数据库也在不断的将NoSQL的优秀实践集成进去,或许最终两者会走向融合吧。
1.2. 关系型数据库演进过程
在这里不谈DBMS的相关技术,如事务、关系模型等,而是以DBMS在互联网的使用为主。在互联网初创时代,用户和内容都比较小,这时候使用一个数据库就能解决所有的问题。
随着业务的发展,数据库的读慢慢的变成瓶颈,为了解决读的问题,采用复制节点(Slave)来分担读请求,由Master节点负责写操作,并异步的将数据复制到Slave节点,这样、非实时的读操作请求可以发送到Slave节点来完成。
当用户数目逐渐增多,这时候写操作也成为数据库的瓶颈,这时候需要有多个Master来承担写操作,其实这个也是数据库常用的分库分表操作,将不同的数据库表放置到不同的节点。
通过分库分表的方式从一定程度上解决了海量数据的存储和管理问题,但当某一个表数据量特别大的时候,需要将一个表分布到多个节点,这时候需要将表进行水平分区,当然这种分区方式有很多不同的方式,首先我们想到的是增加一个索引服务器,应用写数据的同时需要写索引(数据条目和数据库节点对应关系)到索引服务器,这就需要保证索引服务器和数据服务器的数据一致性问题,而同时读数据的时候首先需要到索引服务器获取对应的数据库节点信息,一般来说,索引数据很小可以放在内存中以加快访问,但索引服务器存在单点故障的问题,此外,对数据的不同方式的访问,如范围查询、列值查询很难通过索引服务器中完成,一般通过所有节点全范围扫描方式完成。
1.3. NoSQL简介
从上一节我们可以看出,关系型数据库尽管做了很多改进和努力,但是还是存在很多问题:如大量数据写入处理(可扩展性问题)、灵活的表结构(Schema)变更和海量数据快速的查询处理性能等,其不能很好的处理或者解决方案成本较高。
为了解决关系型数据库的不足,NoSQL出现了,并针对不同的业务需求进行定制化处理以满足功能和性能上的需求,如在互联网某些应用中,对数据的一致性要求可以降低,但要求较高的可用性。所以在某种程度上讲,我给出的NoSQL的定义是:企业根据自己需求提供的定制化的低成本的分布式存储系统。
按照存储模型分类,NoSQL大致可以分为[1]:
l Key-Value键值存储:以DynamoDB、Redis等为代表
l Column-Family列式存储,或者也可以称之为列簇存储,以HBase、Cassandra为代表
l Document Store文档型存储,以MongoDB、CouchDB为代表
l Graph Database图数据库,以Neo4J为代表,这种类型在本书中后续不会涉及
一个有趣的NoSQL家族的进化图参考文献[2]所示,我们可以看到这样的进化趋势:Key-Value时代,BigTable(Column-Family)时代,Document时代、Graph数据库时代,最终向关系型数据演进: