1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Hbase 进阶

Hbase 进阶

时间:2023-12-20 21:51:11

相关推荐

Hbase 进阶

目录

1. HBase MemStore Flush1.1 MemStore 概述1.2 MemStore Flush 触发条件 2.HBase Compaction3. Region Move4. Region Spilt4.1 HBase Region Spilt 类型4.2 HBase Region Spilt 流程 5. Region Merge5.1 Region Merge 场景5.2 Region Merge 流程 6. RowKey 设计6.1 RowKey 设计规范6.2 常用的 RowKey 设计6.2.1 Salt RowKey6.2.2 Hash RowKey(建议使用)6.2.3 Reverse RowKey6.2.4 单调递增 RowKey6.2.5 倒序时间戳 RowKey 7. 协处理器7.1 POM 文件7.2 Code7.2.1 ESUtils Code7.2.2 HBaseElasticsearchObserver Code 7.3 增加协处理器7.4 报错

HBase 1.4 参数地址

1. HBase MemStore Flush

1.1 MemStore 概述
之前给大家简单介绍了 MemStore,这里需要介绍 MemStore 的 Flush,再介绍一下 MemStore。在 HBase 中,Region 是最小的数据服务单元,一个表是由一个或者多个 Region 组成的。在 Region 中又根据 ColumnFamily (列簇)的数量分为一个或者多个 Store,一个ColumnFamily 对应一个 Store。每个 Store 分成 一个 MemStore 和多个 HFile。 HBase 中所有的数据在做更新或者插入操作之前,都是先把数据写入到 MemStore 里面,达到指定大小之后再把这些操作写入磁盘中,生成一个新的 HFile 文件,这种设计极大的提高了 HBase 的写入性,数据在写入到 MemStore 中的同时会按照顺序把数据写入到 HLog 中。HBase 为了方便 RowKey 进行检索,数据在 MemStore 中会先进行一次排序,然后再写入到 HFile中,HFile 中的数据都要按照 RowKey 进行排序,是数据保持有序。HBase 在读取数据先从 MemStore 中读取数据,如果没有找到则会去 HFile 中找,最后要是再找不到,则会去 HLog 中找,把最终结果 Merge 之后返回给用户。可见在 HBase 中无论是写入数据还是读取数据,MemStore 都至关重要,接下来重点针对 MemStore 的 Flush 操作进行深入的解析。
1.2 MemStore Flush 触发条件
MemStore 级别限制: 当 Region 中任一 MemStore 的大小达到了刷新的阈值(hbase.hregion.memstore.flush.size ,默认是128M),会触发该 MemStore 的 Flush。 Region 级别限制: 当一个 Region 中所有的 MemStore 大小总和达到了上限(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认是 4 * 128M ),会触发该 Region 里面所有的 MemStore Flush 操作,在 Flush 的同时,会阻塞所有写入该 Store 的写请求,继续对该 Region 发送请求的时候,会抛错 region too busy exception 异常。 Region Server 级别限制: 当 Region Server 中的所有 MemStore 大小总和达到了上限 (hbase.regionserver.global.memstore.upperLimit * hbase_heapsize),会触发该 Region Server 的 MemStore Flush,按照 MemStore 的大小由大到小执行 Flush,直到该 Region Server 里所有的 MemStore 低于阈值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize)则停止刷新。 Hlog级别限制: 当一个 Region Server 中 HLog 数据达到阈值(hbase.regionserver.maxlogs)时,系统会选取最早的一个 HLog 对应的一个或者多个 Region 进行 Flush。 HBase 定期刷新 MemStore: 设置 HBase 定期刷新的参数为:hbase.regionserver.optionalcacheflushinterval ,默认为一个小时,为了避免所有的 MemStore 都在统一时刻 Flush 导致无法写入任何数据,定期的 Flush 会有一定的随机延时,设置为0,表示禁用。 手动执行 Flush: 用户可以通过shell命令 flush ‘tablename’或者flush ‘region name’分别对一个表或者一个 Region 进行 Flush。 总结: 在生产上面,唯独触发 Region Server 级别的 Flush ,是属于灾难级别的,会阻塞所有落在该 Region Server 上面的读写请求,阻塞时间较长,其他级别的 Flush ,只会阻塞对应的 Region 上面的读写请求,阻塞时间较短。

