一、Hbase表的设计
1.1、 Hbase 表设计原理(ps:这里不知道可不可以这样说):
https://blog.csdn.net/yydu_666/article/details/80620980
1.2、列簇设计
官方建议不超过2到3个列簇,columnFamily flush临近的column family也会可能被触发关联flush
产生大量IO。因此尽量将关联很强的信息都放在同一个列簇下面,比如:用户的信息
https://www.cnblogs.com/frankdeng/p/9310356.html
二、RowKey设计
2.1、 rowkey 设计原则
2.2.1、长度原则
最好在16位,
1)持久化HFile按照keyValue形式存储, 如果rowkey是100个字节,
则几万的数据将占据近百数M的存储空间,影响HFile的存储效率
2)MemStore 将缓存数据存在内存中,rowkey太长,系统无法存
储更多数据,影响检索效率
3)系统64位的
2.2.2、散列性
若rowkey以时间递增,则高位为随机的散列字段,低位为时间字段,
避免集中访问产生热点问题;
2.2.3、唯一性
rowkey要唯一;
例子1:设计一个存储用户消费记录的rowkey:
根据设计原则比如 rowkey 由 随机数 + 时间戳 + 字符串 组成,
那么这个 rowkey 就由 用户id(随机三位) + 时间戳 + 消费类型 组成
那么对应的预分区可以分为十个,分别为0,1,2,3..到9的开头的数字的分区
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import com.jm.common.HBaseClient;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @Description: $description$
* @Author: Jomin
* @Date: $time$ $date$
*/
public class CreateBySplitKey {
private static HBaseClient instance = null;
private Connection connection;
public static void main(String[] args) throws IOException {
Configuration configuration = HBaseConfiguration.create();
configuration.set("hbase.zookeeper.quorum", "192.168.164.128"); //hbase 服务地址
configuration.set("hbase.zookeeper.property.clientPort", "2181"); //端口号
Admin admin = ConnectionFactory.createConnection(configuration).getAdmin();
//表名
String name = "test_table_split_region";
TableName tableName = TableName.valueOf(name);
// 创建表名字
HTableDescriptor tableDescriptor = new HTableDescriptor(name);
// 列簇
HColumnDescriptor columnDescriptor = new HColumnDescriptor("info");
tableDescriptor.addFamily(columnDescriptor);
//分区
byte[][] splitKeys = genSplitKeys(10);
admin.createTable(tableDescriptor, splitKeys);
System.out.println("create table sucsssss");
}
static private byte[][] genSplitKeys(int regionCount) {
int splitkeyCount = regionCount - 1;
byte[][] bs = new byte[splitkeyCount][];
List<byte[]> bsList = new ArrayList<byte[]>();
for (int i = 1; i < splitkeyCount; i++) {
String splitkey = String.valueOf(i);
System.out.println(splitkey);
bsList.add(Bytes.toBytes(splitkey));
}
Collections.sort(bsList, new Bytes.ByteArrayComparator());
bsList.toArray(bs);
return bs;
}
}
创建后,显示

补充例子:https://www.jianshu.com/p/59d198e501c8
http://bigdata-star.com/archives/1256
2.2.4、避免数据热点问题
1、rowkey 加盐;
2、rowkey 哈希, 将rowkey 哈希之后,用确定的哈希,重构 rowkey 来读取数据(我用这个);
3、rowkey 反转;
( ps : 哈希一致性参考链接
的方法二: https://blog.csdn.net/qq_31289187/article/details/80869906 )
三、预建分区
每个region 维护一个startRowKey和EndRowKey
四、冷热数据处理
https://www.cnblogs.com/small-k/p/8847926.html
https://developer.aliyun.com/article/738128?spm=a2c6h.12873581.0.0.7229187aX9Y9iZ
五、降IO