HBase中的rowkey是按字典顺序排序的,通过rowkey查询可以对千万级的数据实现毫秒级响应。然而,如果rowkey设计不合理的话经常会出现一个很普遍的问题----热点。当大量client的请求(读或者写)只指向集群的一个节点,或者很少量的几个节点时,也就代表产生了热点问题。

避免产生热点的方式也就是尽可能的将rowkey均匀分散到所有的region上,下面介绍了几种rowkey设计常用的方式:

第一:加盐(salting)

加盐是指在rowkey的前缀添加随机数据,使rowkey尽可能的分布到其他regionserver上

假设遇到下面的rowkey,表的预分区设置为每个字母对应一个region。前缀“a”是一个region,前缀“b”是另一个region等等。那么在这个表中,所有以“f”开头的rowkey都将位于同一个region。比如:

  foo0001
  foo0002
  foo0003
  foo0004

那么,如果你想把它们分散到四个不同的region,那么就可以使用四种不同的前缀: a、b、c和d来做加盐。在加盐之后,rowkey也就变成了下面这样。

  a-foo0003
  b-foo0001
  c-foo0004
  d-foo0002

(ps:由于现在可以向四个region写数据,理论上,性能比之前向同一个region写吞吐量提升四倍)

并且,如果后续有新的数据写入,rowkey也就会随机的添加前缀,写到不同的region中

缺点:加盐虽然可以很大程度的避免热点问题,提升写入效率,但是由于rowkey被随机的添加了salt值,在读取时候要付出额外的开销。具体怎么读取加盐后的数据,后面再做介绍

第二:哈希(hashing)

哈希的算法有多种,在rowkey设计中用的比较多的大概就是MD5了吧,但是需要注意的是MD5散列还是有碰撞的可能性的,概率很小,但是不是零。

所以一般使用MD5做rowkey散列时候,都会附加一个唯一字段,比如账号字段account,对account做MD5,截取6位左右的md5返回值然后再拼接account字段,也就是:

  substr(md5(account))+account

此外,通过md5散列之后的rowkey,在创建表预分区时候,可以使用hbase自带的HexStringSplit方法

第三:反转(Reversing)

如果定义的rowkey字段,前部分数据变化幅度很小,变化很慢,尾部数据变化频率较高,便可以考虑反转字段,尤其对类似时间戳的数据

不管以哪种方式设计rowkey,在查询时候也要做对应的数据处理,比如做hash的,查询时候也需要先把数据hash之后,然后查询rowkey;通过反转方式设计的rowkey同理。

第四:最小化rowkey和列簇长度

rowkey可以是任意的字符串,最大长度64KB,但是建议在设计rowkey时候,尽可能的短,原因:

  1.hbase数据存储是以key-value的形式存储的,如果rowkey比较长,比如100字节,那么1000w行数据,光rowkey存储就需要100*1000w=10亿个字节,将近1G的数据。

  2.memstore的会缓存数据到内存,如果rowkey比较长,同样会占用更多的空间

  3.建议rowkey设计在8字节的整数倍,控制在16个字节,因为目前的操作系统大多都是64位的,整数倍更好了利用了操作系统的特性。

列簇(ColumnFamily)同理,尽可能的短,最好是一个字符,比如 f 或者 d

第五:Byte Patterns

我们知道,long类型是8个字节,并且你可以通过long类型存储一个最大为18,446,744,073,709,551,615的无符号数字,仅仅用8个字节,但是如果以string类型的形式存储这样的数字,那么几乎需要3倍空间的大小(假定每个字符占一个字节)

举个例子验证一下:

// long
//
long l = 1234567890L;
byte[] lb = Bytes.toBytes(l);
System.out.println("long bytes length: " + lb.length);   // returns 8

String s = String.valueOf(l);
byte[] sb = Bytes.toBytes(s);
System.out.println("long as string length: " + sb.length);    // returns 10

// hash
//
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(Bytes.toBytes(s));
System.out.println("md5 digest bytes length: " + digest.length);    // returns 16

String sDigest = new String(digest);
byte[] sbDigest = Bytes.toBytes(sDigest);
System.out.println("md5 digest as string length: " + sbDigest.length);    // returns 26

但是,也有一个缺点,就是如果使用这种二进制表示的类型时候,在hbase shell界面查数据的时候,可读性比较差,比如:

hbase(main)::> get 'table1', 'rowkey1'
COLUMN                                        CELL
 f:q                                          timestamp=, value=\x00\x00\x00\x00\x00\x00\x00\x01
 row(s) in 0.0310 seconds

