HBase RowKey设计和实现

news2024/11/24 0:36:44

HBase由于存储特性和读写性能,在OLAP即时分析中发挥重要作用,Rowkey的设计好坏关乎到HBase的使用情况。
我们知道HBase中定位一条数据需要四个维度的限制:RowKey,Column Family,Column Qualifier,Timestamp。RowKey是其中最容易出错的,不仅需要根据业务和查询需求来设计,还有很多地方需要关注。

RowKey是什么?

HBase中RowKey可以唯一标识一行记录,在HBase查询时会有几种形式:

  1. 通过get方式,指定RowKey获取唯一一条记录。
  2. 通过scan方式,设置startRow和stopRow参数进行范围匹配。
  3. 全表扫描,直接扫描整表所有数据。
    RowKey字面上来看,就是行键意思,在增删改查中充当主键,它可以使任意字符串,在HBase内部RowKey保存为字节数组。
    HBase中的数据是按照RowKey的ASCII字典顺序进行全局排序的,因此在设计RowKey时,要利用排序存储的特性,将经常读取的行存储到一起,避免做全表扫描。

数据热点?

不合理的RowKey设计产生热点问题,热点发生在大量的客户端直接访问集群的一个或极少数个节点(访问可能为读或写or其他操作)。
大量的访问使热点region所在的单个机器超出自身承受能力,引起性能下降甚至导致region不可用,也将影响到同一个RegionServer上的其他region,由于主机无法服务其他region请求,就造成数据热点的现象。
所以在向HBase中插入数据时,应该优化RowKey的设计,使数据被写入集群的多个region中,尽量将记录均衡的分散到不同的region中,平衡每个region的压力。

怎么避免热点问题?

主要的方法有反转,加盐和哈希。

反转

把固定长度或数字格式的RowKey进行反转,反转分为数据反转和时间戳反转,常用时间戳反转。

  • 反转固定格式的数值以手机号为例,手机号的前缀变化比较少(如152、185等),但后半部分变化很多。如果将它反转过来,可以有效地避免热点。不过其缺点就是失去了有序性。

  • 反转时间这个操作严格来讲不算“打散”,但可以调整数据的时间排序。如果将时间按照字典序排列,最近产生的数据会排在旧数据后面。如果用一个大值减去时间(比如用99999999减去yyyyMMdd,或者Long.MAX_VALUE减去时间戳),最新的数据就可以排在前面了。

加盐

在RowKey前添加一些前缀,加盐的前缀种类越多,RowKey被打的越散。
需要注意的是分配的随机前缀的种类数量应该和想把数据分散到那些region的数量一致。这样,加盐后的RowKey才会根据随机生成的前缀分散到各个region中,避免热点现象。

哈希

哈希和加盐的适用场景类似,但前缀不可以是随机的,因为必须要让客户端能完整的重构RowKey,所以一般会拿原RowKey或其一部分计算Hash值,然后再对Hash值做运算作为前缀。

RowKey设计原则

HBase提出的设计原则主要有:长度原则,唯一原则,排序原则和散列原则。

长度原则

RowKey是一个二进制码流,可以是任意字符串,最大长度为64kb,实际应用中一般为10-100bytes,以byte[]形式保存,一般设计成定长,建议越短越好,不要超过十六个字节,原因是:

  • 在 HBase 的底层存储 HFile 中,RowKey 是 KeyValue 结构中的一个域。假设 RowKey 长度 100B,那么 1000 万条数据中,光 RowKey 就占用掉 100*1000w=10亿个字节 将近 1G 空间,这样会极大影响 HFile 的存储效率。
    在这里插入图片描述
  • HBase 中设计有 MemStore 和 BlockCache,分别对应列族/Store 级别的写入缓存,和 RegionServer 级别的读取缓存。如果 RowKey 字段过长,内存的有效利用率就会降低,系统不能缓存更多的数据,这样会降低检索效率。
    在这里插入图片描述
    此外,目前使用的基于64位的操作系统,内存是按照8B对齐的,所以设计RowKey时一般做成8B的整数倍,如16B或者24B,可以提高寻址效率。
    同样,列族、列名的命名在保证可读的情况下也应尽量短。value 永远和它的 key 一起传输的。当具体的值在系统间传输时,它的 RowKey,列名,时间戳也会一起传输(因此实际上列族命名几乎都用一个字母,比如‘c’或‘f’)。如果RowKey和列名和值相比较较大,Hfile中的索引最终占据了HBase分配的大量内存。

