HBase写入优化--write buff

简介: write buff操作 前两天在观察kafka消费数据的时候,发现HBase偶尔会报一个org.apache.hadoop.hbase.RegionTooBusyException: org.apache.hadoop.hbase.RegionTooBusyException这种错误出来,从描述上看,是HBase写入太过频繁导致的。

write buff操作

前两天在观察kafka消费数据的时候,发现HBase偶尔会报一个org.apache.hadoop.hbase.RegionTooBusyException: org.apache.hadoop.hbase.RegionTooBusyException这种错误出来,从描述上看,是HBase写入太过频繁导致的。

首先来看我的写入操作代码:

/**
     * 单条更新hbase数据
     * 
     * @param tableName
     *            表名
     * @param put
     *            put对象
     * @return 成功与否
     * @throws IOException
     */
    public synchronized boolean insert(String tableName, Put put) throws IOException {
        Table table = getTable(tableName);
        table.put(put);
        table.close();
        return true;
    }

这种方式写入单条数据,写入情况就是,没过来一条数据,就向HBase的region里面写入一条,操作太频繁。
解决方式:批量写入
首先,在hbase-site.xml配置文件中加入(也可以使用其他配置方式,如代码方式,但是不建议使用代码方式,发布时候还要重新编译,太麻烦):

 <property>
    <name>hbase.client.write.buffer</name>
    <value>5242880</value>
  </property>

设置达到多少时候就行写入。
接着,修改单条写入时候的代码:

public synchronized boolean insert(String tableName, Put put) throws IOException {
        HTable table  = (HTable) getTable(tableName);
        table.setAutoFlushTo(false);
        put.setDurability(Durability.SKIP_WAL);//禁用hbase的预写日志功能
        table.put(put);
        return true;
    }

这样,如果调用这个insert方法,插入数据,虽然成功返回也不报错,但是只是在客户端做一个数据累计,等达到了我设置的5M之后,才进行一次性写入。虽然这样做减少了IO次数和网络传输次数,但是,一旦客户端出错或者HBase有问题,那么这些数据就丢失掉了,对于保证数据绝对不能丢失的这种情况,建议谨慎使用。

write buff分析

  • Put操作
 public void put(Put put) throws IOException {
        this.getBufferedMutator().mutate(put);
        if(this.autoFlush) {
            this.flushCommits();
        }
    }

观察HBase client的api,会发现,这里,如果是autoFlash,会立马执行一个操作,叫做flushCommits,在这个操作里面,会立即将数据写入数据库。
另外,在table进行关闭的时候,也会隐性的将数据写入数据库:

 public void close() throws IOException {
        if(!this.closed) {
            this.flushCommits();
            if(this.cleanupPoolOnClose) {
                this.pool.shutdown();

                try {
                    boolean e = false;

                    do {
                        e = this.pool.awaitTermination(60L, TimeUnit.SECONDS);
                    } while(!e);
                } catch (InterruptedException var2) {
                    this.pool.shutdownNow();
                    LOG.warn("waitForTermination interrupted");
                }
            }

            if(this.cleanupConnectionOnClose && this.connection != null) {
                this.connection.close();
            }

            this.closed = true;
        }
    }

真正的写入操作,其实是发生在:

  public void mutate(List<? extends Mutation> ms) throws InterruptedIOException, RetriesExhaustedWithDetailsException {
        if(this.closed) {
            throw new IllegalStateException("Cannot put when the BufferedMutator is closed.");
        } else {
            long toAddSize = 0L;

            Mutation m;
            for(Iterator i$ = ms.iterator(); i$.hasNext(); toAddSize += m.heapSize()) {
                m = (Mutation)i$.next();
                if(m instanceof Put) {
                    this.validatePut((Put)m);
                }
            }

            if(this.ap.hasError()) {
                this.currentWriteBufferSize.addAndGet(toAddSize);
                this.writeAsyncBuffer.addAll(ms);
                this.backgroundFlushCommits(true);
            } else {
                this.currentWriteBufferSize.addAndGet(toAddSize);
                this.writeAsyncBuffer.addAll(ms);
            }

            while(this.currentWriteBufferSize.get() > this.writeBufferSize) {
                this.backgroundFlushCommits(false);
            }

        }
    }

当当前的数据达到我们设置的buff size的时候,才会进行一个真正的写入操作。

PS:如果想让数据立即写入,可以显示调用flushCommits或者调用close方法。

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
&nbsp; 相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情:&nbsp;https://cn.aliyun.com/product/hbase &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
6月前
|
机器学习/深度学习 分布式计算 Hadoop
一种HBase表数据迁移方法的优化
一种HBase表数据迁移方法的优化
90 0
|
存储 缓存 算法
HBase优化之路-合理的使用编码压缩
为什么要讨论HBase编码压缩 编码+压缩能够成倍的减少数据的磁盘占用空间,节省可观的存储费用 编码+压缩通常情况下可以提高系统吞吐率,让系统可以做更多的功 默认建表不启用编码或者压缩,对初学者不友好 了解HBase编码 举个栗子,我们有一张物流表叫"express",记录物流订单的流转详情。
4428 0
|
3月前
|
缓存 监控 Java
"Java垃圾回收太耗时?阿里HBase GC优化秘籍大公开,让你的应用性能飙升90%!"
【8月更文挑战第17天】阿里巴巴在HBase实践中成功将Java垃圾回收(GC)时间降低90%。通过选用G1垃圾回收器、精细调整JVM参数(如设置堆大小、目标停顿时间等)、优化代码减少内存分配(如使用对象池和缓存),并利用监控工具分析GC行为,有效缓解了高并发大数据场景下的性能瓶颈,极大提升了系统运行效率。
71 4
|
存储 SQL 消息中间件
Kylin 在贝壳的性能挑战和 HBase 优化实践(2)
Kylin 在贝壳的性能挑战和 HBase 优化实践
130 0
Kylin 在贝壳的性能挑战和 HBase 优化实践(2)
|
SQL 分布式计算 监控
Kylin 在贝壳的性能挑战和 HBase 优化实践(1)
Kylin 在贝壳的性能挑战和 HBase 优化实践
126 0
Kylin 在贝壳的性能挑战和 HBase 优化实践(1)
|
Arthas 负载均衡 Java
Hbase1.3 生产优化,源码分析
Hbase1.3 生产优化,源码分析
131 0
|
缓存 安全 Java
HBase 优化_3 | 学习笔记
快速学习 HBase 优化_3
160 0
|
存储 缓存 分布式数据库
HBase 优化_2 | 学习笔记
快速学习 HBase 优化_2
115 0
|
存储 负载均衡 分布式数据库
HBase 优化_1 | 学习笔记
快速学习 HBase 优化_1
127 0