为了支持结构化数据存储服务的高可用性和可扩展性,非关系型数据库的架构通常比较复杂,而且具体实现也不尽相同。我们分析了几种主流的非关系型数据库,总结了它们具体实现中的关键功能,其中主要包括了应用接口,数据管理,节点管理三大部分。
1 应用接口
应用接口是非关系型数据库提供给用户的编程接口,通过该接口用户可以享受非关系型数据库的数据存储服务。相对传统的数据库而言,非关系型数据库的应用接口有两个特点:简单和灵活。对于普通用户而言,非关系型数据库只提供简单的几个有限的接口:存储,获取和删除,而且这些接口都是通过键(key)来操作的。所谓灵活,是指在允许的数据大小范围内,用户可以存储任意格式的数据。
一般而言,应用接口的通信协议有两种: HTTP和Protocol Buffers/Avro。HTTP方式可以承载XML和JSON这些用户可读的数据和信息,而Protocol Buffers将结构数据序列化传输,然后在接收端将其反序列化,由于序列化的数据更小,从而实现快速传输,提高系统效率。这两种方式都是与平台和语言无关的。
接下来,我们对这三种接口进行进一步分析。存储操作代替了传统数据库的插入和更改操作,它需要用户至少提供键以及所对应的数据项。例如,在Cassandra里,它的存储数据项是以行粒度的,其提供的存储操作为insert(table, key, rowMutation)。这里的table是键值空间,key是数据项的键,rowMutatable是行粒度的数据项,该行可以包括多个列值。另外,在某些实现中,比如Dynamo,存储操作还会要求提供一些上下文对象,这些上下文对象包含了存储数据项的版本信息和所在节点信息,这些信息对于数据管理非常重要。获取操作是通过键以及其他相关信息来获得对应的数据项,返回给用户使用。在非关系型数据库中,考虑到应用的特殊需求,删除操作通常并不是物理上删除数据项,而是将该数据项标识为已删除,有些非关系型数据库甚至不提供删除操作。
2 数据管理
通常,非关系型数据库是一个分布式系统,它所存储的数据项分布在各个节点上。该系统的数据管理需要保证数据读写的高可用性,其关键技术涵括了分区,数据复制和读写,数据版本管理等几个方面。
分区是保证非关系型数据库可扩展的基础,它涉及到数据和节点的管理。目前,大多数非关系型数据库的分区都是通过一致性哈希来实现的。所谓一致性哈希,是将哈希函数所有的哈希值构成了一个首尾相接的环(最大值和最小值相接),而组成非关系型数据库的每个节点在环上随机选择一个哈希值,将该环分割成N份(N为节点数目)。在选取哈希函数的时候,要尽可能将节点