用大白话彻底搞懂 HBase RowKey 详细设计

来源 | 且听_风吟

来源 | CSDN 博客,责编 | Carol

封图 | CSDN 付费下载于东方 IC

前言

RowKey作为HBase的核心知识点,RowKey设计会影响到数据在HBase中的分布,还会影响我们查询效率,所以RowKey的设计质量决定了HBase的质量。是咱们大数据从业者必知必会的,自然也是面试必问的考察点。

那么rowkey到底是什么呢?原理是什么呢?怎么设计RowKey呢?使用场景是怎样的呢?有哪些设计原则呢?又如何进行优化呢?

下面就让我们带着这些问题,一起探索RowKey的世界!

RowKey的概念

RowKey从字面意思来看是行键的意思,咱们知道HBase可以理解为一个nosql(not only sql)数据库,既然是数据库,那么咱们日常使用最多的就是增删改查(curd)。其实在增删改查的过程中RowKey就充当了主键的作用,它和众多的nosql数据库一样,可以唯一的标识一行记录。

RowKey行键 (RowKey)可以是任意字符串,在HBase内部,RowKey保存为字节数组。存储时,数据按照RowKey的字典序(byte order)排序存储。设计RowKey时,要充分利用排序存储这个特性,将经常一起读取的行存储放到一起。

RowKey的特点小结如下:

  1. RowKey类似于主键,可以唯一的标识一行记录;

  2. 由于数据按照RowKey的字典序(byte order)排序存储,因此HBase中的数据永远都是有序的。

  3. RowKey可以由用户自己指定,只要保证这个字符串不重复就可以了。

知识点补充:在HBase中检索数据时使用到RowKey的一共有三种方式:

  • get:通过指定单个RowKey来获取对应的唯一一条记录;

  • like:通过RowKey的range来进行匹配;

  • scan:通过设置startRow和stopRow参数来进行范围匹配(注意:如果不设置就是全表扫描)。

RowKey的作用

要了解RowKey的作用,首先我们需要知道在HBase中,一个Region就相当于一个数据分片,每个Region都有StartRowKey和StopRowKey(用来表示 Region存储的RowKey的范围),HBase表里面的数据是按照RowKey来分散存储到不同的Region里面的。

为了避免热点现象咱们需要将数据记录均衡的分散到不同的Region中去,因此需要RowKey满足这种散列的特点。此外,在数据读写过程中也是与RowKey密切相关的。RowKey的作用可以归纳如下:

  1. Hbase在读写数据时需要通过RowKey找到对应的Region;

  2. MemStore和HFile中的数据都是按照 RowKey 的字典序排序。

那到底啥是热点现象呢?咱们接着分析!

热点现象

4.1、热点现象怎么产生

我们知道HBase中的行是按照rowkey的字典顺序排序的,这种设计优化了 scan操作,可以将相关的行以及会被一起读取的行存取在临近位置,便于 scan读取。

然而万事万物都有两面性,在咱们实际生产中,当大量请求访问HBase集群的一个或少数几个节点,造成少数RegionServer的读写请求过多,负载过大,而其他RegionServer负载却很小,这样就造成热点现象(吐槽:其实和数据倾斜类似,还整这么高大上的名字)。

掌握了热点现象的概念,我们就应该知道大量的访问会使热点Region所在的主机负载过大,引起性能下降,甚至导致Region不可用。所以我们在向HBase中插入数据的时候,应优化RowKey的设计,使数据被写入集群的多个region,而不是一个。尽量均衡地把记录分散到不同的Region中去,平衡每个Region的压力。

其实RowKey的优化主要就是在解决怎么避免热点现象。那么有哪些避免热点现象的方法呢?各有什么缺点?带着问题,接着往下看。

4.2、如何避免热点现象(RowKey的优化)

在日常使用中,主要有3个方法来避免热点现象,分别是反转,加盐和哈希。听起来很奇怪,下面咱们逐个举例详细分析:

