HBase的RowKey详解、RowKey设计原则和RowKey优化方法

这篇具有很好参考价值的文章主要介绍了HBase的RowKey详解、RowKey设计原则和RowKey优化方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、RowKey的概念

HBaseRowKey 可以唯一标识一行记录,在 HBase 查询的时候有以下几种方式:

  • 通过 get 方式,指定 RowKey获取唯一一条记录;
  • 通过 scan 方式,设置 startRowstopRow 参数进行范围匹配;
  • 全表扫描,即直接扫描整张表中所有行记录。

从字面意思来看,RowKey就是行键的意思,在增删改查的过程中充当了主键的作用。它可以是任意字符串,在 HBase 内部 RowKey保存为字节数组。

HBase 中的数据是按照 RowKeyASCII字典顺序进行全局排序的,有伙伴可能对 ASCII字典序印象不够深刻,下面举例说明:

假如有5个Rowkey"012""0""123""234""3",按ASCII字典排序后的结果为:"0""012""123""234""3"

因此我们设计Rowkey时,需要充分利用排序存储这个特性,将经常一起读取的行存储放到一起,要避免做全表扫描,因为效率特别低。

2、RowKey设计的三大原则

2.1、RowKey唯一原则

RowKey中数据是以 key-value 格式存储的,RowKey可以类比为MySQL里面的key值,因此在HBase的一张表里面,RowKey不应该重复。而且一个RowKey只能对应一条数据,用RowKeyget表里面的数据时,返回的应该是唯一一条对应的数据记录,不应该返回多条。

另外,因为 RowKey 是按照字典顺序排序存储的,所以可以将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。不过这样做虽然方便了 scan 等范围查询数据,也可能会导致热点问题

2.2、RowKey长度原则

RowKey是一个二进制码流,可以是任意字符串,最大长度 64kb,实际应用中一般为 10-100bytes,以byte[] 形式保存,一般设计成定长。

建议越短越好,不要超过 16 个字节,原因如下:在 HBase 的底层存储 HFile 中,RowKeyKey-Value 结构中的一个域。假设 RowKey 长度 100B,那么 1000 万条数据中,光 RowKey 就占用掉 100*1000w=10 亿个字节 将近 1G 空间,这样会极大影响HFile 的存储效率。

过长会导致 RowKey memStore 中占据的内存空间过大,而实际数据占据的空间很小,只写了少量数据就因为RowKey占据太多空间而flush。因此建议越短越好,不要超过100个字节。

rowkey,HBase,hbase,数据库,大数据

2.3、排序原则

RowKey 是按照字典顺序排序存储的,因此,设计 RowKey 的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。

一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为RowKey 的一部分对这个问题十分有用,可以用Long.Max_Value-timestamp 追加到key 的末尾。

例如 [key][reverse_timestamp],[key]的最新值可以通过 scan [key]获得[key]的第一条记录,因为 HBaseRowKey 是有序的,第一条记录是最后录入的数据。

2.4、RowKey散列原则

散列原则的作用是将数据打散,不要让连续的数据集中在一个region里面,降低热点问题出现的可能性。

# 第一部分数据:
1638584124_user_id
1638584135_user_id
1638584146_user_id
1638584157_user_id
1638584168_user_id
1638584179_user_id

# 第二部分数据:
4214858361Iuser_id
5314858361_user_id
6414858361_user_id
7514858361_user_id
8614858361_user_id
9714858361_user_id

以上面的数据为例,图中的数据就是以时间戳的方式来排序,这样排序如果要访问的数据集中在某一个时间段上,这个时间段内连续的RowKey在一个region里面(因为 HBase 里面的数据按照字典排序,连续写入的时候就会让数据因为连续的 RowKey 会进入相同的 region 里面),对这一个region进行频繁的访问就造成了热点问题。因此应该按照散列原则,给时间戳RowKey的前面加上随机生成的散列字段,这样连续的时间戳数据也会因为随机的散列字段而进入不同的region,避免了热点问题。

当然图上并没有这么做,代码的上半部分数据是原始数据,而代码的下半部分选择将时间戳反转,这样每行RowKey的前几位也是各不相同的,不会被写入同一个region里面,同样避免了热点问题。

3、HFile简单结构示意图

HBase中设计有MemStoreBlockCache,分别对应列族/Store级别的写入缓存,RegionServer 级别的读取缓存。如果 RowKey字段过长,内存的有效利用率就会降低,系统不能缓存更多的数据,这样会降低检索效率。

rowkey,HBase,hbase,数据库,大数据

另外,我们目前使用的服务器操作系统都是 64 位系统,内存是按照 8B 对齐的,因此设计 RowKey时一般做成 8B的整数倍,如 16B 或者 24B,可以提高寻址效率。