唯一原则

由于RowKey用来唯一标识一行记录,所以必须在设计上保证RowKey的唯一性。

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

排序原则

RowKey是按照字典顺序排序存储的,所以设计RowKey时,利用排序特性,将经常读取的数据存储到一起,将最近可能访问的数据放到一起。
一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为 RowKey 的一部分对这个问题十分有用,可以用 Long.Max_Value-timestamp追加到key的末尾。
例如 [key][reverse_timestamp] , [key]的最新值可以通过scan [key]获得[key]的第一条记录,因为 HBase 中 RowKey 是有序的,第一条记录是最后录入的数据。

散列原则

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

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

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

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

相关文章

同源策略和跨域请求的实现

一、什么是同源策略 如果两个 URL 的 protocol、port (en-US) (如果有指定的话) 和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是“元组”。(“元组”是指一组项目构成的整体,双重/…

C语言 文件操作 深度解析 #重点知识:文件操作函数的使用#

文章目录前言1. 为什么使用文件2. 什么是文件程序文件数据文件3. 文件的打开和关闭4. 文件的顺序读写fgetcfputcfgetsfputsfprintffscanf流的介绍fwritefread5. 文本文件和二进制文件6. 文件读取结束的判定被错误使用的feof7. 文件缓冲区写在最后前言 相信大家对文件都不陌生&a…

4、数据类型

目录 1. 基本类型 (1)数值类型 (2)字符类型 (3)布尔类型 2. 构造类型 3. 空类型 本文主要介绍基本数据类型。 1. 基本类型 基本类型也就是C语言中的基础类型,其中包括整型、字符型、浮点…

我的 git 实战记录

我的 git 实战记录 1. 将本次提交追加到上一次提交 1.1. 情景描述 有些时候,我提交东西太勤快了,导致有部分内容没有提交上去。分为两种情况: 已经 push 远程仓库还没有 push 到远程仓库 1.2. 已经 push到远程仓库 先 git add 提交修改…

Windows免费MQTT服务器搭建及使用

1、EMQ X(简称 EMQ) 简介 EMQ的源代码完全开源,支持百万级并发连接,支持完整的MQTT协议,可以简单方便地部署在Linux、Mac OS X或Windows等平台上,支持MySQL、Redis等扩展插件,总的来说,EMQ满足…

Java设计模式-访问者模式Visitor

介绍 访问者模式(Visitor Pattern),封装一些作用于某种数据结构的各元素的操作,它可以在不改变数据结构的前 提下定义作用于这些元素的新的操作。主要将数据结构与数据操作分离,解决 数据结构和操作耦合性问题访问者模…

day15|513.找树左下角的值、112. 路径总和、113.路径总和ii、106.从中序与后序遍历序列构造二叉树、105.从前序与中序遍历序列构造二叉树

513.找树左下角的值 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 示例 2: 输入: [1,2,3,4,null,5,6,null,null,7] 输出: 7 问题分析: 递归法&#x…

【基础篇】3 # 数组:为什么很多编程语言中数组都从0开始编号?

说明 【数据结构与算法之美】专栏学习笔记 什么是数组? 数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。 线性表和非线性表 线性表(Linear List)&#xff1…

第07章 面向对象编程(中级部分OOP)

文章目录IDE(集成开发环境)IDEA介绍idea运行包包的作用包基本语法包的本质分析(原理)包的命名命名规则命名规范常用的包如何引入包注意事项和使用细节访问修饰符【modifier】基本介绍使用的注意事项封装【encapsulation】介绍封装的好处和理解封装的实现步骤封装练习继承【exte…

【阶段四】Python深度学习02篇:深度学习基础知识:神经网络可调超参数:优化器

本篇的思维导图: 神经网络可调超参数:优化器 优化器相当于是用来调解神经网络模型的‘手柄’。 代码 # 编译神经网络,

【C语言】小王带您轻松实现动态内存管理(简单易懂)

在上文通讯录制作中,动态通讯录的使用中就用到了动态内存管理,如果有同学想看一看是如何运用的内存管理函数的,请参考这篇文章,接下来我们一起学习动态内存管理的相关知识。【C语言】使用C语言实现静态、动态的通讯录(…

浅显易懂的三次握手与四次挥手

目录 一、三次握手 什么是三次握手? 三次握手图解: 过程解析: (1)第一次握手: (2)第二次握手: (3)第三次握手: 二、四次挥手 …

已解决Python读取20GB超大文件内存溢出报错MemoryError

已解决Python读取20GB超大文件内存溢出报错MemoryError 文章目录报错问题报错翻译报错原因解决方法1解决方法2(推荐使用)帮忙解决报错问题 日常数据分析工作中,难免碰到数据量特别大的情况,动不动就2、3千万行,如果…

操作系统进程调度算法

进程调度 高级调度(作业调度):按一定的原则从外存的作业后备队列中挑选一个作业调入内存,并创建进程。每个作业只调入一次,调出一次。作业调入时会建立PCB,调出时会撤销PCB。 中级调度(内存调度…

【历史上的今天】1 月 16 日:互联网工程任务组(IETF)成立;AMD 收购 NexGen;eBay 的第一位员工出生

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2023 年 1 月 16 日,在 26 年前的今天,国家电力公司组建成立。电力是运作着我们生活的基本,国家电力公司成立于 1997 年 1 月 16 日…

《深度学习入门基于python的理论与实现》chap2感知机 笔记

《深度学习入门:基于python的理论与实现》chap2 感知机 笔记 3个月前正式开始入坑AI的时候就是看的这本书,当时比较粗略地看到了第六章,没有记笔记,现在来重温一下 文章目录《深度学习入门:基于python的理论与实现》chap2 感知机 笔记2.1 什么…

【阶段四】Python深度学习05篇:深度学习项目实战:卷积神经网络的定义、卷积网络的结构与卷积层的原理

本篇的思维导图: 卷积神经网络的定义 卷积神经网络,简称为卷积网络,与普通神经网络的区别是它的卷积层内的神经元只覆盖输入特征局部范围的单元,具有稀疏连接(sparse connectivity)和权重共享(weight shared)的特点,而且其中的过滤器可以做到对图像关键特征的…

基于Power BI的品牌销售金额帕累托分析

一、原理 帕累托于1906年提出了著名的关于意大利社会财富分配的研究结论:20%的人口掌握了80%的社会财富。这个结论对大多数国家的社会财富分配情况都成立。因此,该法则又被称为80/20法则。 二、数据源 已知某终端表1《商品信息》…

GO 语言 Web 开发实战一

xdm,咱今天分享一个 golang web 实战的 demo go 的 http 包,以前都有或多或多的提到一些,也有一些笔记在我们的历史文章中,今天来一个简单的实战 HTTP 编程 Get 先来一个 小例子,简单的写一个 Get 请求 拿句柄 设置…

VMware Workstation 17 Pro的下载和安装

目录 一、下载 二、安装 三、检查网络连接 方式一(简便版) 方式二(麻烦版) 一、下载 下载地址: Windows 虚拟机 | Workstation Pro | VMware | CN 1、进入该网址后,往下翻,有两个选项&…