HBase RowKey:这是什么?原则?如何设计?使用场景?设计原则?优化?
RowKey的设计会影响HBase中数据的分布,也会影响我们查询的性能,所以RowKey的设计质量决定了HBase的质量。这是大数据专业人士需要了解和理解的,当然也是面试必答题。
那么rowkey是什么?什么是原则?如何塑造RowKey?使用场景有哪些?设计原则是什么?如何优化呢?
带着这些问题来探索RowKey的世界吧!
RowKey概念
RowKey字面意思是物种的钥匙。我们知道HBase可以理解为一个nosql(不仅仅是sql)数据库。既然是数据库,我们日常使用最多的就是增删改查。 (干酪)。 事实上,在增删改查的过程中,RowKey充当主键。与许多 nosql 数据库一样,它可以唯一标识记录类型。
RowKey 的行键( RowKey )可以是任何字符串,在 HBase 内部 RowKey 存储为字节字段。数据按照RowKey的字典顺序(字节顺序)存储。设计RowKey时,充分利用整理保存功能,将经常一起阅读的行保存起来。
RowKey的特点总结如下:
RowKey类似于主键,可以唯一标识一组记录;
由于数据是按照RowKey的字典顺序(字节顺序)存储的,所以HBase中的数据总是顺序的。
如果字符串不重复,则可以由用户定义RowKey。
补充知识点:在HBase中检索数据时使用RowKey的方式有3种:
get:获取指定单个RowKey对应的唯一记录;
like:使用RowKey范围进行匹配;
scan:通过设置startRow和stopRow参数进行范围匹配(注:如果不设置,则会扫描整个表)。
RowKey的角色
要理解RowKey的角色,我们首先要知道HBase中的一个Region相当于一个数据分片。每个Region都有一个RowKey作用域Start RowKey和Stop RowKey(用来表示该Region的存储),HBase表中的数据根据RowKey分散存储在不同的Region中。
为了避免热点现象,我们需要将数据记录均匀分布到不同的区域,所以RowKey必须满足这种哈希的特性。此外,数据的读写过程也与RowKey密切相关。 RowKey的作用可以概括为:
Hbase在读写数据时必须通过RowKey找到合适的区域;
MemStore和HFile中的数据是按照RowKey的字典顺序排列的。
那么什么是热点现象呢?我们继续分析吧!
热点现象
热点现象是如何产生的?
我们知道HBase中的行是按照rowkey词典的顺序排列的。这种设计优化了扫描操作,并允许将串联的行一起读取。酒吧就在附近,方便扫描。
然而,任何事情都有两个方面。在我们的实际生产中,当大量请求访问一个或几个HBase集群节点时,某些RegionServer读写请求过多,负载过重,而其他RegionServer负载过重。小的话,就会造成热点出现(点评:其实和数据不规则差不多,只是名字这么崇高)。
掌握了接入点现象的概念后,我们应该知道,大量的访问会使接入点区域所在的主机过载,导致性能下降,甚至导致该区域不可达。因此,在向HBase插入数据时,应该优化RowKey的计划,使数据写入集群的多个区域,而不是一个。将记录尽可能均匀地划分到不同的区域,以平衡各个区域的压力。
实际上,RowKey的优化主要是避免热点的解决方案。那么避免热点的方法有哪些呢?各自的缺点是什么?带着问题继续阅读。
。如何避免热点(RowKey优化)
在日常使用中,避免热点的方法主要有三种,分别是翻、盐、搅拌。听起来很奇怪。我们来一一详细分析一下:
.1。车削
我们要分析的第一个方法是车削。顾名思义,它是固定长度或数字格式的rowkey转换。取消分为一般数据取消和时间戳取消,其中时间戳取消最为常见。
有用的场景:
比如我们原本设计的RowKey数据分布是不均匀的,但是RowKey尾巴上的数据表现出了很好的随机性(注:随机性强意味着变化频繁,没有意义,但是分布更好),此时可以考虑将RowKey信息反转或者直接将最后一个字节移至RowKey开头。翻转可以有效地让RowKey随机分布,但翻转后的有序性肯定无法保证,所以牺牲了RowKey的有序性。
缺点:
适合Get操作,但不适合Scan操作,因为原始RowKey中数据的自然顺序被打乱了。
示例:
比如我们通常有最新版本的数据处理需求,需要快速检索数据。目前,我们需要查询RowKey的时间戳,但时间戳通常是这样的:
15886103673731588610367396
前面的部分是一样的。查询过程中很容易产生热点,需要通过改变时间戳来处理。实际生产中,可以在key的末尾追加Long.Max_Value-timestamp,如[key][reverse_timestamp]。通过扫描[key]获取[key]的第一条记录就可以得到[key]的最新值,因为在HBase中RowKey是可以的,所以第一条记录就是最后一个输入。
常见场景,例如需要保存用户操作记录,可以按照操作时间倒序排序。在设计rowkey的时候,可以这样设计[反转的userId][Long.Max_Value - 时间戳],在查询记录所有用户操作的数据时,直接指定反转的userId。 startRow 是 [反转的 userId] [000000000000],stopRow 是 [反转的 userId] [Long.Max_Value - 时间戳]。如果需要查询特定时间段的交易记录,startRow为[reverse userId [Long.Max_Value - 开始时间],stopRow为[reverse userId] [Long.Max_Value - 结束时间]。
.2。腌制
我们要介绍的第二种方法是腌制。玩过密码学的人可能都知道,密码学中也有加盐的方法,但是我们的加盐和密码学习就不一样了,它的原理是在原来的RowKey前面加上一个固定长度的随机数,即赋值随机添加 RowKey 前缀,以不同于前一个 RowKey 的开头。
比如我们设计的RowKey是有道理的,但是数据相似,随机性比较低。逆转不能保证随机性,因此,根据RowKey的说法,不能将其分配到不同的地区。在此期间,您可以使用 Sol 输出插件。
需要注意的是,随机数必须能够平衡所有区域之间的数据负载。这意味着随机分配的前缀类型数量必须与您想要将数据分发到的区域数量一致。只有这样,盐rowkey才会根据随机生成的前缀分散到不同的区域,从而避免出现热点现象。
简单来说,如果加了盐,就尝不到原来的味道了。由于添加了随机数,因此如果添加后仍在查询原始 RowKey,您将不知道随机数是什么。那么在查询的时候就必须在不同的可能的区域中进行搜索。同时,加盐有损阅读。添加盐会增加读写吞吐量。
.3。哈希
最后介绍一下大家最熟悉的哈希方法。无论你学什么技术,都会涉及到哈希。它们都很相似并且相对简单。
这里的哈希值是基于全部或部分RowKey数据的哈希值,然后将哈希值全部或部分替换为原始RowKey的前缀。这里提到的常用哈希包括 MD5、sha1、sha256 或 sha512 等算法。
其实哈希和加盐的相关场景是类似的,但是由于加盐方法的前缀是随机数,不方便使用原始的rowkey查询,所以出现了哈希方法,因为哈希应用了不同的频繁算法到计算出的前缀,以便散列在整个集群中分配负载并轻松读取数据。
与倒置一样,哈希会破坏 RowKey 的自然顺序,因此不鼓励扫描。
RowKey的设计原则
通过前面的分析,你应该知道RowKey的设计在HBase中的重要性了。为了帮助我们设计出完美的RowKey,HBase介绍了RowKey的设计原则。总共有四点:长度原则、唯一性原则、排序原则、凝聚原则。
RowKey 在选择字段时,最基本的原则 是唯一性原则,因为RowKey 必须能够唯一标识一类数据。无论应用程序的负载特性如何,RowKey 字段都应该首先考虑最常见的查询场景。数据库通常被设计为有效地读取和使用数据,而不仅仅是存储数据。然后,结合负载的具体特点,对RowKey场的选取值进行变换,并与RowKey优化相结合,即可以优化热点回避方法。
,长度原则
RowKey本质上是一个二进制代码流,可以是任何字符串。最大长度为 64 kb。实际应用中一般为10-100字节。它以字节数组[]的形式存储。一般设计成固定长度。官方建议是越短越好,不要超过16字节。原因可以总结为:
影响HFile的存储效率:HBase中的数据实际上是基于持久化HFile中的key和value。以表格形式保存。此时,如果RowKey很长,比如达到200字节,仅考虑RowKey,仅仅1000w行的记录就占用了近2GB的空间,这极大地影响了HFile的存储效率。
降低检索效率:因为MemStore会将部分数据缓存在内存中,如果RowKey比较长,内存的有效使用就会减少,更多的数据无法缓存,从而降低检索效率。
6字节是64位操作系统的最佳选择:64位系统,内存按8字节对齐,控制在16字节,8字节的整数倍充分利用了操作系统的最佳特性操作系统。
,独特原理
其实,结合HashMap源码设计或者主键的概念就可以理解独特原理。由于RowKey是用来唯一标识一类记录的,因此设计时必须保证RowKey的唯一性。
注意:由于HBase中的数据存储格式是键值对格式,如果将相同的RowKey数据插入到HBase中的同一张表中,原来存在的数据将被新数据覆盖。 (与HashMap效果相同)。
,排序原理
HBase会根据ASCII按照自然顺序对RowKey进行排序,所以我们在设计RowKey的时候,可以根据这个特性设计出完美的RowKey。该功能的一个很好的用途是排序原则。
,哈希原理
哈希原理用大白话来说,就是我们设计的RowKey必须均匀分布在各个RegionServer上。
例如绘制RowKey时,当Rowkey以时间戳递增时,不要将时间放在二进制代码之前。 Rowkey的高位可以作为程序循环生成的哈希字段,低位可以插入时间。该字段可以提高数据在每个区域服务器上均匀分布以实现负载平衡的可能性。
根据前面分析的热点发生原因,我们认为:
如果没有哈希字段,且第一个字段只有时间信息,那么所有新数据都积累的地方就会出现热点。区域服务器。这样,在检索数据时,负载将集中在各个区域服务器上。如果不扩散的话,查询的效率就会降低。
HBase中的RowKey是按照字典顺序存储的,所以在设计RowKey的时候,我们需要充分利用这种排序特性,将经常读取的数据存储在一个块中,并合并最近可以访问的数据。如果最有可能访问最近写入 HBase 表的数据,您可以考虑使用时间戳作为行键的一部分。由于它是按字典顺序排序的,因此可以使用 Long.MAX_VALUE 作为行键 - 一个可以确保有新记录的时间戳。读取时可以快速找到传入的数据。
总结
看完这篇你应该了解RowKey的方方面面了。本文从RowKey的原则、可能出现的问题、优化方法、各优化措施的缺点和应用场景、规划原则等角度出发。相信对RowKey进行详细全面的分析会对您有所帮助。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。