同样,列族、列名的命名在保证可读的情况下也应尽量短。value 永远和它的 key 一起传输的。当具体的值在系统间传输时,它的 RowKey,列名,时间戳也会一起传输(因此实际上列族命名几乎都用一个字母,比如'c''f')。如果你的 RowKey和列名和值相比较很大,那么你将会遇到一些有趣的问题。HFile中的索引最终占据了 HBase分配的大量内存。

4、热点问题

我查看了很多博客,很多博客都只说了连续的RowKey在同一个region里面就会导致热点问题,其实这样是没有说完的。因为如果只是RowKey连续,那么RegionServer会自动划分过大的region,这样每个region里面的数据量也是差不多的,不会因为这样就导致热点问题。

导致热点问题的原因是,Clinet访问查询数据时,可能会集中访问某一段连续RowKey的数据,而因为HBase中是按照字典序升序来排列数据的,这样连续将数据写入表中时,连续RowKey的数据就会被划分在同一个region里面,而针对这一段连续RowKey所在的region进行频繁大量的访问,导致region所在的节点机器承受了超出自身处理极限的访问量,从而导致效率低下甚至故障。而其他节点存储的数据因为没有被访问,所以一个节点拼死的忙,其他节点围观看戏,这就造成了热点问题。

另外还有一种情况,那就是设置的预分区不合理,同样会导致热点问题,预分区不合理同样可能导致设置的其中一个region里面的数据被大量访问。

对于热点问题,应该做的是,对RowKey进行合理的设计,让一段连续的RowKey进入不同的region当中,这样就避免了访问集中在同一个region上。

4.1、加盐

RowKey分配一个随机前缀以使得它和之前的RowKey的开头不同。分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致。加盐之后的RowKey就会根据随机生成的前缀分散到各个region上,从而避免热点问题。

4.2、哈希

针对RowKey进行hash运算,运算得出的结果,再拼接到原先RowKey的前面,这样连续RowKey计算得到的hash值不相同,将hash值与RowKey拼接后的新RowKey较大概率不会连续,这样就会被送入不同的region里面

但是上面也说了,这只是较大概率不会连续,但是连续的RowKey计算出来的hash值的前缀依旧可能相同。比如一段连续的RowKeyr1r2r3,这三者经过hash运算后的结果为aaaaabaac,这样虽然hash结果不同,但是hash值的前缀相同,按照字典序排序时依旧是连续的数据。

使用hash的好处是,同一个RowKeyhash值是固定的,因此查询时只要计算一下hash值,依旧可以按照RowKey查询数据。而加盐就是给每一个RowKey随机加上一个前缀,这就导致同一个RowKey,多次加盐的结果也是不同的,因此没办法再用RowKeyget到某一条数据(当然非要用RowKey去查也可以,用子串过滤器,把原来的RowKey作为子串去匹配加盐后的RowKey)。

使用hash的坏处是,虽然可以继续使用get查询,但是因为计算到的hash值依旧可能连续,导致热点问题没有被解决。而加盐可以保证解决热点问题,即连续RowKey的数据一定被划分到不同的region里面。

4.3、反转

第三种防止热点的方法时反转固定长度或者数字格式的RowKey。这样可以使得RowKey中经常改变的部分放在前面。这样可以有效的随机RowKey,但是牺牲了RowKey的有序性。

就比如时间戳,大量连续的时间戳只有最后两三位会改变,前面几位基本不会改变,此时就可以将最后两三位提到最前面,将重复的时间戳部分放到后面,避免了连续。

4.4、时间戳反转

时间戳反转这里的反转应该打上引号,因为这里不是将123变成321这样的反转,而是用大数减去小数,用差值作为新的RowKey

1638620506_uid
1638620512_uid
1638620524_uid
1638620536_uid
1638620548_uid

此时需求是,让最新的记录排在最前面,也就是按照时间戳逆序排序,最新也即最大的时间戳排在最上面方法就是设定一个大数,比如设置一个9999999999的时间戳,然后用这个时间戳去减去上面rowkey里面的时间戳,结果为:

1638620506_uid ——> 8,361,379,493_uid
1638620512_uid ——> 8,361,379,487_uid
1638620524_uid ——> 8,361,379,475_uid
1638620536_uid ——> 8,361,379,463_uid
1638620548_uid ——> 8,361,379,451_uid

这样再排序的时候,按照字典序排列,最后一条RowKey8,361,379,451_uid就会被放在第一位,实现了最新的一条记录放在最前面的需求。文章来源地址https://www.toymoban.com/news/detail-762860.html

