HBase优化策略及协处理器

服务端优化

什么导致HBase性能下降

Jvm内存分配与GC回收策略

HBase运行机制相关的配置分配不合理

表结构设计及用户使用方式不合理

HBase数据存储过程

HBase写入时当memstore达到一定大小会flush到磁盘保存成HFile,当HFile小文件太多回执行compact操作进行合并(compact就是将很多小文件合并成一个大文件的过程。compact分为minor compaction和major compaction)

当Region的大小达到某一阈值之后,回执行split操作

当HBase做compact和split操作时需要优化

常见服务端配置优化

Jvm设置与GC设置

hbase-site.xml部分属性配置

属性简介建议

hbase.regionserver.handler.countrpc请求的线程数量,默认值是10

hbase.hregion.max.filesize当region的大小大于设定值后hbase就会开始split建议手动split

hbase.hregion.majorcompactionmajor compaction的执行周期将值设置成0,在业务低峰手动执行majorcompaction

hbase.hstore.compaction.min一个store里的storefile总数超过该值,会触发默认的合并操作默认3

hbase.hstore.compaction.max一次合并最多合并多少个storeFile

hbase.hstore.blockingStoreFiles一个region中的Store(CoulmnFamily)内有超过多少个storeFile时,则block所有的写请求进行compaction

hfile.block.cache.sizeregionserver的block cache的内存大小限制在偏向读的业务中可调大该值

hbase.hregion.memstore.flush.sizememstore超过该值将被flush

hbase.hregion.memstore.block.multiplier如果memstore的内存大小超过flush.size*multiplier,会阻塞该memstore的写操作建议设置成5,设置太大会有内存溢出的风险

常用优化策略

预先分区

HBase默认创建表的时候会自动创建一个Region分区

创建表时预先创建一些空的Region,并指定Rowkey的存储范围。这样可以减少Split操作,减少IO操作

Rowkey优化

利用HBase默认排序特点,将一起访问的数据放到一起

防止热点问题,避免使用时序或者单调的递增递减等

Column优化

列族的名称和列的描述命令尽量简单

同一张表的列族不要超过三个

读写优化

写优化策略

同步批量提交(默认)

异步批量提交 (会提升性能,但可能存在数据丢失,在一些业务中可以采用)

WAL优化,是否必须开启(默认开启),持久化等级

读优化策略

客户端:Scan缓存设置,批量获取

服务端:BlockCache配置是否合理,HFile是否过多(通过服务端的配置进行设置)

表结构设计问题

HBase协处理器

协处理器简介

HBase协处理器受BigTable协处理器的启发,为用户提供类库和运行时环境,使得代码能够在HBase RegionServer和Master上处理(使用协处理器需要谨慎,可能会导致性能下降甚至数据丢失)

协处理分为系统协处理器 and 表协处理器

系统协处理器:全局加载到RegionServer托管的所有表和Region上(是属于所有的表)

表协处理器:用户可以指定一张表使用协处理器(只是针对一张表)

观察者(Observer):类似于关系数据库的触发器

终端(Endpoint):动态的终端有点像存储过程

2.实现一个ResionObserver类型的协处理器

引入pom:

  org.apache.hbase

  hbase-common

  1.2.4

  org.apache.hbase

  hbase-server

  1.2.4


一个简单demo

package com.imooc.bigdata.hbase.coprocessor.observer;

import java.awt.image.ImagingOpException;

import java.io.IOException;

import java.util.Arrays;

import java.util.List;

import org.apache.hadoop.hbase.Cell;

import org.apache.hadoop.hbase.CellUtil;

import org.apache.hadoop.hbase.CoprocessorEnvironment;

import org.apache.hadoop.hbase.client.Delete;

import org.apache.hadoop.hbase.client.Durability;

import org.apache.hadoop.hbase.client.Get;

import org.apache.hadoop.hbase.client.Put;

import org.apache.hadoop.hbase.client.Result;

import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;

import org.apache.hadoop.hbase.coprocessor.ObserverContext;

import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;

import org.apache.hadoop.hbase.regionserver.wal.WALEdit;

import org.apache.hadoop.hbase.util.Bytes;

/**

* Created by xt on 18-6-18.

*/

public class RegionObserverTest extends BaseRegionObserver {

  private byte[] columnFamily = Bytes.toBytes("cf");

  private byte[] countCol = Bytes.toBytes("countCol");

  private byte[] unDeleteCol = Bytes.toBytes("unDeleteCol");

  private RegionCoprocessorEnvironment environment;

  //regionserver 打开region前执行

  @Override

  public void start(CoprocessorEnvironment e) throws IOException {

    environment = (RegionCoprocessorEnvironment) e;

  }

  //RegionServer关闭region前调用

  @Override

  public void stop(CoprocessorEnvironment e) throws IOException {

  }

  /**

  * 1. cf:countCol 进行累加操作。 每次插入的时候都要与之前的值进行相加

  */

  @Override

  public void prePut(ObserverContext e, Put put, WALEdit edit,

      Durability durability) throws IOException {

    if (put.has(columnFamily, countCol)) {

      //获取old countcol value

      Result rs = e.getEnvironment().getRegion().get(new Get(put.getRow()));

      int oldNum = 0;

      for (Cell cell : rs.rawCells()) {

        if (CellUtil.matchingColumn(cell, columnFamily, countCol)) {

          oldNum = Integer.valueOf(Bytes.toString(CellUtil.cloneValue(cell)));

        }

      }

      //获取new countcol value

      List cells = put.get(columnFamily, countCol);

      int newNum = 0;

      for (Cell cell : cells) {

        if (CellUtil.matchingColumn(cell, columnFamily, countCol)) {

          newNum = Integer.valueOf(Bytes.toString(CellUtil.cloneValue(cell)));

        }

      }

      //sum AND update Put实例

      put.addColumn(columnFamily, countCol, Bytes.toBytes(String.valueOf(oldNum + newNum)));

    }

  }

  /**

  * 2. 不能直接删除unDeleteCol    删除countCol的时候将unDeleteCol一同删除

  */

  @Override

  public void preDelete(ObserverContext e, Delete delete,

      WALEdit edit,

      Durability durability) throws IOException {

    //判断是否操作cf列族

    List cells = delete.getFamilyCellMap().get(columnFamily);

    if (cells == null || cells.size() == 0) {

      return;

    }

    boolean deleteFlag = false;

    for (Cell cell : cells) {

      byte[] qualifier = CellUtil.cloneQualifier(cell);

      if (Arrays.equals(qualifier, unDeleteCol)) {

        throw new IOException("can not delete unDel column");

      }

      if (Arrays.equals(qualifier, countCol)) {

        deleteFlag = true;

      }

    }

    if (deleteFlag) {

      delete.addColumn(columnFamily, unDeleteCol);

    }

  }

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容