hbase rowkey 设计的更多相关文章

  1. HBase Rowkey 设计指南

    为什么Rowkey这么重要 RowKey 到底是什么 我们常说看一张 HBase 表设计的好不好,就看它的 RowKey 设计的好不好.可见 RowKey 在 HBase 中的地位.那么 RowKey ...

  2. Hbase rowkey设计+布隆过滤器+STORE FILE & HFILE结构

    Rowkey设计 Rowkey设计原则 Rowkey设计应遵循以下原则: 1.Rowkey的唯一原则 必须在设计上保证其唯一性.由于在HBase中数据存储是Key-Value形式,若HBase中同一表 ...

  3. Hbase rowkey设计一

    转自 http://blog.csdn.net/lifuxiangcaohui/article/details/40621067 hbase所谓的三维有序存储的三维是指:rowkey(行主键),col ...

  4. Hbase Rowkey设计

    转自:http://www.bcmeng.com/hbase-rowkey/ 建立Schema Hbase 模式建立或更新可以通过 Hbase shell 工具或者使用Hbase Java API 中 ...

  5. HBase总结(十八)Hbase rowkey设计一

    hbase所谓的三维有序存储的三维是指:rowkey(行主键),column key(columnFamily+qualifier),timestamp(时间戳)三部分组成的三维有序存储. 1.row ...

  6. Hbase Rowkey设计原则

    Hbase是三维有序存储的,通过rowkey(行键),column key(column family和qualifier)和TimeStamp(时间戳)这三个维度可以对HBase中的数据进行快速定位 ...

  7. hbase rowkey设计的注意事项

    充分利用有序性 1.1 如果要scan操作,且不是很频繁,可以利用rowkey的有序性将需要一起扫描的数据放到一起.例如直接用时间戳.这样就可以按时间scan了.这个只要是简单的全表扫描都行. 1.2 ...

  8. HBase的rowkey设计(含实例)

    转自:http://www.aboutyun.com/thread-7119-1-1.html 对于任何系统的数据设计,我们都想提高性能,达到资源最大化利用,那么对于hbase我们产生如下问题: 1. ...

  9. HBase的RowKey设计原则

    HBase是三维有序存储的,通过rowkey(行键),column key(column family和qualifier)和TimeStamp(时间戳)这个三个维度可以对HBase中的数据进行快速定 ...

随机推荐

  1. Python多进程与多线程编程及GIL详解

    介绍如何使用python的multiprocess和threading模块进行多线程和多进程编程. Python的多进程编程与multiprocess模块 python的多进程编程主要依靠multip ...

  2. Excel催化剂开源第7波-VSTO开发中Ribbon动态加载菜单

    在VS开发环境中,特别是VSTO的开发,微软已经现成地给开发者准备了设计器模式的功能区开发,相对传统的VBA.ExcelDna和其他方式的COM加载项开发来说,不需要手写xml功能区,直接类似拖拉窗体 ...

  3. AndroidStudio使用genymotion模拟器

    安装Genymotion之前首先要安装好virtualbox这个软件 virtual官方网站:https://www.virtualbox.org/ genymotion的官方网站: https:// ...

  4. Oracle RAC运维所遇问题记录一

    Oracle11gR2,版本11.2.0.4集群测试环境运行正常 主机名:rac1,rac2 hosts文件: # Public172.17.188.12 rac1172.17.188.13 rac2 ...

  5. 安科 OJ 1190 连接电脑 (并查集)

    时间限制:1 s 空间限制:128 M 传送门:https://oj.ahstu.cc/JudgeOnline/problem.php?id=1190 题目描述 机房里有若干台电脑,其中有一些电脑已经 ...

  6. Git学习笔记 (二)

    Git学习笔记(二) 突然发现,学习新知识新技能,都得经常温故使用,这样才能日益精进.最近学习的Git是因为加入了课题组,在学习做一些后台,由于后台开发会牵扯到多人开发,所以学会Git这一代码管理工具 ...

  7. MySql(Linux)

    百度云:链接:http://pan.baidu.com/s/1jHQtPau    密码:elr8 官方下载网址:http://dev.mysql.com/downloads/mysql/

  8. HttpWebRequest的使用之Get和Post的差别(C#)

    这两天做的是通过一个HttpWebRequest将采集地址发送到服务端,服务端会返回一个JSON格式的字符串,然后我这边再对这个JSON进行反序列化,得到我想要的数据.在这篇文章里我简单介绍一下Htt ...

  9. SQLyog12最新版破解

    1.SQLyog-12.2.4-0.x64Trial.exe,直接去官网下载. 2.修改注册表项   开始-运行-regedit ,进入注册表  HKEY_CURRENT_USER\Software\ ...

  10. 针对Nginx日志中出现的漏洞扫描与爬虫的三种措施

    0x001 使用fail2ban工具结合防火墙(iptables | firewalld),将大量404请求的IP地址封了.(详见fail2ban使用说明:https://www.cnblogs.co ...