文章目录

  • 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']

hbase 中的切分点 hbase 分区策略_hbase

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

  1. 某一个用户(比如zhangsan)在2021年12月一共消费的总钱数
    RowKey:user_date
    startRowKey:zhangsan_2021-12
    endRowKey:zhangsan_2021-12.
  2. 在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基础优化

  1. Zookeeper会话超时时间
    zookeeper.session.timeout:默认值为90000毫秒(90s)。当某个RegionServer挂掉,90s之后Master才能察觉到。可适当减小此值,以加快Master响应,可调整至60000毫秒。
  2. RPC监听数量
    hbase.regionserver.handler.count:默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。
  3. 手动控制Major Compaction
    hbase.hregion.majorcompaction:默认值:604800000秒(7天), Major Compaction的周期,若关闭自动Major Compaction,可将其设为0
  4. 优化HStore文件大小
    hbase.hregion.max.filesize:默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile。
  5. 优化HBase客户端缓存
    hbase.client.write.buffer:默认值2097152bytes(2M)用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的。
  6. 指定scan.next扫描HBase所获取的行数
    hbase.client.scanner.caching:用于指定scan.next方法获取的默认行数,值越大,消耗内存越大。
  7. BlockCache占用RegionServer堆内存的比例
    hfile.block.cache.size:默认0.4,读请求比较多的情况下,可适当调大
  8. MemStore占用RegionServer堆内存的比例
    hbase.regionserver.global.memstore.size:默认0.4,写请求较多的情况下,可适当调大