4.2.1、反转(Reversing)

第一种咱们要分析的方法是反转,顾名思义它就是把固定长度或者数字格式的 rowkey进行反转,反转分为一般数据反转和时间戳反转,其中以时间戳反转较常见。

适用场景:

比如咱们初步设计出的RowKey在数据分布上不均匀,但RowKey尾部的数据却呈现出了良好的随机性(注意:随机性强代表经常改变,没意义,但分布较好),此时,可以考虑将RowKey的信息翻转,或者直接将尾部的bytes提前到RowKey的开头。反转可以有效的使RowKey随机分布,但是反转后有序性肯定就得不到保障了,因此它牺牲了RowKey的有序性。

缺点:

利于Get操作,但不利于Scan操作,因为数据在原RowKey上的自然顺序已经被打乱。

举例:

比如咱们通常会有需要快速获取数据的最近版本的数据处理需求,这时候就需要把时间戳作为RowKey来查询了,但是时间戳正常情况下是这样的:

1588610367373
1588610367396

前面这部分是相同的,在查询的时候就容易造成热点现象,因此需要使用时间戳反转的方式来处理。实际生产中可以用Long.Max_Value - timestamp追加到 key 的末尾,比如 [key][reverse_timestamp], [key]的最新值可以通过scan [key]获得[key]的第一条记录,因为HBase中RowKey是有序的,所以第一条记录是最后录入的数据。

