提出需求
电信公司的通话详单,为了便于查询,将 用户的每一天的通话记录保存到一个 region 中
分析
见 hbase2.1.x rowkey设计原则 中的 热点问题
验证
建表
建表时指定 region 数量,并指定拆分算法
create 'call_log','info',{NUMREGIONS => 3, SPLITALGO => 'HexStringSplit'}
web查看
http://hadoop1:16010/table.jsp?name=call_log
- 第一个region的rowkey范围:
- 55555555 - 第二个region的rowkey范围:
55555555 - aaaaaaaa - 第三个region的rowkey范围:
aaaaaaaa -
注意:长度是 8 个字符
代码
package top.malaoshi;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.MD5Hash;
import java.io.IOException;
public class TestRowKey {
private Connection conn;
/**
* 创建hbase连接
* @throws IOException
*/
public void conn() throws IOException {
//创建hbase配置对象
Configuration conf= HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "hadoop1,hadoop2,hadoop3");// zookeeper地址
conf.set("hbase.zookeeper.property.clientPort", "2181");// zookeeper端口
//通过配置对象创建连接
conn = ConnectionFactory.createConnection(conf);
}
public void testRowkey() throws IOException {
//获取table对象
Table table = conn.getTable(TableName.valueOf("call_log"));
//主叫号码
String tel="13900000001";
for(int d=20211001;d<20211004;d++) {// 日期:20211001-20211004
for (long i = 13800000001l; i < 13800000080l; i++) {//拨打的电话号
String rowkey = tel +"_"+i + "_" +d+"_132530";//132530表示时间,这里为了演示,时间相同
System.out.println(rowkey);
//创建put对象
Put put = new Put(Bytes.toBytes(rowkey));
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("李雷"));
//执行put命令
table.put(put);
}
}
//关闭table
table.close();
}
public void close() throws IOException {
conn.close();
}
public static void main(String[] args) {
TestRowKey trk=new TestRowKey();
try {
trk.conn();
trk.testRowkey();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
trk.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
web页面查看
比较均匀分布在3台 region server
解决
使用 hbase2.1.x rowkey设计原则 中的 哈希(散列值)
rowkey 设计
rowkey 设计如下:
拼装成字符串:
主叫号码_被叫号码_年月日_时分秒将
主叫号码_被叫号码_年月日_时分秒做 MD5 散列计算,并取出前 8 位。(由上面可知,rowkey的长度是8个字符)rowkey为:
MD5前8位_主叫号码_被叫号码_年月日_时分秒
java代码
package top.malaoshi;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.MD5Hash;
import java.io.IOException;
public class TestRowKey {
private Connection conn;
/**
* 创建hbase连接
* @throws IOException
*/
public void conn() throws IOException {
//创建hbase配置对象
Configuration conf= HBaseConfiguration.create();
//通过配置对象创建连接
conn = ConnectionFactory.createConnection(conf);
}
public void testRowkey2() throws IOException {
//获取table对象
Table table = conn.getTable(TableName.valueOf("call_log"));
//主叫号码
String tel="13900000001";
for(int d=20211001;d<20211004;d++) {// 日期:20211001-20211004
for (long i = 13800000001l; i < 13800000080l; i++) {//拨打的电话号
String rowkey = tel +"_"+i + "_" +d+"_132530";//132530表示时间,这里为了演示,时间相同
//根据rowkey生成md5
String md5 = MD5Hash.getMD5AsHex(rowkey.getBytes());
//md5值比较长,取出前8位
String submd5 = md5.substring(0, 8);
String newRowkey = submd5 + "_" + rowkey;
System.out.println(newRowkey);
//创建put对象
Put put = new Put(Bytes.toBytes(newRowkey));
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("李雷"));
//执行put命令
table.put(put);
}
}
//关闭table
table.close();
}
public void close() throws IOException {
conn.close();
}
public static void main(String[] args) {
TestRowKey trk=new TestRowKey();
try {
trk.conn();
trk.testRowkey();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
trk.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
web页面查看
比较均匀分布在3台 region server


