hbase的rowkey设计

hbase的rowkey设计

背景

将es日志转存到hbase上,并且方便团队人员查询。

hbase的基础概念

hbase版本

    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>1.3.0</version>
    </dependency>

hbase常用概念

行键(row key):
    HBase中的行有一个rowkey(行键)和 一个或者多个列组成, 列的值与rowkey、列相关联
    行在存储是按行键的字典序排序
    行键的设计非常重要, 尽量让相关的行存储在一起
列(Column):
    HBase中的列有列族(column family) 和列限定符(列名)(Column Qualifier)组成
    表示如下 : 列族名:列限定符 例如: C1:USER_ID C1:SEX
列族(Column Family):
    出于性能原因, 列族将一组列及其值组织在一起
    每个列族都有一组存储属性: 例如 是否应该换成在内存中, 数据如何被压缩等
    表中的每一行都有相同的列族, 但在列族中不存储任何内容
    所有的列族的数据全部都存储在一块(文件系统HDFS)
    Hbase官方建议所有的列族保持一样的列, 并且将同一类的列放在一个列族中
列标识符(Column Qualifier)
    列族中包含一个个的列限定符, 这样可以为存储的数据提供索引
    列族在创建表的时候是固定的, 但列限定符是不做限制的
    不同的列可能会存在不同的列标识符
单元格(Cell): 单元格是行、列族和列限定符的组合,包含一个值和一个时间戳, 数据以二进制存储
版本号(verson num): 
    每条数据都会有版本号的概念
    每条数据都可以有多个版本号, 默认值为系统时间戳, 类型为Long
时间戳(timeStamp): 
    每个数据都会有时间戳的概念
    在向Hbase插入更新数据的时候, HBase默认会将当前操作的时间记录下来, 当然也可以人为指定时间
    不同版本的数据按照时间倒序排序, 即最新的数据排在最前面

hbase需要设计主键的原因

HBase仅能通过主键(row key)和主键的range来检索数据,仅支持单行事务

hbase常见的主键设计方式和建议

1、唯一性: 主键必须是唯一的,不能重复。每行数据在 HBase 表中都应该有一个唯一的主键。

2、散列性: 主键应该具有良好的散列性,避免出现 “热点” 的问题。热点问题是指某些主键值出现频繁,导致部分 Region Server 负载过重,而其他 Region Server 负载较轻。

3、长度: 主键的长度应该尽量短,这有助于减少存储空间和提高检索效率。

4、可读性: 主键可以是可读的,方便人类识别和查询。但是,为了满足唯一性和散列性的要求,可能需要对可读的主键进行哈希或其他方式的转换。

5、时间戳: 在某些场景下,可以将时间戳作为主键的一部分。这样可以方便按时间范围检索数据,并且可以保证数据的按时间排序。

6、字典序: 在某些场景下,可以将主键设计成字典序,这样可以在检索时获取按字典序排序的结果。

7、扫描性能: 主键的设计还应该考虑到数据的访问模式。如果经常需要扫描一定范围的数据,可以将相关的数据行放在相邻的区域中,以提高扫描性能。

8、固定长度: 主键最好是固定长度的。变长主键可能会导致在存储时需要额外的字节开销

实际采用的方式

直接上代码

// row设计
            String row = "";
            String end = String.valueOf(Math.abs(data.hashCode()));
            if(StringUtils.isNotBlank(shipId)&&!"null".equals(shipId)){
                String begin = shipId.substring(shipId.length()-1);
                if("0".equals(begin)){
                    begin ="5" ;
                }
                row = begin + shipId+ monthDay+ end;
            }else{
                String begin = String.valueOf((int)(Math.random() * (9 - 1 + 1) + 1));
                String monthDayHour = DateFormatUtils.format(new Date(Long.parseLong(timestamp)),"MMddHHmmss");
                row = begin + Math.abs(className.hashCode())+ monthDayHour + end;
            }

翻译翻译
1、业务id最后一位
2、业务id
3、es日志的抓换 “MMddHHmmss”
4、es data数据的hashcode值

好处

1、可以查单个key
2、方便模糊某个时间段的所有业务id的数据
3、已有数据可以快速根据规则得到 对应的数据

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值