2.HBase Compaction

随着 HBase 运行的时间越来越长,MemStore 会 Flush 生成多个 HFile,可能会导致,随机读取一条数据,需要检索多个 HFile ,而且会在 HDFS 上面生成多个小文件,基于这些,HBase 提供了 Compaction。Compaction 的作用: 小文件合并,减少文件的数量,减少稳定度的延迟。对于删除、过期、多版本冗余的数据进行清除,降低存储空间,提高数据的本地化率。 Compaction 的分类: Minor Compaction:只合并小文件,对TTL过期数据设置过期清理,不会对文件内容进行清除操作。Major Compaction:对 Region 下同一个 Column family 的 StoreFile 合并为一个大文件,并且清除删除、过期、多余版本的数据。 Compaction 的触发条件: 当每次 MemStore Flush 的时候,将数据写入到 HFile 中,每次 Flush 会对当前的 Store 里面的总文件数进行检验,一旦总文件数超过阈值(pactionThreshold 默认是3),则触发 Compaction 操作。后台线程定期检查:后台线程(CompactionChecker)定期检查是否需要执行合并,检查周期为(hbase.server.thread.wakefrequency * pactchecker.interval.multiplier 默认值:10000ms*1000)。手动触发:执行命令 major_compact 、 compact。当文件小于阈值(paction.min.size 默认 128M),则会立即被添加到 Major Compaction 合并的队列,当 HFile 数量超过阈值(paction.min 默认3),则启动 Minor Compaction。 生产上(建议): hbase.hregion.majorcompaction = 0 ,关闭 Major Compaction。pactionThreshold = 6 (默认3),修改 发生 Minor Compaction 的文件数量。

3. Region Move

在工作中,某个 Region Server 上面如果有很多大的 Region ,且读写请求比较频繁,其他的 Region Server 比较空闲,导致请求不均匀。这时候可以手动 Move Region 到空闲的 Region Server,使集群资源充分利用。Move 是 Region 的迁移,是一个轻量级的操作,因为本身 HBase 数据存储在 HDFS 上面,不需要独立管理数据,因此 Region 的迁移,真实不需要迁移数据,只是把这个 Region 中的读写服务都放在另一台 Region Server 上面。

Move a region. Optionally specify target regionserver else we choose oneat random. NOTE: You pass the encoded region name, not the region name sothis command is a little different to the others. The encoded region nameis the hash suffix on region names: e.g. if the region name wereTestTable,0094429456,1289497600452.527db22f95c8a9e0116f0cc13c680396. thenthe encoded region name portion is 527db22f95c8a9e0116f0cc13c680396A server name is its host, port plus startcode. For example:,60020,1289493121758Examples:hbase> move 'ENCODED_REGIONNAME'hbase> move 'ENCODED_REGIONNAME', 'SERVER_NAME'

4. Region Spilt

