文章目录
- HBase优化
- 1、预分区
- 1.1 手动设定预分区
- 1.2 生成十六进制序列预分区
- 1.3 按照文件设置规则预分区
- 1.4 使用JavaAPI创建预分区(不常用)
- 2、RowKey的设计
- 案例
- 优化:设计一个同时满足以上两个需求的RowKey
- 预分区优化
- 提前将分区号和月份进行对应优化需求2
- 3、内存优化
- 4、hbase-site.xml基础优化
HBase优化
1、预分区
每一个region维护着startRowKey与endRowKey,如果加入的数据符合某个region维护的rowKey范围,则该数据交给这个region维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。
1.1 手动设定预分区
create 'staff1','info', SPLITS => ['1000','2000','3000','4000']
1.2 生成十六进制序列预分区
create 'staff2','info',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
1.3 按照文件设置规则预分区
splits.txt
aaa
ccc
bbb
ddd
create 'staff3', 'info',SPLITS_FILE => 'splits.txt'
1.4 使用JavaAPI创建预分区(不常用)
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import java.io.IOException;
public class HBaseConnect {
public static void main(String[] args) throws IOException {
// 1.获取配置类
Configuration conf = HBaseConfiguration.create();
// 2.给配置类添加配置
conf.set("hbase.zookeeper.quorum","hadoop102,hadoop103,hadoop104");
// 3.获取连接
Connection connection = ConnectionFactory.createConnection(conf);
// 4.获取admin
Admin admin = connection.getAdmin();
// 5.获取descriptor的builder
TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(TableName.valueOf("bigdata", "staff4"));
// 6. 添加列族
builder.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info")).build());
// 7.创建对应的切分
byte[][] splits = new byte[3][];
splits[0] = Bytes.toBytes("aaa");
splits[1] = Bytes.toBytes("bbb");
splits[2] = Bytes.toBytes("ccc");
// 8.创建表
admin.createTable(builder.build(),splits);
// 9.关闭资源
admin.close();
connection.close();
}
}
2、RowKey的设计
一条数据的唯一标识就是rowkey,那么这条数据存储于哪个分区,取决于rowkey处于哪个一个预分区的区间内。
目的:让数据均匀的分布于所有的region中,在一定程度上防止数据倾斜。
方法:
- 生成随机数、hash、散列值
- 字符串反转,一定程度上散列逐步put进来的数据。
20170524000001转成10000042507102
20170524000002转成20000042507102
- 字符串拼接
案例
需求: 数据如下:
user | date | pay |
zhangsan | 2022-01-05 09:08:00 | 100 |
zhangsan | 2021-12-30 09:08:00 | 100 |
zhangsanfeng | 2022-01-04 09:08:00 | 200 |
lisi | 2021-12-31 09:08:00 | 150 |
- 某一个用户(比如zhangsan)在2021年12月一共消费的总钱数
RowKey:user_date
startRowKey:zhangsan_2021-12
endRowKey:zhangsan_2021-12. - 在2021年12月份所有人一共消费的总钱数
RowKey:date_user
startRowKey:2021-12
endRowKey:2021-12.
优化:设计一个同时满足以上两个需求的RowKey
RowKey:date(yyyy-MM)_user_date(-dd HH:mm:SS)
需求1:
startRowKey:2021-12_zhangsan
endRowKey:2021-12_zhangsan.
需求2:
startRowKey:2021-12
endRowKey:2021-12.
预分区优化
可以将一年的所有数据分为120个region
`000.
`001.
…
RowKey设计:(hash[user-MM]%120)_yyyy-MM_user_-dd HH:mm:SS
由于部分用户消费记录特别多,hash[user]%120会导致数据倾斜hash[user-MM]%120是为了将相同用户再次打散。
需求1:
startRowKey:(hash[zhangsan-12]%120)_2021-12_zhangsan
endRowKey:(hash[zhangsan-12]%120)_2021-12_zhangsan.
需求2:
startRow -> 000_2021-12
endRow -> 000_2021-12.
…
startRow -> 119_2021-12
endRow -> 119_2021-12.
扫描120次
提前将分区号和月份进行对应优化需求2
000、001、…、119,其中000-009为1月份,010-019为2月份,…,110-119为12月
RowKey设计:(hash[user]%10+月份对应的分区)_yyyy-MM_user_-dd HH:mm:SS
startRow -> 110_2021-12
endRow -> 110_2021-12.
…
startRow -> 119_2021-12
endRow -> 119_2021-12.
扫描10次
3、内存优化
HBase操作过程中需要大量的内存开销,毕竟Table是可以缓存在内存中的,但是不建议分配非常大的堆内存,因为GC过程持续太久会导致RegionServer处于长期不可用状态,一般16~36G内存就可以了,如果因为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死。
4、hbase-site.xml基础优化
- Zookeeper会话超时时间
zookeeper.session.timeout
:默认值为90000毫秒(90s)。当某个RegionServer挂掉,90s之后Master才能察觉到。可适当减小此值,以加快Master响应,可调整至60000毫秒。 - RPC监听数量
hbase.regionserver.handler.count
:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。 - 手动控制Major Compaction
hbase.hregion.majorcompaction
:默认值:604800000秒(7天), Major Compaction的周期,若关闭自动Major Compaction,可将其设为0 - 优化HStore文件大小
hbase.hregion.max.filesize
:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile。 - 优化HBase客户端缓存
hbase.client.write.buffer
:默认值2097152bytes(2M)用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的。 - 指定scan.next扫描HBase所获取的行数
hbase.client.scanner.caching
:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。 - BlockCache占用RegionServer堆内存的比例
hfile.block.cache.size
:默认0.4,读请求比较多的情况下,可适当调大 - MemStore占用RegionServer堆内存的比例
hbase.regionserver.global.memstore.size
:默认0.4,写请求较多的情况下,可适当调大