设为首页 加入收藏

TOP

hbase复习和压缩算法
2019-02-12 13:42:16 】 浏览:26
Tags:hbase 复习 压缩 算法

问题:
存储在HDFS上的一个大文件有100T,怎么在实时的要求下,快速找出对应的record
实时的增删改查 hbase 根据key 查找value 底层二进制编码 序列化和反序列化
主键 列簇1 列簇2 。。。
设计核心:跳表 + 布隆过滤器
HBase : 数据库 ,底层数据存储在HDFS

Hive只要支持 select 查询延迟很高 底层的执行引擎,其实就是一个分布式的计算引擎
hbase的最大特性就是解决根据key进行实时查询的需求,一般来说,不适合做关联查询

怎么解决大量数据集中的单条记录的实时增删改查?

1、第一,数据要排序, 二分查找

2、第二,因为数据集特别大,所以,需要分片。 分而治之

以上这两个特点结合起来,就是一个数据结构: 跳表

表的所有数据按照rowkey进行字典排序的。

如果按照rowkey进行查询,快速的定位到用户要查询的rowkey到底在最底层的那个小文件中,最后再去扫描这个小文件

配合使用布隆过滤器 怎么实现的

提前在每一个小文件(region)设置好了一个布隆过滤器,那么根据布隆过滤器的特点。它能快速的判断,某个value是否在这个集合中。

优点:快速判断一个元素是否在这个集合(region)中
缺点:存在误判: 如果返回true,有可能是假的。 如果返回false,那么一定是不存在

布隆过滤器会占用额外的磁盘空间,底层数据文件,肯定不止1G

hbase的表结构:

1、表 和普通的mysql中的表的概念是一样的

2、rowkey 所有的数据,在进行查询的时候,一般来说,都是根据rowkey
但是也可以使用过滤器,去扫描整张表的数据

1、hbase的表数据的查询方式:

直接根据rowkey
根据rowkey的范围range
全表扫描<

br>
2、rowkey的长度限制问题

不能超过64KB, 最好在10-100byte之间 最好16,最好是8的倍数

3、列簇

一组key组成一个列簇: 具有相同IO特性

查询其中一个key1的时候一般来说,都会查询另外一个key2
所以说key1和key2具有相同的IO特性

经验推荐: 虽然说在部分场景中,有可能存储的数据,就具有多个不同的IO特性,应该要存储成为多个不同的列簇
但是根据经验来判断,最好使用一个列簇

4、列

真正的key-value中的key就是列
插入的key-value到底应该存储在哪个列簇中,是在插入的时候,一定要指定的

5、时间戳

作用:就相当于一个key_value中的value的多个版本的版本号

两种管理方式:

1、保存最近的最新的N个版本
2、保存一定时间范围内的所有数据, 如果某个版本数据超过时限要求,那么会被hbase的服务器自动删除的。

hbase的架构:
首先hbase集群有三种角色:
client
server : 主从架构
主节点:hmaster
从节点:hregionserver
hbase依赖于:

1、hdfs做数据存储
2、zookeeper做协调(解决SPOF, 存储寻址入口)

hmaster没有参与真正的数据的查询和插入的处理(主要用来管理hregionserver的状态,和所有的region的负载均衡)

单点故障的问题,但是不迫切

表示:hbase的主节点,可以在宕机了以后,整个hbase集群依然可以对外提供服务

当前hbase中的每个region都会增长。增长到10G的大小的时候就会进行分裂

分裂的标准:在hbase1.x以前,是256M
在hbase1.x开始,是10G

分裂出来的两个region一般来说,hregionserver会汇报给hmaster,hmaster一般来说,都会寻找
一个新的hregionserver来进行存储这分裂出来的两个region当中的一个


原始数据表raw:所有hbase表都会有多个region
.meta.:所有的这些region的映射信息都存储在第二级表中。映射信息过多,造成第二级表也会进行分裂,形成多个region
-root-:第二级表的多个region也被映射起来,存储在第一级表-root-中

最终的核心要点: -root-这个表中的数据量不管多大,都不会进行分裂

找到-root-这个表的那个唯一region在哪里,就能找到数据是哪些region

zookeeper给hbase存储寻址入口:
其实就是存储了-root-表的唯一region在哪个hregionserver中 但是会经常有迁移操作

hbase的寻址机制

region就是一张hbase表的逻辑抽象单位

一个region并不是一个单独的文件, 在HDFS上的目录树中体现为一个文件夹

regionserver:

1、一个regionserver中的所有region都是来自于一个表么? 不是的。

2、一个表的所有region都存储在一个表中么 不是的。

所有表的所有region是进行负载均衡的处理之后存储在整个hbase集群

hbase的启动前提:

启动zk
启动hdfs
hdfs dfsadmin -safemode
hdfs haadmin -getServiceState nn1/nn2

HBase的shell操作:

1、进入客户端:hbase shell

2、查看当前hbase的shell命令有那些:help