4.1 HBase Region Spilt 类型
ConstantSizeRegionSplitPolicy:0.94版本前默认切分策略。这是最容易理解但也最容易产生误解的切分策略,从字面意思来看,当 Region 大小大于某个阈值(hbase.hregion.max.filesize)之后就会触发切分,实际上并不是这样,真正实现中这个阈值是对于某个 Store 来说的,即一个 Region 中最大 Store 的大小大于设置阈值之后才会触发切分。另外一个大家比较关心的问题是这里所说的 Store 大小是压缩后的文件总大小还是未压缩文件总大小,实际实现中 Store 大小为压缩后的文件大小(采用压缩的场景)。ConstantSizeRegionSplitPolicy 相对来来说最容易想到,但是在生产线上这种切分策略却有相当大的弊端:切分策略对于大表和小表没有明显的区分。阈值(hbase.hregion.max.filesize)设置较大对大表比较友好,但是小表就有可能不会触发分裂,极端情况下可能就1个,这对业务来说并不是什么好事。如果设置较小则对小表友好,但一个大表就会在整个集群产生大量的region,这对于集群的管理、资源使用、failover来说都不是一件好事。IncreasingToUpperBoundRegionSplitPolicy: 0.94版本~2.0版本默认切分策略。这种切分策略微微有些复杂,总体来看和 ConstantSizeRegionSplitPolicy 思路相同,一个 Region 中最大 Store 大小大于设置阈值就会触发切分。但是这个阈值并不像 ConstantSizeRegionSplitPolicy 是一个固定的值,而是会在一定条件下不断调整,调整规则和 Region 所属表在当前 Region Server 上的 Region 个数有关系 :(#region个数)^3 * flush size * 2,当然阈值并不会无限增大,最大值为用户设置的 MaxRegionFileSize。这种切分策略很好的弥补了 ConstantSizeRegionSplitPolicy 的短板,能够自适应大表和小表。而且在大集群条件下对于很多大表来说表现很优秀,但并不完美,这种策略下很多小表会在大集群中产生大量小 Region,分散在整个集群中。而且在发生 Region 迁移时也可能会触发 Region 分裂。SteppingSplitPolicy: 2.0版本默认切分策略。这种切分策略的切分阈值又发生了变化,相比 IncreasingToUpperBoundRegionSplitPolicy 简单了一些,依然和待分裂 Region 所属表在当前 RegionServer 上的 Region 个数有关系,如果 Region 个数等于1,切分阈值为 flush size * 2,否则为 MaxRegionFileSize。这种切分策略对于大集群中的大表、小表会比 IncreasingToUpperBoundRegionSplitPolicy 更加友好,小表不会再产生大量的小 Region,而是适可而止。建议使用:ConstantSizeRegionSplitPolicy
4.2 HBase Region Spilt 流程
Region In Transition: RIT Region Server 更改ZK节点 /hbase/region-in-transition 中该 Region 的状态为 SPLITING。Master通过watch节点 /hbase/region-in-transition 检测到 Region 状态改变,并修改内存中 Region 的状态,在 Master 页面RIT模块就可以看到 Region 执行 Split 的状态信息。在父存储目录下新建临时文件夹.split保存 Split 后的daughter region信息。关闭 Parent Region:Parent Region 关闭数据写入并触发 Flush 操作,将写入 Region 的数据全部持久化到磁盘。此后短时间内客户端落在父 Region 上的请求都会抛出异常 NotServingRegionException。核心分裂步骤:在.split文件夹下新建两个子文件夹,称之为daughter A、daughter B,并在文件夹中生成 reference 文件,分别指向父 Region 中对应文件。父 Region 分裂为两个子 Region 后,将daughter A、daughter B拷贝到 HBase 根目录下,形成两个新的 Region。Parent Region 通知修改 hbase.meta 表后下线,不再提供服务。下线后 Parent Region在 meta 表中的信息并不会马上删除,而是标注 Split 列、offline列为true,并记录两个子 Region。开启daughter A、daughter B两个子 Region 。通知修改 hbase.meta 表,正式对外提供服务。

5. Region Merge

Merge two regions. Passing 'true' as the optional third parameter will forcea merge ('force' merges regardless else merge will fail unless passedadjacent regions. 'force' is for expert use only).You can pass the encoded region name or the full region name. The encodedregion name is the hash suffix on region names: e.g. if the region name wereTestTable,0094429456,1289497600452.527db22f95c8a9e0116f0cc13c680396. thenthe encoded region name portion is 527db22f95c8a9e0116f0cc13c680396Examples:hbase> merge_region 'FULL_REGIONNAME', 'FULL_REGIONNAME'hbase> merge_region 'FULL_REGIONNAME', 'FULL_REGIONNAME', truehbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME'hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME', true

5.1 Region Merge 场景
当某个 Region 长时间没有被写入数据,而且该 Region 里面的数据可能是因为 TTL(数据存活时间) 过期而删除,在这种情况下,该 Region 存在没什么意义。一旦空闲的 Region 很多,会导致集群的运维成本上升,所以将相邻的空闲 Region 进行 Merge,可以有效的减少 Region 的数量。
5.2 Region Merge 流程
客户端发送 Merge 请求到 Master。Master 将待 Merge 的 Region 放在一个 Region Server 里面。Master 发送合并请求给 Region Server 。Region Server 接受到 Merge 请求,启动本地事务执行 Merge 操作。在 Merge 操作中首先是先把两个带合并的 Region 下线,然后再进行 Merge 操作。将 meta 表中合并前的两个 Region 信息删除,合并结束后再把新的 Region 的信息写入到 meta 表中。上线新的 Region。

6. RowKey 设计

6.1 RowKey 设计规范
Region 中 有两个重要的指标 SartKey、EndKey,这两个指的是 Region 中 RowKey 的范围。在 HBase 中获取数据有两种方式: 通过 RowKey 得到数据。全表查询数据。 RowKey 唯一原则 HBase 中的 RowKey 相当于关系型数据库中的主键。 RowKey 长度原则 为了减少 RowKey 带来的磁盘消耗,RowKey 是一个二进制的字符,最大长度为64KB,建议不要超过 16 字节。HBase 中的存储结构是 Key Value 格式存储的,如果 RowKey 过长,会极大的影响 HFile 文件的存储效率,会频繁的触发 MemStore Flush 机制。
6.2 常用的 RowKey 设计
6.2.1 Salt RowKey
固定长度的随机数 + 原始表的主键 ==> RowKey优点: 极大的提高了写入数据的吞吐量,保障所有的 Region 负载均衡。 缺点: 由于添加的是随机数,基于原表查询的时候不知道 前面的随机数是什么,无法准确的锁定一条数据。由于不知道前面增加的随机数是什么,无法更新数据,导致数据会重复。
6.2.2 Hash RowKey(建议使用)
基于原表主键进行 Hash ,将 Hash 值作为 RowKey 前缀,然后再加上原表前缀。算法包:md5 sha1 sha256 sha512优点: 同一条数据只会生成一个 RowKey,不会重复数据。极大的提高了写入数据的吞吐量,保障所有的 Region 负载均衡。对通过 RowKey 得到一条数据十分有利。 缺点: 不利于全表查询数据,由于 RowKey 是通过 Hash 之后计算出来的,数据只根据 RowKey 进行排序,原始的数据则是无序的。
6.2.3 Reverse RowKey
如果原表的主键类似于手机号码、身份证号,数据开头为1、3比较密集,会导致数据的分布不均匀,可以先把原表主键翻转作为 RowKey。优点: 同一条数据只会生成一个 RowKey,不会重复数据。极大的提高了写入数据的吞吐量,保障所有的 Region 负载均衡。对通过 RowKey 得到一条数据十分有利。 缺点: 不利于全表查询数据,由于 RowKey 是通过 Hash 之后计算出来的,数据只根据 RowKey 进行排序,原始的数据则是无序的。原表主键要是手机号、身份证号这种类型的。
6.2.4 单调递增 RowKey
单调递增的行键客户端的请求都通过 这个 Region 响应,当这个 Region 写完了之后才会进行其他 Region 的写的操作。
6.2.5 倒序时间戳 RowKey
把时间戳倒序作为 RowKey

7. 协处理器

协处理器作用是类似于触发器的作用,再把数据写入到 HBase 的时候,会同步写入到 ES(ElasticSearch) 里面,有时候由于业务的原因,需要 OLAP,HBase 重写轻读,不能更好的处理业务,则需要引用 ES ,把 Hbase 中的数据下发到 ES 里面。
7.1 POM 文件

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.9.3</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>1.2.0-cdh5.16.2</version></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><version>1.2.0-cdh5.16.2</version></dependency><dependency><groupId>mons</groupId><artifactId>commons-lang3</artifactId><version>3.11</version></dependency>

7.2 Code
7.2.1 ESUtils Code

package com.xk.bigdata.hbase.utils;import org.apache.http.HttpHost;import org.elasticsearch.client.RestClient;import org.elasticsearch.client.RestHighLevelClient;import java.io.IOException;import java.lang.reflect.Field;import mons.lang3.StringUtils;import java.util.ArrayList;import java.util.List;public class ESUtils {// ElasticSearch的集群名称public static String clusterName;// ElasticSearch的hostpublic static String nodeHost;// ElasticSearch的端口(Java API用的是Transport端口,也就是TCP)public static int nodePort;// ElasticSearch的索引名称public static String indexName;public static RestHighLevelClient client;/*** 初始化客户端*/public static void iniClient() {client = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));}/*** 得到 ESUtils 里面配置的常量数据*/public static String getInfo() {List<String> fields = new ArrayList<String>();try {for (Field f : ESUtils.class.getDeclaredFields()) {fields.add(f.getName() + "=" + f.get(null));}} catch (IllegalAccessException ex) {ex.printStackTrace();}return StringUtils.join(fields, ", ");}/*** 关闭客户端*/public static void stopClient() throws IOException {if (null != client) {client.close();}}}

7.2.2 HBaseElasticsearchObserver Code

package com.xk.bigdata.hbase.observer;import com.xk.bigdata.hbase.utils.ESUtils;import mons.logging.Log;import mons.logging.LogFactory;import org.apache.hadoop.conf.Configuration;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.Put;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;import org.elasticsearch.action.DocWriteResponse;import org.elasticsearch.action.delete.DeleteRequest;import org.elasticsearch.action.delete.DeleteResponse;import org.elasticsearch.action.index.IndexRequest;import org.elasticsearch.action.index.IndexResponse;import org.elasticsearch.client.RequestOptions;import java.io.IOException;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.NavigableMap;public class HBaseElasticsearchObserver extends BaseRegionObserver {private static final Log LOG = LogFactory.getLog(HBaseElasticsearchObserver.class);/*** 读取配置文件** @param env 上下文*/private static void readConfiguration(CoprocessorEnvironment env) {Configuration conf = env.getConfiguration();ESUtils.clusterName = conf.get("es_cluster");ESUtils.nodeHost = conf.get("es_host");ESUtils.nodePort = conf.getInt("es_port", -1);ESUtils.indexName = conf.get("es_index");}/*** 开始之前执行*/@Overridepublic void start(CoprocessorEnvironment e) throws IOException {// 读取配置文件readConfiguration(e);// 初始化 ESESUtils.iniClient();LOG.error("------observer init EsClient ------" + ESUtils.getInfo());}/*** 最后执行*/@Overridepublic void stop(CoprocessorEnvironment e) throws IOException {ESUtils.stopClient();}/*** 插入数据*/@Overridepublic void postPut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException {String indexId = new String(put.getRow());try {NavigableMap<byte[], List<Cell>> familyMap = put.getFamilyCellMap();Map<String, Object> map = new HashMap<String, Object>();for (Map.Entry<byte[], List<Cell>> entry : familyMap.entrySet()) {for (Cell cell : entry.getValue()) {String key = Bytes.toString(CellUtil.cloneQualifier(cell));String value = Bytes.toString(CellUtil.cloneValue(cell));map.put(key, value);}}IndexRequest indexRequest = new IndexRequest(ESUtils.indexName).id(indexId);indexRequest.source(map);IndexResponse indexResponse =ESUtils.client.index(indexRequest, RequestOptions.DEFAULT);if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {System.out.println("create success:" + ESUtils.indexName + " : " + indexId);} else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {System.out.println("update success: " + ESUtils.indexName + " : " + indexId);} else {System.out.println("create/update fail: " + ESUtils.indexName + " : " + indexId + " : " + indexResponse.getResult().toString());}} catch (Exception ex) {LOG.error(ex);LOG.error("observer put a doc, index [ " + ESUtils.indexName + " ]" + "indexId [" + indexId + "] error : " + ex.getMessage());}}/*** 删除数据*/@Overridepublic void postDelete(ObserverContext<RegionCoprocessorEnvironment> e, Delete delete, WALEdit edit, Durability durability) throws IOException {String indexId = new String(delete.getRow());try {DeleteRequest request = new DeleteRequest(ESUtils.indexName,indexId);DeleteResponse deleteResponse = ESUtils.client.delete(request, RequestOptions.DEFAULT);if (deleteResponse.getResult() == DocWriteResponse.Result.DELETED) {System.out.println("delete success: " + ESUtils.indexName + " : " + indexId);} else {System.out.println("delete fail: " + ESUtils.indexName + " : " + indexId + " : " + deleteResponse.getResult().toString());}} catch (Exception ex) {LOG.error(ex);LOG.error("observer delete a doc, index [ " + ESUtils.indexName + " ]" + "indexId [" + indexId + "] error : " + ex.getMessage());}}}

7.3 增加协处理器
上传 Jar 到 HDFS

[hadoop@bigdata ~]$ cd lib/[hadoop@bigdata lib]$ ll总用量 88052-rw-r--r--. 1 hadoop hadoop 90161640 2月 6 21:16 hbase-basic-1.0-jar-with-dependencies.jar[hadoop@bigdata lib]$ hadoop fs -mkdir /lib21/02/06 21:17:42 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable[hadoop@bigdata lib]$ hadoop fs -put hbase-basic-1.0-jar-with-dependencies.jar /lib21/02/06 21:18:01 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

添加协处理器

[hadoop@bigdata lib]$ cd ~[hadoop@bigdata ~]$ cd app/hbase[hadoop@bigdata hbase]$ bin/hbase shellhbase(main):001:0> create 'hbasetoes','info'0 row(s) in 1.4130 seconds=> Hbase::Table - hbasetoeshbase(main):002:0> disable 'hbasetoes'0 row(s) in 2.3290 secondshbase(main):003:0> alter 'hbasetoes', METHOD => 'table_att','coprocessor'=>'hdfs://bigdata:9000/lib/hbase-basic-1.0-jar-with-dependencies.jar|com.xk.bigdata.hbase.observer.HBaseElasticsearchObserver|1001|es_cluster=hbasetoes_es,es_host=bigdata,es_port=9200,es_index=hbasetoes_index'Updating all regions with the new schema...1/1 regions updated.Done.0 row(s) in 1.9500 secondshbase(main):004:0> enable 'hbasetoes'0 row(s) in 4.2700 secondshbase(main):005:0> put 'hbasetoes','key1','info:c1','100'0 row(s) in 1.1430 secondshbase(main):006:0> put 'hbasetoes','key1','info:c1','10'0 row(s) in 0.0090 seconds

查看 HBase Region Server 日志

-02-06 22:58:57,314 ERROR [RS_OPEN_REGION-bigdata:60020-0] observer.HBaseElasticsearchObserver: ------observer init EsClient ------clusterName=hbasetoes_es, nodeHost=bigdata, nodePort=9200, indexName=hbasetoes_index, client=org.elasticsearch.client.RestHighLevelClient@e099b57-02-06 22:58:57,315 INFO [RS_OPEN_REGION-bigdata:60020-0] regionserver.RegionCoprocessorHost: Loaded coprocessor com.xk.bigdata.hbase.observer.HBaseElasticsearchObserver from HTD of hbasetoes successfully.

查询 es

GET hbasetoes_index/_search{"took" : 0,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.0,"hits" : [{"_index" : "hbasetoes_index","_type" : "_doc","_id" : "key1","_score" : 1.0,"_source" : {"c1" : "10"}}]}}

卸载协处理器

hbase(main):007:0> disable 'hbasetoes'0 row(s) in 2.2480 secondshbase(main):008:0> alter 'hbasetoes', METHOD => 'table_att_unset', NAME => 'coprocessor$1'Updating all regions with the new schema...1/1 regions updated.Done.0 row(s) in 1.8960 secondshbase(main):009:0> enable 'hbasetoes'0 row(s) in 1.2380 seconds

7.4 报错
报错内容

java.lang.NoClassDefFoundError: org/apache/http/client/config

排查原因,发现是 httpclient、guava 冲突,具体的 POM 如下

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><parent><artifactId>hbase-project</artifactId><groupId>com.xk.bigdata</groupId><version>1.0</version></parent><modelVersion>4.0.0</modelVersion><artifactId>hbase-basic</artifactId><dependencies><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-server</artifactId><exclusions><exclusion><artifactId>httpcore</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion><exclusion><artifactId>httpclient</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion><exclusion><artifactId>guava</artifactId><groupId>com.google.guava</groupId></exclusion></exclusions></dependency><dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><exclusions><exclusion><artifactId>httpclient</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion><exclusion><artifactId>httpcore</artifactId><groupId>org.apache.httpcomponents</groupId></exclusion></exclusions></dependency><dependency><groupId>mons</groupId><artifactId>commons-lang3</artifactId></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency></dependencies><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build></project>

还有疑问可以翻看 GitHub上面代码

GitHub 代码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。