第五章 Hbase专题之建表高级操作&表设计优化

1、建表属性

1.1、建表基本语句
create "table","cf1":"column","value"

create "table",{NAME => "cf1", VERSION => 3}.{NAME => "CF2",TTL=1212212}

(1)表名:没有太多要求,见名知意

(2)列簇定义

  • 列簇名称长度:最好就一个字母

  • 列簇的个数:最好就是一个,不超过三个

  • 列属性定义:列簇名称、最大版本、生命周期、布隆过滤器、读缓存

1.2、列簇属性之BLOOMFILTER(布隆过滤器)
  • 含义:是否使用布隆过滤及使用何种方式,布隆过滤可以每列族单独启用
使用方法:create 'table',{NAME => 'baseinfo' BLOOMFILTER => 'ROW'}
  • HColumnDescriptor.setBloomFilterType拥有三种策略:

    • ①NONE:不使用布隆过滤器
    • ②ROW:行键的哈希在每次插入行时将被添加到布隆,主要用于经常查询行键时
    • ③ROWCOL:行键 + 列族 + 列族修饰的哈希将在每次插入行时添加到布隆,主要用于行和列簇中的列的联合查询
  • 作用:用布隆过滤可以节省读磁盘过程,可以有助于降低读取延迟

1.3、列簇属性之VERSION(版本号)
  • 含义:是数据保留多个版本
create 'table',{ NAME => 'baseinfo' VERSIONS=>'2'}
  • 相关策略
    • MIN_VERSIONS => ‘0’:在compact操作执行之后,至少要保留的版本
      • 前提:只有在设置了TTL时候生效
1.4、列簇属性之COMPRESSION(压缩)
  • 含义:是该列族是否采用压缩,采用什么压缩算法
create 'table',{NAME=>'info',COMPRESSION=>'SNAPPY'}
  • 相关压缩算法:推荐使用Snappy算法,标准 - 压缩率、压缩速率

在这里插入图片描述

  • 注意事项:如果建表之初没有压缩,后来想要加入压缩算法,可以通过alter修改schema
1.5、列簇属性之TTL(Time To Live)
  • 含义:列族数据的存活时间,单位是s

  • 删除时间:下次 major compact的时候再彻底删除数据

  • 默认时间:默认是2147483647,即:Integer.MAX_VALUE 值大概是68年

2、Hbase建表优化之预分区

2.1、预分区概述

​ 在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客 户端都向这一个region写数据,直到这个region足够大了才进行切分。

​ Hbase预分区:通过预先创建一些空的regions,这样当数据写入HBase时,会按照region分区情况,在集群内做 数据的负载均衡,从而加快批量写入速度

2.2、命令行创建预分区
# 1、创建表直接将表切分为5段
hbase>create 'table1','f1',SPLITS => ['\x10\x00', '\x20\x00', '\x30\x00','\x40\x00']

# 2、创建表时指定该表有8个Region,分界值算法为UniformSplit
hbase>create 'table2','f1', { NUMREGIONS => 8 , SPLITALGO => 'UniformSplit' }

# 3、创建表时指定该表有10个Region,分界值算法为HexStringSplit
hbase>create 'table3','f1', { NUMREGIONS => 10, SPLITALGO => 'HexStringSplit' }
2.3、API方式创建预分区
hbase org.apache.hadoop.hbase.util.RegionSplitter test_table HexStringSplit -c
10 -f info
hbase org.apache.hadoop.hbase.util.RegionSplitter splitTable HexStringSplit -c
10 -f info
  • 参数详述:
test_table:表名
HexStringSplit:split 方式
-c:指定初始region数量
-f:指定family信息

3、Hbase建表优化之BulkLoad

3.1、BulkLoad原理概述
  • 含义:批量插入

​ 正常数据进行插入的时候,都要进行先写操作日志,再写内存,等待时间/数据量会触发flush和compact和split

​ BulkLoad模式通过mapreduce程序直接生成 HFile, 直接导入到hbase表中的

  • BulkLoad原理示意图:

img

(1)从数据源中提取数据,通常是文本文件或者其他数据库,然后将数据文件上传到HDFS中

(2)将数据转换为HFile,这个步骤需要MapReduce,将rowkey作为OutputKey,将一个Put或者Delete作为OutputValue,在这个阶段,将会在输出文件夹中,一个Region就创建一个HFile。注意输入的数据将会几乎被重写,所以所需的磁盘空间至少比原始的数据集的大小多一倍,在进程结束后,可以删除转储文件。