3、通过查看帮助文档可以得知;

a、如果哪个命令不会使用: help "command"
b、如果不知道具体有那些组或者组中的命令的名称: help "command_group"

2、关于库

关于表(创建create,查看表列表list。查看表的详细信息desc,删除表drop,清空表truncate,修改表的定义alter)

关于数据的操作(增put,删delete,查get + scan, 改==变相的增加

drop == 清空数据truncate + 删除表定义

hbase的表一经创建之后。那么列簇的名字就不能更改了。

可以通过先删除列簇,然后添加回来,但是你必须要承受 损失这个列簇

修改:alter

get : rowkey

scan : 不用指定rowkey

hbase的java api操作:

HDFS当中的核心API :2 个

HBase当中的核心API :13个

HBaseConfiguration 配置信息
Connection
HBaseAdmin/Admin 管理员

HTable 整个表的抽象信息
HColumnDescriptor 列的描述信息
HTableDescriptor 列簇的描述信息

Put
Delete
Get
Scan

KeyValue
Cell

Result
ResultScanner
Filter

过滤器
分页操作

分享的面试的问题总结:

1、hbase的调优。 MR的调优, Hive的调优, Spark调优。

负载不均衡的问题/数据倾斜的问题

2、集群架构和节点数,数据量的问题

推导公式: 方便你们自己去模拟和构造数据量

30TB

每条记录的长度
总记录数
数据记录的总天数

3、数据仓库 Hive 数据仓库

hive的执行引擎:MR, Hive2推荐使用Spark
数据支撑:HDFS
也有可能来自于HBase Hive和HBase的整合
ZooKeeper
Hive的使用简单: 就是编写SQL

4、Spark中的一个面试题
跟kafka做整合的问题
Spark Streaming + kafka
消费数据有三种模式:
1、至少一次
2、最多一次
3、有且仅有一次 必须依赖 zookeeper

往hbase中插入数据的五种方式:

1、table.put(put)
2、table.put(puts)
3、MR
4、多线程多客户端并发写入
5、bulkload

其实是使用MR程序提前生成好HFile

最基本的数据插入:

1、首先往WAL Log中记录日志数据

2、把数据更新到内存

3、内存达到一定的阈值之后,就会flush数据到磁盘HFile

4、HfILE达到一定数量之后,就会进行合并。 StoreFile


hbase的底层原理:

1、hbase的各种核心概念(表)

key-value数据库(rowkey, hashmap)
一张四维表格
rowkey 行健(全局字典排序, 不能超过64KB, 最好10-100字节)
列簇 就是包含了一组具有相同IO特性的一组key
列 面向列,等同的任务是mysql表中的列
值 hbase表中的所有数据,都是按照字节数组存储
时间戳 控制hbase中的真正的key-valeu中的vlaue的版本的

get 'student','rk01','cf1:age',ts

2、hbase的组织架构

hbase的集群特点: 主从架构

1、hmaster 管理节点 主节点
2、hregionserver 工作节点 从节点
3、zookeeper 服务协调(选举master, 存储寻址入口:-root-这个表的那个唯一的region的唯一region在哪个regionserver)
4、hdfs 分布式的文件系统,用来给hbase做底层的数据存储支撑的。
/hbase126/data/default/user_info/846ce4c6701699c71bf4711a9a88e8d8/base_info/55378f109cbd4092bc59bd5b34c3afb7
55378f109cbd4092bc59bd5b34c3afb7: storefile hfile

5、mapreduce 非必须组件
6、client 给用户提供一个终端工具可以操作hbase(发送请求读写hbase库)


3、hbase的shell操作

hbase shell
help
help 'get' || help 'ddl'

4、api
con.getAdmin()
con.getTable()
Put Delete Get Scan

get : Result
Scan : ResultScanner

Cell 由 rowkey + cf + key + ts 唯一确定的一个格子 value KeyValue
分页过滤器
整合mapreduce : TableMapRedcueUtil (initTableMapperJob initTableReducerJob)
bulkload方式往hbase表中插入数据 (没有记录 HLog)

habse的底层原理:

在hbase的文件组织形式上,一定要记住:
一个集群会有多个regionserver
每一个regionserver就是用来去管理master分配给它的region
每一个regionserver中管理的所有的region是有可能来自于多个不同的table的
每一个regionserver中的所有region在进行数据插入的时候是会被记录日志的。

client:
存储了-root-这张表的那个唯一的region的所有数据会被缓存在当前这个resgionserver中的内存中

client会缓存第一次查询到的 -root- 这张表的那个唯一的region是存储在哪个regoinserver中的位置信息

client第一次请求,没有办法,只能通过请求zookeepr得到-root-的位置
client第N次请求的时候,直接从缓冲中保存的-root-的位置地址,直接请求即可
有可能会出现缓存失效, 再次重新请求zk即可

hbase的regionserver构造:
1、client发送的 put delete 其实在底层的数据文件中,都是 追加的形式
2、一个store就是就是一个region中的一个列簇
一个store由 一个memestore和多个storeFile(HFile)
为什么这么构造?
1、解决效率问题,如果都是在内存中进行查询和插入,效率高
2、解决安全问题,因为内存存在着掉电丢失数据的情况,数据存磁盘就不害怕数据的丢失
WAL

1、首先记录日志
2、然后更新请求数据到内存
3、当内存上涨到一定限制时,所以需要溢写数据到磁盘
4、溢出到磁盘的文件有可能会有很多,会进行合并

1、为了删除无效数据
2、为了保证全局有序

合并:

简单的说,就是把rowkey相同的所有KeyValue对象收集到一起,进行合并,按照key Type进行操作
首先判断是否有相同的key(行健,列簇,列,ts)对象,判断key type 同时也会判断事件戳
add delete ==== 最终抵消 delete add ===== 不会不出现
只有刚溢写出来的文件才会由 delete的keytype出现

hbase的数值组织形式:

1、表
2、region
3、store
4、hfile
5、data block ----> data
6、keyvalue
7、kv(rowkey, cf, qualifier, value, ts)

缓存淘汰算法:
FIFO
LRU least recently used
LFU : least frequently used
memcached redis
每一个列簇中的属性信息有很多。其中有一项叫做;
BloomFilter = Row

如果溢写出来一个HFile之后,触发了 compact 操作:
这个 compact 一定是 minor compact:
compact : 小合并 大合并
major_compact 和 minor_compact 的区别:
minor_compact 仅仅合并小文件(HFile) count(HFile) >= 3 就会触发 不会进行Put Delete数据的合并
清理的数据就是 设置了 TTL(time to live) 过期了的数据

major_compact 合并一个 region 内的所有文件
把所有的小文件都合并成一个大文件:StoreFile --- HDFS ---- HFile

小合并自动执行
大合并必须手动执行 -- 默认的配置是 --- 七天 ---- 一天

分裂 : 一个 region 一分为二

RS :
1、管理 master 分配给它的 region

2、管理 region的 分裂

3、管理 region 中的 storefile的合并

4、其实每一个regionserver都是一个 HDFS 客户端

RS 上线 和 下线


master:

1、管理所有的 regionserver

2、接收所有的regionserver的汇报,然后进行region的负载均衡

3、维护hbase的元数据信息(namespace, table,column family)

master可以宕机一段时间:

1、受影响: 所有 master该做的事都没有机器做,所以, 元数据的修改操作统统不能做

2、不受影响: 插入 和 查询不受影响。

master的上线 和 下线


压缩算法的比较
以下是Google几年前发布的一组测试数据(数据有些老了,有人近期做过测试的话希望能共享出来):

Algorithm % remaining Encoding Decoding
GZIP 13.4% 21 MB/s 118 MB/s
LZO 20.5% 135 MB/s 410 MB/s
Zippy/Snappy 22.2% 172 MB/s 409 MB/s

其中:

1)GZIP的压缩率最高,但是其实CPU密集型的,对CPU的消耗比其他算法要多,压缩和解压速度也慢;

