对于写密集型应用,每天写入量巨大,数据增长量无法预估,且对性能和可靠性要求非常高,普通关系型数据库无法满足其需求。对于全文搜索和数据分析这类对查询性能要求极高的场景也是如此。为了进一步满足上面两类场景的需求,有了宽表存储和搜索引擎技术,本文将对他们的架构、原理、优缺点做介绍。
— 宽表存储 —
宽表存储最早来自Google的Bigtable论文,最初的定义为:A Bigtable is a sparse, distributed, persistent multidimensional sorted map. The map is indexed by a row key, column key, and a timestamp; each value in the map is an uninterpreted array of bytes.《Bigtable: A distributed storage system for structured data》
Bigtable 会把数据存储在若干个 Table(表)中,Table 中的每个 Cell(数据单元)的形式如下:Cell 内的数据由字节串(string)构成,使用行、列和时间戳三个维度进行定位。
图片来源于《Bigtable: A distributed storage system for structured data》Bigtable 在存储数据时会按照 Cell 的 Row Key 对 Table 进行字典排序,并且将一个 Table 按 Row 切分成若干个相邻的 Tablet,并将 Tablet 分配到不同的 Tablet Server 上存储。如此一来,客户端查询较为接近的 Row Key 时 Cell 落在同一个 Tablet 上的概率也会更大,查询的效率也会更高。Table 中的不同 Cell 可以保存同一份数据的多个版本,以时间戳进行区分。时间戳本质上为 64 位整数,可由 Bigtable 自动设定为数据写入的当前时间(微秒),也可由应用自行设定,但应用需要自行确保 Cell 间不会出现冲突。对于拥有相同 Row Key 和 Column Key 的 Cell,Bigtable 会按照时间戳降序进行排序,如此一来最新的数据便会被首先读取。由于Google Bigtable解决了海量数据场景下并发检索与查询、高速日志写入等核心业务场景需求,工业界受其启发开发了一些项目,如HBase、Cassandra等,并统称其为Wide Column Store(宽表存储,又称表格存储)。宽表存储可以无schema限制,表的字段可以自由扩展。一个数据表可以有无穷多的column,并且每行可以有不同的column,也允许每行有很多的空值,类似一个稀疏矩阵。一个列族(column family)存储经常被一起查询的相关数据。当前DB-Engine中宽表NoSQL数据库的排名如下表,可以看到最受欢迎的主要是Cassandra、HBase和Azure上的Cosmos DB。接下来我们将介绍一下HBase的情况。HBase是一个面向列的分布式NoSQL数据库,是Google Bigtable 框架的开源实现,能够响应随机、实时的数据检索需求。HBase主要的存储和处理对象是大宽表,存储模式可以兼容本地存储、HDFS和Amazon S3等Hadoop支持的文件系统,相比于RDBMS有很强的线性扩展能力。HBase通过采用基于LSM树的存储系统以保证稳定的数据写速率,同时利用其日志管理机制以及HDFS多副本机制确保数据库容错能力。通常的适用场景为:面向多版本、稀疏的、半结构化和结构化的数据高并发写入/查询的OLTP业务。HBase的数据模型由不同的逻辑概念构成,包括:表、行、行键、列、列族、单元、时间戳。- 表(Table):Table是HBase中数据的组织形式,是列的集合,和传统数据库中表的意义类似,同时也能够涵盖列数据在不同时间戳下的更新记录。
- 列(Column):是数据库中单独的数据项,每一个Column包含数据的一种类型。
- 列族(ColumnFamily):HBase中表的数据都是按照ColumnFamily分组,ColumnFamily是一个或多个HBase表中相近类型列的聚合。HBase将同一个ColumnFamily的数据放在一个文件中存储,可以起到类似于垂直分区的作用。查询时能减少不必要的扫描,增加查询速度。
- 行(Row):Row是RowKey和ColumnFamily的集合,一个Row中可以包括一个或多个ColumnFamily。
- 行键(RowKey):HBase中的行数据以RowKey形式进行排序,具有主键的作用,在查询时HBase可以通过RowKey定位数据,Region也是通过RowKey划分的。
- 时间戳(Timestamp):Timestamp是给定值的版本标识,和值同时写入HBase数据库。Timestamp可以是任何类型的时间格式,对于每个RowKey来说可以有多个时间版本的记录更新。
- Client:Client是整个HBase集群的访问入口,负责与HMaster通信,以进行集群管理类操作,或者与HRegionServer通信进行数据读写类操作。
- ZooKeeper:集群中每个节点的状态信息都会注册在ZooKeeper,HMaster通过ZooKeeper感知每个HRegionServer的健康状态。另外HBase允许启动多个HMaster,ZooKeeper可保证集群中只有一个HMaser在运行。
- HMaster:负责管理对数据表的CRUD操作,管理HRegionServer的负载均衡,负责新Region的分配;在HRegionServer故障停机时负责失效HRegionServer上的Region迁移。
- HRegionServer:一个节点对应一个HRegionServer。负责接收HMaster分配的Region,负责与Client通信并处理其管理的所有Region相关读/写请求。
- HStore:HStore在HBase中负责数据存储功能,有1个MemStore和0个或更多的StoreFiles。数据先写入内存MemStore,刷写成StoreFile(File的封装),最后持久化到HDFS,当查询某一列的时候只需要调出HFDS相应的block即可。
- HLog:日志管理与回回放,每个进入MemStore的操作都会记录在HLog。
— 全文搜索引擎—
关系数据库以行记录的方式存储有固定格式数据,与之不同的是,搜索引擎会将数据以文档的形式存储,在物理上会是层次化结构或者树形结构。这个做法的好处是非常容易增加半结构化或者结构化数据的处理能力。目前搜索引擎比较有代表性的数据库有开源Elasticsearch,国内星环科技有自研的搜索产品Scope。在DB Engine的排名中,Elasticsearch常年排名在前十以内,相较于SQL数据库,ES提供了可扩展、近实时性的分布式搜索功能,支持将文本数据分割为多个部分交由集群节点进行存储和备份以提高检索速度并保证数据的完整性,支持自动化的负载均衡和应急处理以确保整个集群处于高可用状态。ES适用于各种对文档等非结构化数据有处理需求的业务,如智能分词、全文检索、相关度排名等。ES定义了一套专有的存储和管理数据的要素和概念,最主要的为Field、Document、Type和Index。Field是Elasticsearch中最小的数据单位,与关系型数据库中的列相似,是一组具有相同数据类型的数据值的集合。Document类似于关系型数据中行的概念,一个Document包含每一个Field中与之相应的数据值。Type类似数据库中的表级别概念,而Index是Elasticsearch中最大的数据单位,与 SQL的索引不同,ES中index对应SQL中schema的概念。Elasticsearch | SQL Database |
Index | Database |
Type | Table |
Document | Row |
Field | Column |
- 不支持事务功能仅能支持数据的最终一致性,因此不能用于关键数据的存储和使用
- 分析能力偏弱如复杂的聚合能力偏弱
- 各个分片之间的高可用采用主从复制,可能存在数据脑裂问题
- 单个Node的处理数据容量还有待提升
- ES的安全模块是商业化插件,大量的ES集群缺少合适的安全防护
— 小结—
本文介绍了宽表存储和搜索引擎技术的架构、原理、优缺点(现在各项技术发展比较快,可能存在技术描述跟最新技术发展情况不太一致的情况)。那么有了基础的数据存储管理,下一步是通过整合计算,获得所需结果,面对大数据量,如何实现高吞吐、低延迟、高扩展、支持容错,是分布式计算技术的关键,下一篇起,我们将介绍以MapReduce和Spark为代表的分布式计算技术。【参考文献】【1】Chang F, Dean J, Ghemawat S, et al. Bigtable: A distributed storage system for structured data[J]. ACM Transactions on Computer Systems (TOCS), 2008, 26(2): 1-26.【2】Lars George,HBase: The Definitive Guid, 2011.