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、已有数据可以快速根据规则得到 对应的数据