2)LZO的压缩率居中,比GZIP要低一些,但是压缩和解压速度明显要比GZIP快很多,其中解压速度快的更多;

3)Zippy/Snappy的压缩率最低,而压缩和解压速度要稍微比LZO要快一些。

BigTable和HBase中压缩算法的选择
BigTable中采用的是Zippy算法,目标是达到尽可能快的压缩和解压速度,同时减少对CPU的消耗。

HBase中,在Snappy发布之前(Google 2011年对外发布Snappy),采用的LZO算法,目标和BigTable类似;在Snappy发布之后,建议采用Snappy算法(参考《HBase: The Definitive Guide》),具体可以根据实际情况对LZO和Snappy做过更详细的对比测试后再做选择。

实际项目中的实践经验
项目中使用clearspring公司开源的基数估计的概率算法:stream-lib,用于解决去重计算问题,如UV计算等,它的特点在于:

1)一个UV的计算,可以限制在一个固定大小的位图空间内完成(不同大小,对应不同的误差率),如8K,64K;

2)不同的位图可以进行合并操作,得到合并后的UV。

当系统中维护的位图越多的时候,不管是在内存中,还是在存储系统(MySQL、HBase等)中,都会占用相当大的存储空间。因此,需要考虑采取合适的算法来压缩位图。这里分为以下两类情况:

1)当位图在内存中时,此时压缩算法的选择,必须有尽可能快的压缩和解压速度,同时不能消耗过多CPU资源,因此,适合使用LZO或Snappy这样的压缩算法,做到快速的压缩和解压;

2)当位图存储到DB中时,更关注的是存储空间的节省,要有尽可能高的压缩率,因此,适合使用GZIP这样的压缩算法,同时在从内存Dump到DB的过程也可以减少网络IO的传输开销。


编程开发网
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Hbase FilterList使用总结 下一篇HBase的SQL引擎(1)-Phoenix

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(217) }