hbase优化

hbase 创建表结构示例·

create 'car_gb_binary',{NAME=>'carnet',COMPRESSION=>'snappy',BLOOMFILTER=>'ROW'},{NUMREGIONS=>100,SPLITALGO=>'HexStringSplit'}

解释:
BLOOMFILTER=布隆过滤器,默认为ROW,有三个选项NONE、ROW、ROWCOL
NUMREGIONS=>10:默认region数
SPLITALGO=>分裂规则,十六进制
VERSIONS=>版本号--如果没有必要,设置为1
COMPRESSION=>压缩方式,默认为NONE,有snappy、zip等
DFS_REPLICATION=>1 hdfs中备份数量为1--经测试,该配置有效。如果是在表已存在情况下,修改了表属性。只对后续的写入、split、merge等操作有效,之前的数据如果不操作的话,还是按照原来的备份数量
CONFIGURATION =>configuration中设置split策略,禁用自动split


create 'carnet:gb_binary',{NAME=>'a',COMPRESSION=>'snappy',BLOOMFILTER=>'ROW', VERSIONS=>1, DFS_REPLICATION => '1'},{NUMREGIONS=>10,SPLITALGO=>'HexStringSplit',CONFIGURATION => {'hbase.regionserver.region.split.policy'=>'org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy'}}


#alter 为修改表结构指令
alter 'carnet:gb_binary',{NAME=>'a',COMPRESSION=>'snappy',BLOOMFILTER=>'ROW',DFS_REPLICATION => '3'}

hbase性能调优

主要是针对于服务端的配置优化

地方大幅度发

默认值建议值说明调优 
zookeeper.session.timeout3分钟1分钟RegionServer与Zookeeper间的连接超时时间。当超时时间到后,ReigonServer会被Zookeeper从RS集群清单中移除,HMaster收到移除通知后,会对这台server负责的regions重新balance,让其他存活的RegionServer接管设置成1分钟,减少hmaster感知时间 
hbase.regionserver.handler.count30100rpc handler,handler太少无法处理高并发增加这个值,提高rpc并发数 
hbase.hregion.max.filesize10G30Gregion下hfile大小经验值为20~30G,也不是越大越好,越大索引层次越深,对查询稍有影响,越小容易造成split,region个数太多 
hbase.hregion.memstore.flush.size128M128M/256Mmemstore达到多大时flush到磁盘regionserver 分配16G内存时,分配128M,分配32G时,分配256M, 机器内存大时建议将memstore调整到256M , 
hbase.regionserver.global.memstore.upperLimit0.40.45单台regionserver上所有region的memstore内存达到regionserver内存乘以这个值后,会flush memstore到磁盘,生成hfile这个值根据实际情况调整,如果写多读少,可以调大这个值,注意hbase.regionserver.global.memstore.upperLimit + hfile.block.cache.size不能超过0.8,否则会有OOM风险 
hfile.block.cache.size0.40.35blockcache占用的百分比这个值根据实际情况调整,如果读多写少,可以调大这个值,注意hbase.regionserver.global.memstore.upperLimit + hfile.block.cache.size不能超过0.8,否则会有OOM风险 
hbase.hstore.blockingStoreFiles101000当一个region下hfile超过10个时,block住所有写请求直到compaction完成设置一个较大值,减少block住写请求 
hbase.hregion.memstore.mslab.enabledTRUETRUE减少内存碎片造成的full gc  
hbase.hregion.majorcompaction6048000000major_compact触发周期禁用majorcompaction,每天晚上定时通过contab执行compaction动作。  脚本,实施部门有。 
hbase.regionserver.regionSplitLimit21474836472147483647超过这个值后region将会停止自动split分裂时会造成对性能上的抖动,需要消耗cpu和io,对性能要求很高可以关闭自动分裂,把值设为0,在集群负载不大的时候下手动或定时脚本去split。对性能要求不高自动split就可以 
hbase.client.scanner.caching10001000每次scan rpc返回记录条数查询返回的数据太大会造成客户端长时间等待,造成超时,每次rpc小批量返回即可 
hbase.regionserver.thread.compaction.large110large compaction线程个数major compact时需要把region下所有hfile合并成一个大hfile,需要把线程数设置大一些 
hbase.regionserver.thread.compaction.small15small compaction线程个数minor compact把几个小hfile合并成一个hfile,1个线程太少 
GC优化4G机器内存充足,建议给32G“-Xms16g -Xmx16g -Xmn1g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=15 -XX:CMSInitiatingOccupancyFraction=70 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/data1/hbase-logs/gc-$(hostname)-hbase.log“-Xms16g -Xmx16g -Xmn1g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=15 -XX:CMSInitiatingOccupancyFraction=70 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/data1/hbase-logs/gc-$(hostname)-hbase.log配置方位:  在cdh    hbase   配置界面==> 高级 ==》HBase RegionServer 的 Java 配置选项
建表   1. table要预分区,分区个数=表总大小(估算)/HFile大小
2. 设置压缩格式,推荐使用snappy压缩
3.开启row boolean filter
4.列族名、字段名尽量要短,列族比如用f
 

hbase split触发规则

1、admin手动分裂

2、memory中数据flush至hfile之前,会去校验是否需要split。如果当前region中hfile的数量超过了hbase.hstore.blockingStoreFiles 设置的数量。如果超过,且没有等待超时,就会触发split。flush之后,还会再去校验一次,是否需要split

3、单个region存储大小超过hbase.hregion.max.filesize设定的文件大小,不再触发split

hbase merge触发规则

merge的触发由后台周期性检查,如果发现满足以下条件,则开启merge:

1、参与合并的文件个数 >= hbase.hstore.compaction.min (default is 3), 但最多不超过hbase.hstore.compaction.max(default is 10)

2、参与合并的文件需满足的条件: 

文件大小 < hbase.hstore.compaction.max.size (default is Long.MAX_VALUE)

且,文件大小 < 所有创建日期比该文件大(新)的文件大小之和*1.2

文件大小 < hbase.hstore.compactoin.min.size(memstore flush size)

3、文件选择的优先级

优先考虑老文件。

hbase 批量迁移数据

1、hive插入数据至hbase

hive插入数据至hbase参数优化--数据量不大的情况可以使用,数据量大还是要采用bulkload方式

 set hive.exec.dynamic.partition.mode=nonstrict;
 #设置map并发数量
 set mapreduce.job.running.map.limit=2;
 #关闭hbase的WAL,有点事提高了写入速度,缺点是如果出现错误无法查找日志
 set hive.hbase.wal.enabled=false;
 #开启大量导入配置
 set hive.hbase.bulk=true;

2、bulkload

#hbase中创建一张新表,用于存储迁移后的数据
create 'log_new',{NAME=>'a',COMPRESSION=>'snappy', BLOOMFILTER=>'ROW', VERSIONS=>1, DFS_REPLICATION => '1'},{NUMREGIONS=>24,SPLITALGO=>'HexStringSplit',CONFIGURATION => {'hbase.regionserver.region.split.policy'=>'org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy'}}

#删除临时表
hadoop fs -rm -r -skipTrash /tmp/hbase/car_log_new

#执行MR,使用bulkload方式,将hbase数据存储至临时文件
hadoop jar statistic-job-0.0.1.jar /tmp/me/2020-05-25 /user/me/data-report.result

#将临时文件用ulkLoad方法能够将数据快速的load到HBase log_new表中
hbase org.apache.hadoop.hbase.mapreduce.LoadIncrementalHFiles /tmp/hbase/log_new log_new

2、spark hbase context

该方式利用spark,全盘scan hbase 表,来达到获取数据并写入新的表。相比前两种方式,速度更快

引用的相关jar包

        <!--版本号 -->
        <hadoop.version>3.0.0</hadoop.version>
		<hbase.version>2.0.0</hbase.version>
		<spark.version>2.2.0</spark.version>

        <!-- hbase-spark -->
        <dependency>
    	    <groupId>org.apache.hbase</groupId>
			<artifactId>hbase-spark</artifactId>
			<version>2.1.0-cdh6.1.1</version>
			<exclusions>
				<exclusion>
					<groupId>org.glassfish</groupId>
					<artifactId>javax.el</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.glassfish</groupId>
					<artifactId>javax.el</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

package xxx.spark;

import lombok.SneakyThrows;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.hbase.spark.JavaHBaseContext;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.VoidFunction;
import scala.Tuple2;
import scala.Tuple3;

import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;

/**
 * spark:迁移hbase表
 * args[0] 迁移表
 * args[1] 新表
 */
public class HbaseToHbase {
    public static void main(String[] args) {

        String tableName = args[0];
        String targetTableName = args[1];

        SparkConf sparkConf = new SparkConf().setAppName("hbase to hbase");//.setMaster("local");
        JavaSparkContext jsc = new JavaSparkContext(sparkConf);
        //jsc.addJar("spark.jar");


        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", "hdp-master01.leapmotor.com,hdp-master02.leapmotor.com,hdp-node01.leapmotor.com");
        conf.setInt("hbase.zookeeper.property.clientPort", 2181);
        /*conf.addResource(new Path("/etc/hbase/conf/core-site.xml"));
        conf.addResource(new Path("/etc/hbase/conf/hbase-site.xml"));*/

        JavaHBaseContext hbaseContext = new JavaHBaseContext(jsc, conf);

        Scan scan = new Scan();
        scan.setCaching(1000);

        JavaRDD<Tuple2<ImmutableBytesWritable, Result>> javaRdd = hbaseContext.hbaseRDD(TableName.valueOf(tableName), scan);

        hbaseContext.foreachPartition(javaRdd, new VoidFunction<Tuple2<Iterator<Tuple2<ImmutableBytesWritable, Result>>, Connection>>() {
            @Override
            public void call(Tuple2<Iterator<Tuple2<ImmutableBytesWritable, Result>>, Connection> t) throws Exception {
                Connection connection = t._2;
                BufferedMutator m = connection.getBufferedMutator(TableName.valueOf(targetTableName));
                Iterator<Tuple2<ImmutableBytesWritable, Result>> it = t._1;
                int count = 0;
                while (it.hasNext()) {
                    count++;
                    Tuple2<ImmutableBytesWritable, Result> data = it.next();
                    List<Cell> list = data._2.listCells();
                    Put put = new Put(data._2.getRow());
                    list.forEach(new Consumer<Cell>() {
                        @SneakyThrows
                        @Override
                        public void accept(Cell cell) {
                            put.add(cell);
                        }
                    });
                    m.mutate(put);
                }
                System.out.println(count);
                m.flush();
                m.close();
            }
        });

    }
}

表重命名方式

disable 'carnet:gb_binary_2024'
snapshot 'carnet:gb_binary_2024', 'gb_binary_2024_snapshot'
clone_snapshot 'gb_binary_2024_snapshot', 'carnet:gb_binary_2023'
-- delete_snapshot 'gb_binary_2024_snapshot'
-- drop 'carnet:gb_binary_2024'
enable 'carnet:gb_binary_2023'
enable 'carnet:gb_binary_2024'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值