1.Google的三篇论文
①GFS:
- 第一次揭示了如何在大量廉价机器基础上存储海量数据
②MapReduce:
- 揭示了如何在大量廉价机器的基础上稳定的实现超大规模的并行数据处理
③BigTable
- 解决海量结构化数据的存储以及高效读写的问题
2.HBase数据模型
①HBase是一个Map,由键值构成,与普通Map不同的是,HBase是一个稀疏的、分布式的、多维排序的Map
3.逻辑视图
①table:表,一个表包含多行数据
②row:行,一行数据包含一个唯一标识rowkey、多个column以及对应的值。在HBase中,一张表中的数据所有row都按照rowkey的字典顺序由小到大排序
③column:列,与关系型数据库中的列不同,HBase中的column有column family(列簇)以及qualifier(列名)两部分组成,两者通过“:”相连。比如contents:html,
其中content为列簇,html为列簇下具体的一列。column family在创建表的时候需要指定,用户不能随意增减。一个column family下可以设置任意多个Qualifier,因此可以理解为HBase中的列可以动态增加,理论上可以扩展到上百万列
④timestamp:时间戳,每个cell在写入HBase的时候都会默认分配一个时间戳作为该cell的版本。HBase支持多版本特性,即同一rowkey、column下可以有多个value存在,这些value使用timestamp作为版本号,版本越大,表示数据越新
⑤cell:单元格,由五元素(row,column,timestamp,type,value)组成的结构,其中type表示Put/Delete这样的操作类型,timestamp代表这个cell的版本。这个结构在数据库中实际是以KV结构存储的,其中(row,column,timestamp,type)是K,value字段对应KV结构的V
⑥Hbase引入了列簇的概念,列簇下的列可以动态扩展;另外,HBase使用时间戳实现了数据的多版本支持
4.多维稀疏排序Map
①BigTable本质上是一个Map结构数据库,HBase亦然,也是由一系列KV构成的。
②HBase是稀疏的、分布式的、持久性的、多维的以及排序的
③HBase中Map的Key是一个复合键,由rowkey、column、family、Qualifier、type以及timestamp组成,value即为cell值
④多维:HBase的key是一个复合结构,由多维元素构成,包括rowkey、column family、qualifier、type以及timestamp
⑤稀疏:对于空值,Hbase不需要任何填充。因此稀疏性是HBase的列可以无限扩展的一个重要条件
⑥排序:构成HBase的KV在同一个文件中都是有序的——先比较rowkey,rowkey小的排在前面;如果rowkey相同,再比较column,即column family:qualifier,column小的排在前面;如果column还相同,再比较时间戳timestamp,即版本信息,timestamp大的排在前面
⑦分布式:构成HBase的所有Map并不集中在某台机器上,而是分布在整个集群中
5.物理视图
①HBase中的数据是按列簇存储的,即将数据按照列簇分别存储在不同目录中
| rowkey | timestamp | columnfamily:anchor |
|---|---|---|
| “com.cnn.www” | t9 | anchor:cnnis.com=”CNN” |
| “com.cnn.www” | t8 | anchor:mylook.ca=”CNN.com” |
6.行式存储、列式存储、列簇式存储
①行式存储:
- 行式存储系统会将一行数据存储在一起,一行数据写完之后再接着写下一行,最典型的是MySQL这类关系型数据库
- 行式存储在获取一行数据时是很高效的,但是如果查询某个只需要读取表中指定列对应的数据,那么行式存储会先取出一行行数据,再在每一行数据中截取待查找目标列。这种处理方式在查找过程中引入了大量无用列信息,从而导致大量内存占用。因此,这类系统仅适合处理OLTP类型的负载,对于OLAP这类分析型负载并不擅长
②列式存储:
- 列式存储理论上会将一列数据存储在一起,不同列的数据分别集中存储。
- 列式存储对于只查找某些列数据的请求非常高效,只需要连续读出所有待查找目标列,然后遍历处理即可;但是反过来,列式存储对于获取一行数据的请求就不那么高效了,需要多次IO读取多个列数据,最终合并得到一行数据。另外同一行数据通常具有相同的数据类型,因此列式存储具有天然的高压缩特性
③列簇式存储:
- 列簇式存储介于行式存储和列式存储之间,可以通过不同的设计思路在行式存储和列式存储之间切换。
7.Hbase体系结构
①HBase体系结构借鉴了BigTable论文,是典型的master-slaver模型
②系统中有一个管理集群的Master节点以及大量实际服务用户读写的RegionService节点。
③HBase中所有数据最终都存储在HDFS系统中
④HBase集群系统中还有一个Zookeeper节点,协助Master对集群进行管理
8.Hbase客户端
①HBase客户端访问数据之前,首先需要通过元数据表定位目标数据所在RegionServer,之后才会发送请求到该RegionServer。同时这些元数据会被缓存到客户端本地,以方便之后的请求访问。如果集群RegionService发生宕机或者执行了负载均衡等,从而导致数据分片发生迁移,客户端需要重新请求最新元数据并缓存在本地
9.Zookeeper
①用于协调管理分布式应用
②实现Master的高可用:通常情况下系统中只有一个Master工作,一旦Active Master由于异常宕机,Zookeeper会检测到该宕机事件,并通过一定机制选举出新的Master,保证系统正常运转
③管理系统核心元数据:比如,管理当前系统中正常工作的RegionService集合,保存系统元数据表hbase:meta所在的RegionServer地址等
④参与RegionServer宕机恢复:Zookeeper通过心跳可以感知到RegionServer是否宕机,并在宕机后通知Master进行宕机处理
⑤实现分布式表锁:HBase中对一张表进行各种管理操作需要先加表锁,防止其他用户对同一张表进行管理操作,造成表状态不一致。
10.Master
①处理用户的各种管理请求,包括建表、修改表、权限操作、切分表、合并数据分片以及Compaction等
②管理集群中所有RegionServer,包括RegionServer中Region的负载均衡、RegionServer的宕机恢复以及Region的迁移等
③清理过期日志以及文件,Master会每隔一段时间检查HDFS中HLogs是否过期、HFile是否已经被删除,并在过期之后将其删除
11.RegionService
①主要用来响应用户的IO请求,是HBase中最核心的模块,有WAL(HLog)、BlockCache以及多个Region构成
②WAL(HLog):HLog在HBASE有两个核心作用
- 用于实现数据的高可靠性,并非直接写入HFile数据文件,而是先写入缓存,再异步刷新落盘。为防止缓存数据丢失,数据写入缓存之前需要先顺序写入HLog,这样,即时缓存数据丢失,数据写入缓存之前首先顺序写入HLog,这样,即使缓存数据丢失,任然可以通过HLog日志恢复
- 用于实现HBase集群间主从复制,通过回放主集群推送过来的HLog日志实现主从复制
③BlockCache:
- HBASE系统中的读缓存。客户端从磁盘读取数据之后通常会将数据缓存到系统之中,后续访问同一行数据可以直接从内存中获取而不需要访问磁盘。对于有大量热点读的业务来说,缓存机制会带来极大的性能提升
- BlockCache缓存对象时一系列Block块,一个Block块默认为64K,有物理上相邻的多个KV数据组成。BlockCache同时利用了空间局部性和时间局部性原理,前者表示最近将读取的KV数据很可能与当前读取到的KV数据在地址上是邻近的,缓存单位是Block而不是单个KV就可以实现空间局部性;后者表示一个KV数据正在被访问,那么近期他还可能再次被访问。当前BlockCache主要有两种实现方式——LRUBlockCache和BucketCache,前者实现相对简单,而后者在GC优化方面有明显的提升
④Region:表示数据分片,当数据表大小超过一定阈值就会“水平切分”,分裂为两个Region。Region是集群负载的基本单位。通常一张表的Region会分布在整个集群的多态RegionServer上,一个RegionServer上会管理多个Region,当然,这些Region一般来自不同的数据表
- 一个Region由一个到多个Store构成,Store的个数取决于表中列簇的个数,多少个列簇就有多少个Store。
- HBase中,每个列簇的数据都集中存放在一起的形成一个存储单元Store,因此建议将由相同IO特性的数据设置在同一个列簇中。
- 每个Store由一个MEMStore和一个或多个HFile组成。MemStore称为写缓存,用户写入数据时首先会写到MEMStore,当MEMStore写满之后(缓存数据超过阈值,默认128M),系统会异步地将数据flush成一个HFile文件。显然,随着数据不断写入,HFile文件会越来越多,当HFile文件数量超过一定阈值之后系统将会执行Compact操作,将这些小文件通过一定策略合并成一个或多个大文件
12.HDFS
①HBase底层依赖HDFS组件存储实际数据,包括用户数据文件、HLog日志文件等最终都会写入HDFS落盘
②HDFS数据默认3副本存储策略可以有效保证数据高可靠性
③Hbase内部封装了一个名为DFSClient的HDFS客户端组件,负责对HDFS的实际数据进行读写访问
13.HBase的优点
①容量巨大:HBase的单表可以支持千亿行、百万列的数据规模,数据容量可以达到TB甚至PB级别。传统关系型数据库,如果单条记录超过亿行,读写性能就会急剧下降,在HBase中不会出现这样的问题
②良好的可扩展性:HBase集群可以非常 方便的实现集群容量扩展,主要包括数据存储节点扩展以及读写服务节点扩展。HBase底层数据存储依赖于HDFS系统,HDFS可以通过简单的增加DataNode实现扩展,HBase读写服务节点也一样,可以通过简单增加RegionServer节点实现计算层的扩展
③稀疏性:HBase支持大量稀疏存储,即允许大量列值为空,并不占用任何存储空间。。因此HBase可以存储至多上百万列的数据,即时表中存在大量的空值,也不需要任何额外的存储空间
④高性能:HBase目前擅长于OLTP场景,数据写操作性能强劲,对于随机单点读以及小范围的扫描读,其性能也能够得到保证。对于大范围的扫描读可以使用MapReduce提供的API,以便实现更高效的并行扫描
⑤多版本:HBase支持多版本特性,即一个KV可以同时保留多个版本,用户可以根据需要选择最新版本或者某个历史版本
⑥支持过期:HBase支持TTL过期特性,用户只需要设置过期时间,超过TTL的数据就会被自动清理,不需要用户写程序手动删除
14.HBase的缺点(可以通过Phoenix、Spark等组件解决)
①HBase不支持很复杂的聚合运算(如join、groupby等)。
②HBase本身没有实现二级索引功能,所以不支持二级索引查找
③HBase原生不支持全局跨行事务,只支持单行事务模型
