HBase 数据存储结构
在HBase中, 从逻辑上来讲数据大概就长这样:
单从图中的逻辑模型来看, HBase 和 MySQL 的区别就是:
- 将不同的列归属与同一个列族下
- 支持多版本数据
这看着感觉也没有那么太大的区别呀, 它解决了 MySQL 的那些问题呢? 每一个新事物的出现, 都是为了解决原本存在的问题.
- 对写入友好, 支持异步大批量并发写入
- 可动态添加列
- 按列存储数据, 不存在的列不会落盘, 节省空间. 而 MySQL 中不存在的内容也要用 null 填充
- 支持海量数据分布式存储(BigTable 最开始就是 Google 为了解决数据存储问题而提出来的)
- 等等
那么他是如何解决这些问题的呢? 他的数据是如何进行存储的呢?
HBase 数据物理结构
在介绍其物理结构之前, 要先简单提一下 LSM 树
LSM树
和 MySQL 所使用的B+树一样, 也是一种磁盘数据的索引结构. B+树是一种对读取友好的存储结构, 但是当大量写入的时候, 比如日志信息, 因为涉及到随机写入, 就显得捉襟见肘了.
而LSM树就是针对这种大量写入的场景而提出的. 他的中文名字叫: 日志结构合并树. 文件存储的是对数据的修改操作, 数据会 append 但不会去修改原有的数据. 是顺序写入操作.
但是, 如果不管不顾的将所有的操作都顺序写入了, 那读取数据的时候没有任何根据, 需要扫描所有操作才能读到. LSM 树的做法是, 先在内存中维护一份小的有序的数据(内存不存在随机读写的问题), 当这份数据超过一定大小的时候, 将其整个放入磁盘中.
这样, 磁盘中就存在很多个有序的文件了, 但是会有大量的小文件, 读取数据时要依次查找, 导致读取性能降低. 这时就需要对多个小文件进行多路归并合成一个文件来优化读取的性能.
至此, 基本就是LSM 树的全部思想了.
- 在内存中维护一个有序的数据
- 将内存中的数据push 到磁盘中
- 将磁盘中的多个有序文件进行归并, 合成一个较大的有序文件
HBase存储
在HBase中, 数据的存储就使用了 LSM 树进行存储. 其中每一条数据都是一条操作记录. 那么在HBase实现中的部分内容如下.
内存有序结构的实现
通过跳表来维护内存中的有序结构, 当一个跳表装满之后, 将禁止新的写入操作并将其 push 到磁盘中, 同时开一个新的数据结构来接收新到的操作请求.
每条数据的存储内容
存储了一个KV 键值对, 其中的 V 就是我们写入的值, 而这个 key 由以下部分组成:
- row key
- 列族
- 列名
- 时间戳
- 操作类型: Put、Delete、DeleteColumn、DeleteFamily 等等
整个列表是 key 的顺序列表. 其排序规则如下:
- row key小的排在前面
- 同 row key 比较列族
- 同列族比较列名
- 同列名比较时间戳, 时间戳大的在前面.
按照这个顺序进行读取指定 row key 的某一列数据时, 最先拿到的数据就是最新的版本, 若是 delete 操作, 说明最后执行了删除操作, 即使后面有数据, 最新数据也是空.
磁盘文件的结构
由三部分组成:
- 头信息: 存储文件大小, 文件块数量, 索引位置, 索引大小等信息
- 索引数据: 用户对文件中所有数据块进行索引, 其中每一个数据块都包含一条索引数据, 索引内容包括
- 数据块的最后一条数据. 用于对索引进行二分查找, 快速定位到指定的数据块
- 数据块在文件中的位置
- 数据块的大小
- 布隆过滤器. 用户在扫描时快速过滤不存在的数据块
- 数据块. 其中存储了每一条 KV 数据.
按照这个结构, 用户在进行指定row_key 读取的时候, 每个文件的操作如下:
- 根据头信息内容, 加载索引数据
- 通过二分查找, 找到 row_key 在哪一数据块下
- 根据布隆过滤器过滤掉不存在的数据块, 加速读取
- 根据数据块的位置和大小, 找到指定数据块并二分查找指定数据
HBase 数据列族式存储
先简单回顾一下行式存储和列式存储.
行式存储
行式存储, 将一行数据存储在一起, 一行数据写完了才会写下一行. 例如典型的 MySQL.
行式存储在读取一行数据的时候是比较快的, 但如果读取的是某一列数据, 也需要将整行读取到内存中进行过滤.
列式存储
与行式存储相对应的就是列式存储, 既将一列数据存储在一起, 不同列的数据分别存储.
列式存储对于只读取某一列比较友好, 但相对的, 如果要读取多列数据, 需要读取多次并进行合并.
列族式存储
而 HBase 中选用了一种折中的方案, 列族式存储, 将列族放到一起存储, 不同列族分别存储.
那么也就是说, 如果一个表有多个列族, 每个列族下只有一列, 那么就等同于列式存储
如果一个表只有一个列族, 该列族下有多个列, 那么就等同与行式存储.
HBase 会将一张表同一列族的数据, 分配到同一个 region 上, 这个region 分配在集群中的某一个 regionServer. 所有的 region 存储在表: hbase:meta 表中, 表结构如下:
表不同列含义如下:
- row_key 由以下字段拼接(逗号)而成
- 表名
- 起始 row_key
- 创建时间戳
- 上面三个字段的md5
- info:regioninfo 主要存储以下数据(json)
- STARTKEY: 起始 row_key
- ENDKEY: 结束 row_key
- NAME: region 名
- ENCODED: 不清楚是什么
- info:seqnumDuringOpen 表示regionServer 在线时长
- info:server 落在哪个 regionServer 上
- info:serverstartcode regionServer 的启动时间
- 等等
总结
简单了解了HBase的数据落盘格式, 也大概解释 HBase 的很多疑惑, 比如:
- 为什么只支持 row key 索引查询
- 因为整个文件是按照 row key 排序的
- 为什么读取效率比 MySQL 低
- 因为要依次读取文件进行查找
- 为什么支持高效率的写入操作
- 因为全部都是顺序读写操作
- 应该如何设置 HBase 的列族
- 将同一场景读取的放到同一列族下, 不同场景读取的放到不同列族下
- 等等
HBase 数据存储结构的更多相关文章
- HBase 的存储结构
HBase 的存储结构 2016-10-17 杜亦舒 HBase 中的表常常是超级大表,这么大的表,在 HBase 中是如何存储的呢?HBase 会对表按行进行切分,划分为多个区域块儿,每个块儿名为 ...
- Cassandra 的数据存储结构——本质是SortedMap<RowKey, SortedMap<ColumnKey, ColumnValue>>
Cassandra 的数据存储结构 Cassandra 的数据模型是基于列族(Column Family)的四维或五维模型.它借鉴了 Amazon 的 Dynamo 和 Google's BigTab ...
- Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)
Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...
- kafka 数据存储结构+原理+基本操作命令
数据存储结构: Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的.每个topic又可以分成几个不同的partition(每个topic有几个partitio ...
- HBase介绍(2)---数据存储结构
在本文中的HBase术语:基于列:column-oriented行:row列组:column families列:column单元:cell 理解HBase(一个开源的Google的BigTable实 ...
- HBase数据存储
HRegionServer  HBase的数据文件都存储在HDFS上,格式主要有两种: - HFile:HBase中KeyValue数据的存储格式,HFile是Hadoop的二进制文件,实际上Sto ...
- BigData NoSQL —— ApsaraDB HBase数据存储与分析平台概览
一.引言 时间到了2019年,数据库也发展到了一个新的拐点,有三个明显的趋势: 越来越多的数据库会做云原生(CloudNative),会不断利用新的硬件及云本身的优势打造CloudNative数据库, ...
- Hashtable数据存储结构-遍历规则,Hash类型的复杂度为啥都是O(1)-源码分析
Hashtable 是一个很常见的数据结构类型,前段时间阿里的面试官说只要搞懂了HashTable,hashMap,HashSet,treeMap,treeSet这几个数据结构,阿里的数据结构面试没问 ...
- 使用MapReduce读取HBase数据存储到MySQL
Mapper读取HBase数据 package MapReduce; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hba ...
随机推荐
- 数据结构-kmp算法
定义 改进字符串的匹配算法 关键:通过实现一个包含了模式串的局部匹配信息的next()函数,利用匹配失败的信息,减少匹配次数. 1.BF算法 暴力匹配 给定 文本串S "BBC ABCDAB ...
- AtCoder Beginner Contest 169
比赛链接:https://atcoder.jp/contests/abc169/tasks A - Multiplication 1 #include <bits/stdc++.h> us ...
- xml——dom&sax解析、DTD&schema约束
dom解析实例: 优点:增删改查一些元素等东西方便 缺点:内存消耗太大,如果文档太大,可能会导致内存溢出 sax解析: 优点:内存压力小 缺点:增删改比较复杂 当我们运行的java程序需要的内存比较大 ...
- Codeforces Round #667 (Div. 3) E. Two Platforms (双指针)
题意:有\(n\)个点往下落,你可以在最下面放两个长度为\(k\)的板子,问做多能接到多少个点. 题解:这题给纵坐标\(y\)完全没有用,我们先对横坐标\(x\)排序,然后从左边开始枚举,用\(l[i ...
- Round Numbers POJ - 3252
题意: 如果你个数的二进制中1的个数要小于等于0的个数,那么这个数就符合题意.现在要你找出来区间[li,ri]这个区间内有多少这样的数 题解: 题意很明显了,是要用二进制,所以我们也把给的区间边界转化 ...
- CF1466-D. 13th Labour of Heracles
CF1466-D. 13th Labour of Heracles 题意: 给出一个由\(n\)个点构成的树,每个点都有一个权值.现在你可以用\(k,k\subset\)\([1, n]\)个颜色来给 ...
- Django分页APP_django-pure-pagination
一.App说明 该App用户Django的数据分页功能 二.安装 pip install django-pure-pagination 三.使用方法 (1)settings注册 INSTALLED_A ...
- 网络安全知识--PHP代码审计/Web For Pantesters 的 SQL injection
SQL 注入一般流程 判断有无注入 单引号判断: ?name=root' 对应语句 select * from table where name='root'' 不符合语法规范,报错,说明有注入 an ...
- USB2.0协议学习笔记---USB数据包结构
USB包类型和传输过程 USB是一种串行总线,因此数据都是一位一位传输的,如同串口那样,但是USB在真实物理电路上却不是TTL电平,而是一种差分信号采用NRZI编码,就是用变化表示0,不变表示1,同 ...
- Lua 从入门到放弃
Lua 从入门到放弃 What is Lua? Lua is a powerful, efficient, lightweight, embeddable scripting language. It ...