到了这里,关于HBase的RowKey详解、RowKey设计原则和RowKey优化方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 头歌 HBase 性能优化:优化拆分和合并

    1. source /etc/profile 2. 3. start - all . sh zkServer . sh start start - hbase.sh    进入终端界面 hbase shell create \\\'stu\\\' ,{ NAME = \\\'info\\\' },{ NAME = \\\'desc\\\' }, SPLITS =   [ \\\'1000\\\' , \\\'2000\\\' , \\\'3000\\\' , \\\'4000\\\' , \\\'5000\\\'] put \\\'stu\\\' , \\\'15653216541\\\' , \\\'info:num\\\' , \\\'14561235651\\\' put \\\'stu\\\' , \\\'15653216541\\\' , \\\'info:s_name\\\' , \\\'cg\\\' put \\\'stu\\\' , \\\'15653216541\\\' ,

    2024年04月14日
    浏览(61)
  • 第 5 章 HBase 优化

    一条数据的唯一标识就是 rowkey,那么这条数据存储于哪个分区,取决于 rowkey 处于 哪个一个预分区的区间内,设计 rowkey的主要目的 ,就是让数据均匀的分布于所有的 region 中,在一定程度上防止数据倾斜。接下来我们就谈一谈 rowkey 常用的设计方案。 1)生成随机数、hash、散

    2024年02月08日
    浏览(37)
  • HBase性能优化与调参

    HBase是一个分布式、可扩展、高性能的列式存储系统,基于Google的Bigtable设计。它是Hadoop生态系统的一部分,可以与HDFS、MapReduce、ZooKeeper等组件集成。HBase具有高可用性、高可扩展性和强一致性等特点,适用于大规模数据存储和实时数据处理。 随着数据量的增加,HBase的性能和

    2024年02月21日
    浏览(37)
  • Hbase基本使用,读写原理,性能优化学习

    HBase简介 HBase定义 Apache HBase 是以 hdfs 为数据存储的,一种分布式、可扩展的 NoSQL 数据库 HBase数据模型 HBase 的设计理念依据 Google 的 BigTable 论文,论文中对于数据模型的首句介绍。 Bigtable 是一个稀疏的、分布式的、持久的多维排序 map。之后对于映射的解释如下: 该映射由行

    2024年02月08日
    浏览(46)
  • hbase优化:客户端、服务端、hdfs

    hbase优化 一.读优化 1.客户端: 2.服务器: 3.列簇:是否过多、 是否使用布隆过滤器:任何业务都应该设置Bloomfilter,通常设置为row就可以,除非确认业务随机查询类型为row+cf,可以设置为rowcol 是否设置ttl 4.hdfs优化: 二、写优化 是否需要写WAL?WAL是否需要同步写入 用批量

    2024年02月14日
    浏览(55)
  • HBase的数据库容量规划与优化

    HBase的数据库容量规划与优化 HBase是一个分布式、可扩展、高性能的列式存储系统,基于Google的Bigtable设计。它是Hadoop生态系统的一部分,可以与HDFS、MapReduce、ZooKeeper等组件集成。HBase适用于大规模数据存储和实时数据访问场景,如日志处理、实时统计、搜索引擎等。 在实际

    2024年02月20日
    浏览(45)
  • 实战案例:HBase的访问控制策略与优化

    在大数据时代,HBase作为一个高性能、可扩展的分布式数据库,已经成为了许多企业和组织的首选。在实际应用中,HBase的访问控制策略和性能优化是非常重要的。本文将深入探讨HBase的访问控制策略与优化,并提供一些实用的最佳实践和技巧。 HBase是一个分布式、可扩展的列

    2024年02月20日
    浏览(40)
  • HBase详解(对hbase集群搭建、读写流程、hbase的javaApi等细致入微的讲解与保姆级的图解)

    我本想用MySQL来与HBase作比较,但发现他们两者毫无可比性,因为两者运用领域不同,各自有各自的优点,就好比爬山穿登山鞋,潜水穿脚蹼一般。 一门技术的兴起,一个优秀的开源项目的存在肯定是有它所存在的意义,正如大数据一样,正是因为随着时间的发展,随着技术

    2024年02月11日
    浏览(40)
  • HBase写入流程详解

    HBase采用LSM树架构,天生适用于写多读少的应用场景。在真实生产线环境中,也正是因为HBase集群出色的写入能力,才能支持当下很多数据激增的业务。需要说明的是,HBase服务端并没有提供update、delete接口,HBase中对数据的更新、删除操作在服务器端也认为是写入操作,不同

    2024年02月14日
    浏览(41)
  • hbase架构详解

    一、什么是Hbae(Hbase的介绍)?         1、Hbase的原型是 Google 的 BigTable 论文,受到该论文思想启发,目前作为hadoop的子项目来开发维护用来支持结构化的数据存储。         2、Hbase是一个高可用、高性能、面向列、可伸缩的分布式存储系统。 二、Hbase的特性 1、海量存

    2024年02月13日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包