在学习不同NoSQL系统的特性之前,了解一下NoSQL的发展史总不会错的;用一句话来说,NoSQL是天生的反派!
天生的反派NoSQL
这里我们不妨把NoSQL比作No SQL,它必须站在RDBMS的对立面,这里不妨通过逻辑流来解释一下这个观点:
RDBMS通过匹配关系数据(关系和表格)的数据操作方法定义SQL语言,并且支持ACID特性的事务。
横向扩展在数据处理前就会进行分配,用以满足网络服务的高吞吐量需求。当下RDBMS横向扩展的更趋向于维护关系模型的作业完整性,这和事务操作构成了RDBMS的核心。
然而在维护完整性的同时进行扩展是非常难得的,而在分配和复制数据时会出现类似的问题。所以在进行横向扩展之前,必须保证通过DBMS实现的基于ACID事务特性不那么严格,当然还有复制完整性也不能那么严格。
RDBMS的横向扩展
对RDBMS进行扩展是很难的。如果只是扩展到几千规模是很轻松的,类似Oracle 这样领先的数据库开发机构在很早之前就发布了一两个这样的产品。
这里不妨假设将RDBMS中的表格分配到几台主机上,而为了高可用性每份数据都会在存储前都会被复制。首先,在保证ACID进行扩展时执行分配操作就非常困难。
想实现ACID中的原子性,执行某个事务时,类似2PC这样的分布事务协议必须在所有系统中使用。
为了满足ACID特性中的隔离级别,数据通常都会被加锁。锁的级别可以是一条记录,一个表格或者是一个索引。
因此,为了在分布式环境中满足原子性和隔离需求,因此在分布式事务协议的处理期间,每个系统都会加上所有相关的锁;系统的负载越大,锁的竞争越繁重。这就是很难扩展的原因。
另一个横向扩展中必须面临的问题就是数据的复制和分配。
事务性复制使用了2PC方法,这里存在的问题就是:当与某个复制事务相关的任何系统出故障时,这个事务就会失败并变得不可用。此外,当复制事务同时涉及几个系统时,性能就会降低。
作为替代,将一个DBMS的WAL(Write Ahead Logging,预写式日志)数据传送给备份系统并让它使用。节点可以配置为master-slave或multi-master方式。
当使用master-slave类型时:这也是最常见的复制方法。复制过程的速度与系统中的从节点数量成反比。
当使用multi-master配置时:当同时存在几个主节点时,处理数据写入进程间的冲突是非常困难的,并且很难阻止这个情况发生。在《The Danagers of Replication and a Solution》一书中(曾获1998年图灵奖),Jim Gray对这个问题进入了深入研究。
通过开发者分片
通常来说,在满足ACID特性的数据库中进行扩展是非常难的。基于这个原因,对数据进行扩展,这个数据库本身就必须拥有简单的模型,将数据分割为N片,然后在单独的片中执行查询。
数据分割的单元被称为“shard”。将N片数据分配个M个DBMS进行操作。DBMS并不会去管理数据片,这需由服务开发者自行完成。
分片的方法由开发者决定,这里同样会有几个问题:
首先,分片必须被定义。
其次,分片映射:
RDBMS的基本储存单元是表格。鉴于一个表格可能会包含一个或多个分片,这里需要明白分片需要被映射到的数据库实例。应用程序也必须知道分片表格对应的位置。
***,分片的分配和重分配:
鉴于吞吐量需求和数据体积,每个分片都不同。所以开发者必须从数据库中增加或者删除一个实例,并且手动重分配分片。这个过程非常繁琐。同时在这个过程中,修改的映射信息必须告知应用程序。数据修改后,还必须做相应的管理(比如,针对复制的配置)。