(3)通过告知RegionServers在哪里找到这些文件,并且将文件加载到HBase中,这一步需要使用LoadIncrementalHFiles。

  • 缺点:因为没有写入Hlog日志,所以如果数据丢失,就没有找回的可能
3.2、命令行实现BulkLoad
  • 生成好的HFile文件迁移到目标集群(即HBase集群所在的HDFS上),然后在使用HBase命令进行导入
# 先使用distcp迁移hfile
hadoop distcp -Dmapreduce.job.queuename=queue_1024_01 -update -skipcrccheck -m 10
/tmp/pres hdfs://nns:9000/tmp/pres

# 使用bulkload方式导入数据
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /tmp/pres person

4、RowKey设计原则

​ HBase中表会被划分为1…n个Region,被托管在 RegionServer 中。Region 二个重要的属性: StartKey 与 EndKey 表示这个 Region 维护的 rowKey 范围,当我们要读/写数据时,如果 rowKey 落在 某个start-end key范围内,那么就会定位到目标region并且读/写到相关的数据

4.1、长度原则
  • 定义:不能太长,最好一个,建议不要超过16个字节

(1)Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;

(2)MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多 的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。

4.2、唯一原则
  • 定义:同一张表的所有rowkey肯定是唯一的

​ 必须在设计上保证其唯一性。rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这 个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。

4.3、散列原则
  • 定义:将数据(Region)分散均匀,保证负载均衡。

​ 如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段, 由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。如 果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer上堆积的热点现象,这 样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。

5、列簇设计原则

  • 追求原则:在合理范围内能尽量少的减少列簇就尽量减少列簇。
  • 最优设计:将所有相关性很强的key-value都放在同一个列簇下,这样既能做到查询效率最高,也能保持尽可能少的访问不同的磁盘文件

CASE:以用户信息为例,可以将必须的基本信息存放在一个列族,而一些附加的额外信息可以放在另一列族 hbase的列簇越少越好!尽量就是1个。

6、数据热点

6.1、数据热点原因

(1)hbase的中的数据是按照字典序排序的,当大量连续的rowkey集中写在个别的region,各个region之间数据分布不均衡;

(2)创建表时没有提前预分区,创建的表默认只有一个region,大量的数据写入当前region;

(3)创建表已经提前预分区,但是设计的rowkey没有规律可循,设计的rowkey应该由regionNo+messageId组成。

6.2、数据热点解决方案
  • 核心:设计出可以让数据分布均匀的RowKey,让每个Region的负载是相同的

(1)加盐

​ 在rowkey的前面增加随机数,具体就是给**rowkey分配一个 随机前缀以使得它和之前的rowkey的开头不同。**分配的前缀种类数量应该和你想使用数据分散到不同 的region的数量一致。加盐之后的rowkey就会根据随机生成的前缀分散到各个region上,以避免热点。

(2)哈希

哈希会使同一行永远用一个前缀加盐,哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的rowkey,可以使用get操作准确获取某一个行数据。

  • 注意事项:既可以分散,也可以让相同特征的值存储在一起

(3)反转

反转固定长度或者数字格式的rowkey,这样可以使得rowkey中经常改变的部分(最没有意义的部分)放在前面。这样可以有效的随机rowkey,但是牺牲了rowkey的有序性。

CASE:以手机号为rowkey,可以将手机号反转后的字符串作为rowkey,这样的就避免了以 手机号那样比较固定开头导致热点问题

(4)时间戳反转

​ 一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为rowkey的一部分对这个 问题十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如 [key] [reverse_timestamp] , [key] 的最新值可以通过scan [key]获得[key]的第一条记录,因为HBase中 rowkey是有序的,第一条记录是最后录入的数据。

CASE:比如需要保存一个用户的操作记录,按照操作时间 倒序排序,在设计rowkey的时候,可以这样设计 [userId反转] [Long.Max_Value - timestamp],在查询用户的所有操作记录数据的时候,直接指定反转 后的userId,startRow是[userId反转] [000000000000],stopRow是[userId反转] [Long.Max_Value - timestamp]

7、Hbase的数据访问方式

(1)单个rowkey:非常频繁的一些 rokwey尽量分散;

(2)范围查询

  • 如果要查询的数据量很大,但是数据很分散,那么就需要从很多regoinserver去查询;
  • 如果要查询的数据量很大,但是又都集中在一个节点,那么这个节点的压力就比较大。

(3)全表扫描

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随缘清风殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值