常见的场景,比如需要保存一个用户的操作记录,就可以按照操作时间倒序排序,在设计rowkey的时候,可以这样设计[反转后的userId][Long.Max_Value - timestamp],在查询用户的所有操作记录数据的时候,直接指定反转后的userId,startRow 是[反转后的userId][000000000000],stopRow 是 [反转后的userId][Long.Max_Value - timestamp]。如果需要查询某段时间的操作记录,startRow 是[反转后的userId[Long.Max_Value - 起始时间], stopRow 是[反转后的userId][Long.Max_Value - 结束时间]。

4.2.2、加盐(Salting)

第二种咱们要介绍的方法是加盐,玩过密码学的可能知道密码学里也有加盐的方法,但是咱们RowKey的加盐和密码学不一样,它的原理是在原RowKey的前面添加固定长度的随机数,也就是给RowKey分配一个随机前缀使它和之前的RowKey的开头不同。

适用场景:

比如咱们设计的RowKey是有意义的,但是数据类似,随机性比较低,反转也没法保证随机性,这样就没法根据RowKey分配到不同的Region里,这时候就可以使用加盐的方式了。

需要注意随机数要能保障数据在所有Regions间的负载均衡,也就是说分配的随机前缀的种类数量应该和你想把数据分散到的那些region的数量一致。只有这样,加盐之后的rowkey才会根据随机生成的前缀分散到各个region中,避免了热点现象。

缺点:

大白话来理解就是加了盐就尝不到原有的味道了。因为添加的是随机数,添加后如果还基于原RowKey查询,就无法知道随机数是什么,那样在查询的时候就需要去各个可能的Region中查找,同时加盐对于读取是利空的。并且加盐这种方式增加了读写时的吞吐量。

4.2.3、哈希(Hashing)

最后介绍大家最熟悉的哈希方法,不管是学的啥技术,都会涉及到哈希,也都大同小异,比较简单。

这里的哈希是基于RowKey的完整或部分数据进行Hash,而后将哈希后的值完整替换或部分替换原RowKey的前缀部分。这里说的hash常用的有MD5、sha1、sha256 或 sha512 等算法。

适用场景:

其实哈希和加盐的适用场景类似,但是由于加盐方法的前缀是随机数,用原rowkey查询时不方便,因此出现了哈希方法,由于哈希是使用各种常见的算法来计算出的前缀,因此哈希既可以使负载分散到整个集群,又可以轻松读取数据。

缺点:

与反转类似,哈希也打乱了RowKey的自然顺序,因此也不利于Scan。

RowKey设计原则

通过前面的分析我们应该知道了HBase中RowKey设计的重要性了,为了帮助我们设计出完美的RowKey,HBase提出了RowKey的设计原则,一共有四点:长度原则、唯一原则、排序原则,散列原则。

RowKey在字段的选择上,需要遵循的最基本原则是唯一原则,因为RowKey必须能够唯一的识别一行数据。无论应用的负载特点是什么样,RowKey字段都应该首先考虑最高频的查询场景。数据库通常都是以如何高效的读取和消费数据为目的,而不仅仅是数据存储本身。然后再结合具体的负载特点,再对选取的RowKey字段值进行改造,结合RowKey的优化,也就是避免热点现象的那些方法来优化就可以了。

5.1、长度原则

RowKey本质上是一个二进制码的流,可以是任意字符串,最大长度为64kb,实际应用中一般为10-100byte,以byte[]数组形式保存,一般设计成定长。官方建议越短越好,不要超过16个字节,原因可以概括为如下几点:

  • 影响HFile的存储效率:HBase里的数据在持久化文件HFile中其实是按照Key-Value对形式存储的。这时候如果RowKey很长,比如达到了200byte,那么仅仅1000w行的记录,只考虑RowKey就需占用近2GB的空间,极大的影响了HFile的存储效率。

  • 降低检索效率:由于MemStore会缓存部分数据到内存中,如果RowKey比较长,就会导致内存的有效利用率降低,也就不能缓存更多的数据,从而降低检索效率。

  • 6字节是64位操作系统的最佳选择:64位系统,内存8字节对齐,控制在16字节,8字节的整数倍利用了操作系统的最佳特性。

5.2、唯一原则

其实唯一原则咱们可以结合HashMap的源码设计或者主键的概念来理解,由于RowKey用来唯一标识一行记录,所以必须在设计上保证RowKey的唯一性。

需要注意:由于HBase中数据存储的格式是Key-Value对格式,所以如果向HBase中同一张表插入相同RowKey的数据,则原先存在的数据会被新的数据给覆盖掉(和HashMap效果相同)。

5.3、排序原则

HBase会把RowKey按照ASCII进行自然有序排序,所以反过来我们在设计RowKey的时候可以根据这个特点来设计完美的RowKey,好好的利用这个特性就是排序原则。

5.4、散列原则

散列原则用大白话来讲就是咱们设计出的RowKey需要能够均匀的分布到各个RegionServer上。

比如设计RowKey的时候,当Rowkey 是按时间戳的方式递增,就不要将时间放在二进制码的前面,可以将 Rowkey 的高位作为散列字段,由程序循环生成,可以在低位放时间字段,这样就可以提高数据均衡分布在每个Regionserver实现负载均衡的几率。

结合前面分析的热点现象的起因,思考:

如果没有散列字段,首字段只有时间信息,那就会出现所有新数据都在一个 RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer上,不分散,就会降低查询效率。

HBase里的RowKey是按照字典序存储,因此在设计RowKey时,咱们要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。如果最近写入HBase表中的数据是最可能被访问的,可以考虑将时间戳作为row key的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作为row key,这样能保证新写入的数据在读取时可以被快速找到。

总结

看到这里RowKey的各个方面应该都已经搞懂了,本文从RowKey的原理,可能出现的问题,如何优化及各个优化措施对应的缺点和适用的场景,设计原则等角度对RowKey进行了详细全面的解析,相信一定能对你有所帮助。

如果您对我的文章感兴趣,欢迎关注点赞收藏,如果您有疑惑或发现文中有不对的地方,还请不吝赐教,非常感谢!!

本文为 CSDN 博主「且听_风吟 」原创,首发于 CSDN 博客,转载请经授权。原文链接:https://blog.csdn.net/qq_26803795/article/details/105994960

 

推荐阅读

  • 后端程序员必备:书写高质量SQL的30条建议

  • 蚂蚁金服高要求的领域建模能力,对研发来说到底指什么?

  • Redis 6.0 新特性:多线程连环 13 问!

  • AI 修复 100 年前晚清影像喜提热搜,有穿越内味儿了!

  • 你现在从事的程序员还有多久会消失?牛津大学研究员帮你算了算

  • 一次对语音技术的彻底批判

  • 到底是哪些人在玩链游?| 《区块链游戏玩家研究报告》

真香,朕在看了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517989.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于Spring AOP,除了动态代理、CGLIB,你还知道什么?

来源 | 草捏子责编 | Carol封图 | CSDN 付费下载于视觉中国Spring 作为 Java 中最流行的框架,主要归功于其提供的 IOC 和 AOP 功能。本文将讨论 Spring AOP 的实现。第一节将介绍 AOP 的相关概念,若熟悉可跳过,第二节中结合源码介绍 Spring 是…

ETL异构数据源Datax_Oracle同步MySQL(全量)_04

文章目录一、Oracle同步Mysql1. 构建json2. 执行数据同步3. 查看同步数据4. 同步数据正确性和准确性5. 同步日志分析一、Oracle同步Mysql 1. 构建json vim oracle2mysql.json{"job": {"setting": {"speed": {"channel": 3},"er…

# 学习使用计算机

冯.诺依曼体系结构 计算机软件 快捷键的使用 CtrlC 复制Ctrlv 粘贴CtrlA 全选CtrlZ 撤销CtrlS保存CtrlShiftEsc 打开任务管理器wlndows 打开菜单AltTab 切换页面AltF4 关闭窗口ShiftDelete 永久删除wlndowsR 打开运行窗口wlndowsE 打开文件资源管理器wlndowsTab 管理页面 Dos…

ETL异构数据源Datax_使用数据分片提升同步速度_05

文章目录1. 构建json,添加数据分片2. Mysql数据清除3. 数据分片前后对比1. 构建json,添加数据分片 {"job": {"setting": {"speed": {"channel": 3},"errorLimit": {"record": 0,"perc…

Flink 1.9 实战:使用 SQL 读取 Kafka 并写入 MySQL

上周六在深圳分享了《Flink SQL 1.9.0 技术内幕和最佳实践》,会后许多小伙伴对最后演示环节的 Demo 代码非常感兴趣,迫不及待地想尝试下,所以写了这篇文章分享下这份代码。希望对于 Flink SQL 的初学者能有所帮助。完整分享可以观看 Meetup 视…

java的基础语法和数据类型,IDEA

IDEA的用法 快捷方法 主函数:psvm输出语句:sout java基础语法注释 注释:必须要写注释 单行注释://多行注释:/**/文档注释javaDoc:/***/ 平时写代码要注意规范 标识符和关键字 所有标识符应该都以字母&…

手把手教你配置VS Code 远程开发工具,工作效率提升N倍

来源 | 后端技术学堂责编 | Carol封图 | CSDN 付费下载于视觉中国今天和大家分享一个远程开发解决方案,聊一聊我平常是如何用 VS Code 进行远程开发工作的,以及一步步教你搭建远程开发环境,拥有比德芙还丝滑的远程开发体验。我们厂里为了最大…

蚂蚁金服隗华:十五年时间见证分布式数据库的崛起

北大计算所启蒙 “做中国人自己的技术” 如果用一句话来评价读书时的隗华(花名:风羿),那一定是“德智体美劳全面发展的好学生”。本科在北航读的计算机专业,硕士则就读于北大的计算机研究所。 北大,中国高…

用户数从 0 到亿,我的 K8s 踩坑血泪史

导读:容器服务 Kubernetes 是目前炙手可热的云原生基础设施,作者过去一年上线了一个用户数极速增长的应用:该应用一个月内日活用户从零至四千万,用户数从零到一亿的裂变式增长,充分享受了容器服务快速简便的扩容操作和…

行,Python玩大了!​取代Excel,程序员:太牛!你怎么看?

Python真的玩大了吗?2020年,Python程序员究竟怎么样?A与B程序员与远方近日日本最大的证券公司之一野村证券首席数字官马修汉普森,在Quant Conference上发表讲话:“用Excel的人越来越少,大家都在用Python。”…

云原生计算重塑企业IT架构 - 分布式应用架构

进入21世纪以来,我们见证了企业分布式应用架构从SOA(Service-oriented Architecture),到微服务架构,再到云原生应用架构的演化。 为了说明企业架构演化背后的思考,我们先谈一些玄学。 第一,企业IT系统的复杂性&#…

首发!《长安十二时辰背后的技术秘籍》正式公开,速来下载

一名死囚如何在十二时辰内利用“唐代黑科技”,拯救长安百姓于水火中? 这就是《长安十二时辰》的故事,剧中有恢弘的长安美景、让人流口水的水晶柿子/水盆羊肉,还有张小敬和檀棋“在一起”呼声……然而,最让人刮目相看的…

ETL异构数据源Datax_MySQL同步Oracle(全量)_07

文章目录1. 清除Oracle数据库中OTBS1表的数据2. 构建json3. 执行脚本4. 同步验证5. 同步分析7. 同步结果1. 清除Oracle数据库中OTBS1表的数据 Truncate TABLE OTBS1;2. 构建json {"core": {"transport": {"channel": {"speed": {&qu…

左手代码右手滑板 支付宝这个程序员有些酷

走在杭州支付宝z空间的园区,常常可以看到一个脚踩滑板,脑后扎个发髻的男青年。 他叫边柳。来蚂蚁金服三年,除了是一名前端码农,也是一位斜杠青年。捧着程序员的“饭碗”,兼顾着滑板和摇滚的爱好,可以说他过…

2019阿里云910会员节大促主会场全攻略

2019阿里云910会员大促活动已经于8月28日正式开启,从已开放的活动页面来看,整场大促活动由阿里云10年有礼时光机、爆款产品推荐、七大分会场组成。 在910这个秋季大幅度优惠促销日,怎样才能花最少的钱配置最特惠的云服务?云栖社区…

浪潮商用机器与腾讯TDSQL完成互认证 共同拓展Power行业生态

日前,浪潮商用机器有限公司宣布,旗下K1 Power服务器系列产品经过几十项基础功能和高可用功能用例的专业测试,与腾讯新兴国产分布式数据库TDSQL完美兼容,且性能优异,可进行顺利的部署、平稳的运行及对外提供服务。此次互…

历时五天用 SwiftUI 做了一款 APP,阿里工程师如何做的?

作者|姜沂(倾寒) 出品|阿里巴巴新零售淘系技术部 导读:自 2014 年苹果发布会发布 Swift 之后, Swift 经过多年迭代,终于达到了 ABI 稳定版本,也意味着 Swift 做为稳定的得语言,值得用在大型 APP, 用来生产环境中。 2…

Istio从懵圈到熟练 – 二分之一活的微服务

Istio is the future!基本上,我相信对云原生技术趋势有些微判断的同学,都会有这个觉悟。其背后的逻辑其实是比较简单的:当容器集群,特别是K8S成为事实上的标准之后,应用必然会不断的复杂化,服务…

数据结构与算法、讲解、动态规划一脸懵?看完之后轻松掌握!

来源 | 昊天码字责编 | Carol封图 | CSDN 付费下载于视觉中国碰到动态规划问题摸不着头脑?总结不出动态规划的类型?有多少人曾经历过这种迷茫与无助?看完本文,让你一脚迈进动态规划的大门。我们在用递归求解问题的过程中&#xff…

搜索场景下的智能推荐演变之路

摘要:传统的推荐手段主要还是深度挖掘用户行为和内容本身相似性的价值,包括但不限于协同过滤,内容表征向量召回,以及各式各样的点击率预估模型,然后这样的推荐行为缺乏内在的逻辑性和可解释性,有一种知其然…