Hbase安装以及基本操作

Hbase基礎學習

一,HBASE的安裝(MAC環境)

下載路徑: http://archive.apache.org/dist/hbase/ (2.4.0)

下載完解壓到 /usr/local/ 目錄下的 hbase-2.4.0 目錄下

tar -zxvf /Data/hbase-2.4.0-bin.tar.gz /Data/hbase-2.4.0/

1.1 修改配置文件

進入 hbase-2.4.0/conf目錄,修改hbase-env.sh和hbase-site.xml文件

1.1.1 hbase-env.sh

在該文件下配置java路徑(JAVA_HOME),hbase使用HBASE自帶的zookeeper(HBASE_MANAGES_ZK),和pid存儲位置(HBASE_PID_DIR)

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/
export HBASE_MANAGES_ZK=true
export HBASE_PID_DIR=/usr/local/hbase-2.4.0/pids

1.1.2 hbase-site.xml

在該文件的configuration標籤中加入以下配置:

 <!--Hbase的运行模式。false是单机模式,true是分布式模式。若为false,Hbase和Zookeeper会运行在同一个JVM里面。默認為false-->
<property>
    <name>hbase.cluster.distributed</name>
    <value>false</value>
  </property>
  <!-- 臨時文件,默認在系統根目錄下 -->
  <property>
    <name>hbase.tmp.dir</name>
    <value>./tmp</value>
   </property>
  <!--检查兼容性,如果设置为false,数据有可能丢失(这是一个警告)-->
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
  <!--region server的共享目录,用来持久化Hbase。-->
  <property>
    <name>hbase.rootdir</name>
     <!--使用本機hadoop的HDFS存儲數據-->
    <value>hdfs://10.197.29.203:9000/hbase-tmp</value>
     <!--使用本機文件系統存儲數據-->
   <!--
      <value>file:///usr/local/hbase-2.4.0/hbase-tmp</value>
   -->
  </property>

1.2 配置環境變量

修改.bashrc文件

vim ~/.bashrc

 export PATH=$PATH:/usr/local/hbase-2.4.0/bin

source ~/.bashrc

查看HBASE是否安裝成功

/usr/local/hbase-2.4.0/bin/hbase version

1.3 運行

啟動Hbase,操作HBASE數據庫

bin/start-hbase.sh
bin/hbase shell

jps查看啟動情況

jps

此時應該存在一個名稱為 HMaster 的進程

關閉Hbase

bin/stop-hbase.sh

1.4 常見問題

1.4.1 JAVA_HOME is not set

进入/usr/local/hbase-2.4.0目录,修改conf/目录下的hbase-env.sh文件,找到 export JAVA_HOME  这一行注释内容,将原来的java环境删除,换上自己的java路径就可以了
  1. 啟動Hbase,操作HBASE數據庫
bin/start-hbase.sh
bin/hbase shell
  1. 關閉Hbase
bin/stop-hbase.sh

1.4.2 KeeperErrorCode = ConnectionLoss for /hbase

啟動/關閉hbase等命令時不要使用 sudo 命令

1.4.3 hadoop安裝後hbase的ruby出錯

LoadError: load error: irb/completion -- java.lang.IncompatibleClassChangeError

將lib下的jruby-complete-x.x.x.jar包修改版本,(我的hbase是2.4.0,修改jar包成jruby-complete-9.1.17.0.jar)

然後在hadoop的 hadoop-2.4.0/share/hadoop/yarn/lib目錄下,也修改 jline-x.x.x.jar這個jar包的版本(我的hadoop是2.4.0,修改jar包成 jline-3.9.0.jar)

二,Hbase常用命令

命名描述语法
whoami我是谁whoami
version返回hbase集群的状态信息version
status返回hbase集群的状态信息status
table_help查看如何操作表table_help
create创建表create ‘表名’, ‘列族1’ create ‘表名’, ‘列族1’, ‘列族2’, ‘列族N’
alter修改列族添加一个列族:alter ‘表名’, 列族X’ 删除列族:alter ‘表名’, {NAME=> ‘列族’, METHOD=> ‘delete’}
describe显示表相关的详细信息describe/desc ‘表名’
list列出hbase中存在的所有表list
exists测试表是否存在exists ‘表名’
put添加或修改的表的值put ‘表名’, ‘行键’, ‘列族名’, ‘列值’ put ‘表名’, ‘行键’, ‘列族名:列名’, ‘列值’
scan通过对表的扫描来获取对用的值scan ‘表名’ 扫描某个列族: scan ‘表名’, {COLUMN=>‘列族名’} 扫描某个列族的某个列: scan ‘表名’, {COLUMN=>‘列族名:列名’} 查询同一个列族的多个列: scan ‘表名’, {COLUMNS => [ ‘列族名1:列名1’, ‘列族名1:列名2’, …]}
get获取行或单元(cell)的值get ‘表名’, ‘行键’ get ‘表名’, ‘行键’, ‘列族名’
count统计表中行的数量count ‘表名’
incr增加指定表行或列的值incr ‘表名’, ‘行键’, ‘列族:列名’, 步长值
get_counter获取计数器get_counter ‘表名’, ‘行键’, ‘列族:列名’
delete删除指定对象的值(可以为表,行,列对应的值,另外也可以指定时间戳的值))删除列族的某个列: delete ‘表名’, ‘行键’, ‘列族名:列名’
deleteall删除指定行的所有元素值deleteall ‘表名’, ‘行键’
enable使表有效enable ‘表名’
disable使表无效disable ‘表名’
is_enabled是否启用is_enabled ‘表名’
is_disabled是否无效is_disabled ‘表名’
drop删除表drop的表必须是disable的 disable ‘表名’ drop ‘表名’
truncate清空表,重新创建指定表truncate ‘表名’
shutdown关闭hbase集群(与exit不同)
tools列出hbase所支持的工具
exit退出

scan參數:

名稱描述使用
COLUMN單個列族名稱{COLUMN=>‘XXX’} 或 {COLUMN=>‘XXX:xxx’}
COLUMNS多個列族名稱{COLUMNS=>[‘XXX’, ‘YYY:yyy’ …]}
LIMIT限制查找條數{LIMIT=>1}
TIMERANGE限制時間範圍{TIMERANGE=>[startTimeLong,endTimeLong]}
FILTER過濾部分
PrefixFilterrowkey前綴過濾scan ‘user’,{FILTER=>“PrefixFilter(‘key-prefix’)”}
RowFilter行主鍵過濾scan ‘user’,{FILTER=>“RowFilter(=,‘substring:key001’)”} scan ‘user’,{FILTER=>“RowFilter(>=,‘binary:a’)”}
KeyOnlyFilter只对单元格的键进行过滤和显示,不显示值scan ‘user’,{FILTER => “KeyOnlyFilter()”}
FirstKeyOnlyFilter只扫描显示相同键的第一个单元格,其键值对会显示出来(用來計數效率很高)scan ‘user’,{FILTER => “FirstKeyOnlyFilter()”}
FamilyFilter列族過濾scan ‘user’,FILTER=>“FamilyFilter(=,‘substring:base’)” scan ‘user’,FILTER=>“FamilyFilter(>,‘binary:base’)”
QualifierFilter列名稱過濾scan ‘user’,FILTER=>“QualifierFilter(=,‘substring:name’)” scan ‘user’,FILTER=>“QualifierFilter(<=,‘binary:na’)”
ColumnPrefixFilter对列名称的前缀进行过滤scan ‘user’, FILTER=>“ColumnPrefixFilter(‘na’)”
MultipleColumnPrefixFilter可以指定多个前缀对列名称过滤scan ‘user’,FILTER=>“MultipleColumnPrefixFilter(‘name’, ‘math’)”
ValueFilter值過濾scan ‘user’, FILTER=>“ValueFilter(=,‘substring:test’)” get ‘user’, ‘row-001’, FILTER=>“ValueFilter(=,‘substring:test’)”
SingleColumnValueFilter在指定的列族和列中进行比较的值过滤器scan ‘user’, FILTER=>“SingleColumnValueFilter(‘base’,‘name’,=,‘substring:test’)”
SingleColumnValueExcludeFilter排除匹配成功的值
ColumnCountGetFilter限制每个逻辑行返回键值对的个数scan ‘user’, FILTER=>“ColumnCountGetFilter(2)”
PageFilter对显示结果按行进行分页显示(一頁就是一個行的數據)scan ‘user’, {STARTROW=>‘key001’,ENDROW=>‘key005’, FILTER=>“PageFilter(1)”}
ColumnPaginationFilterColumnPaginationFilter(limit, offset),对一行的所有列分页,只返回[offset,offset+limit] 范围内的列scan “user”, {STARTROW=>‘’, FILTER=>“ColumnPaginationFilter(2, 0)”}

三,Java使用Hbase

3.1 过滤器Filter

第一个参数有很多种取值以匹配多种场景,取值表格如下:

hbase命令java操作描述
<CompareOperator.LESS匹配小宇设定值的值
CompareOperator.LESS_OR_EQUAL匹配小宇或等于设定值的值
CompareOperator.EQUAL匹配等于设定值的值
CompareOperator.NOT_EQUAL匹配与设定值不相等的值
CompareOperator.GREATER_OR_EQUAL匹配大于或等于设定值的值
CompareOperator.GREATER匹配大于设定值的值
CompareOperator.NO_OP排除一切值

比较器有很多子类,他们的功能如下:

比较器描述
BinaryComparator使用Bytes.compareTo()比较当前值与阈值
BinaryPrefixComparator与上面类似,但是是从左端开始前缀匹配
NullComparator不做匹配,只判断当前值是不是null
BitComparator通过BitwiseOp类提供的按位与(AND)、或(OR)、异或(XOR)操作执行位级比较
RegexStringComparator根据一个正则表达式,在实例化这个比较器的时候去匹配表中的数据
SubStringComparator把阈值和表中数据当做String实例,同时通过contains()操作匹配字符串

注意:

  • 最后三种比较器,即BitComparatorRegexStringComparatorSubStringComparator,只能与EQUALNOT_EQUAL运算符一起使用,因为这些比较器compareTo()方法匹配的时候返回结果是0或者1,如果和GREATERLESS运算符搭配使用,就会产生错误的结果。

  • 使用SingleColumnValueFilter的前提是查詢的COLUMN或COLUMNS中,必須包含此列。

    SingleColumnValueFilter(列族,列名, 比較符,比較器【是否忽略不存在此列的記錄(默認false), 是否只獲取最新版本的記錄(默認true)】)

  • 若同時使用多個過濾器,需要使用類FilterList。對於AND操作則傳入參數FilterList.Operator.MUST_PASS_ALL,OR操作則傳入參數FilterList.Operator.MUST_PASS_ONE

//定義過濾器集
FilterList allFilter = new FilterList(FilterList.Operator.MUST_PASS_ALL);
FilterList orFilter = new FilterList(FilterList.Operator.MUST_PASS_ONE);
//定義過濾器
SingleColumnValueFilter filter1 = new SingleColumnValueFilter(x,x,x,x);
SingleColumnValueFilter filter2 = new SingleColumnValueFilter(y,y,y,y);
FirstKeyOnlyFilter firstKeyOnlyFilter = new FirstKeyOnlyFilter();
//條件
orFilter.addFilter(filter1);
orFilter.addFilter(filter2);
allFilter.addFilter(orFilter);
allFilter.addFilter(firstKeyOnlyFilter);

等同於

FILTER=>"( SingleColumnValueFilter(x,x,x,x) OR SingleColumnValueFilter(y,y,y,y) ) AND FirstKeyOnlyFilter()"
			//RowKey 过滤器
            System.out.println("===============================杭键 过滤器================================");
            System.out.println("==================RowKey 过滤器===================");
            Filter filter = new RowFilter(CompareOperator.EQUAL, new SubstringComparator("003"));
            System.out.println(scan(connection, "user", null, null, filter));
            filter = new RowFilter(CompareOperator.LESS, new BinaryComparator(Bytes.toBytes("key003")));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================PrefixFilter 过滤器===================");
            filter = new PrefixFilter(Bytes.toBytes("row"));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================FirstKeyOnlyFilter 过滤器===================");
            filter = new FirstKeyOnlyFilter();
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================InclusiveStopFilter 过滤器===================");
            filter = new InclusiveStopFilter(Bytes.toBytes("key006"));
            System.out.println(scan(connection, "user", "key003", null, filter));

            System.out.println("===============================列 过滤器================================");
            System.out.println("==================FamilyFilter 过滤器===================");
            filter = new FamilyFilter(CompareOperator.EQUAL, new SubstringComparator("score"));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================QualifierFilter 过滤器===================");
            filter = new QualifierFilter(CompareOperator.EQUAL, new SubstringComparator("math"));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================ColumnPrefixFilter 过滤器===================");
            filter = new ColumnPrefixFilter(Bytes.toBytes("age"));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================MultipleColumnPrefixFilter 过滤器===================");
            filter = new MultipleColumnPrefixFilter(Bytes.toArray(Arrays.asList(Bytes.toBytes("age"), Bytes.toBytes("math"))));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("===============================值 过滤器================================");
            System.out.println("==================ValueFilter 过滤器===================");
            filter = new ValueFilter(CompareOperator.GREATER, new BinaryComparator(Bytes.toBytes("test06")));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================SingleColumnValueFilter 过滤器===================");
            filter = new SingleColumnValueFilter(Bytes.toBytes("base"), Bytes.toBytes("name"), CompareOperator.LESS, new BinaryComparator(Bytes.toBytes("test05")));
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("===============================其它 过滤器================================");
            System.out.println("==================PageFilter 过滤器===================");
            filter = new PageFilter(2);
            System.out.println(scan(connection, "user", null, null, filter));

            System.out.println("==================ColumnPaginationFilter 过滤器===================");
            filter = new ColumnPaginationFilter(2, 1);
            System.out.println(scan(connection, "user", "key001", "key002", filter));

注意: 使用過濾器鏈FilterList的時候,要按照過濾的順序進行添加。

3.2 Hbase協處理器

3.2.1 Observer Coprocessor 的类型

RegionObserver

一个 RegionObserver 协处理器允许您观察一个区域上的事件,比如 Get 和 Put 操作。看到RegionObserver。

RegionServerObserver

RegionServerObserver 允许您观察与 RegionServer 操作相关的事件,例如启动、停止或执行合并、提交或回滚。看到RegionServerObserver。

MasterObserver

MasterObserver 允许您观察与 HBase 主节点相关的事件,比如表创建、删除或模式修改。看到MasterObserver。

WalObserver

WalObserver 允许您观察与写入提前写入日志(WAL)相关的事件。看到WALObserver。

3.2.2 配置協處理器

加載協處理器的兩種方式

  1. 配置文件加載(靜態配置)

    启动全局aggregation,能过操纵所有的表上的数据。通过修改hbase-site.xml这个文件。

    RegionObservers

    <property> 
        <name>hbase.coprocessor.region.classes</name> 	                        <value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value> 
    </property>
    

    WALObservers

    <property>
        <name>hbase.coprocessor.wal.classes</name>
        <value>com.lmc.aggregation.MyWALObservers</value> 
    </property>
    

    MasterObservers

    <property>
        <name>hbase.coprocessor.master.classes</name>
        <value>com.lmc.aggregation.MyMasterObservers</value> 
    </property>
    

    如果想同时配置多个协处理器,可以用逗号分隔多个协处理器的类名。

  2. shell加載(動態配置)

    启用表aggregation,只对特定的表生效。通过HBase Shell 来实现

    步驟:

    (1)disable指定表;(disable ‘test’)

    (2)添加aggregation;(alter ‘test’, METHOD => ‘table_att’,‘coprocessor’=>‘/usr/local/hbase-2.4.0/lib/lmc/lmc-hbase-region-eggregate.jar|com.lmc.aggregation.MyRegionObserver1||’)

    (3)重启指定表。(enable ‘test’)

    其他:刪除aggregation(alter ‘test’, METHOD => ‘table_att_unset’,NAME=>‘coprocessor$1’)

​ (4)重啟HBASE服務

alter ‘test’, METHOD => ‘table_att’,‘coprocessor’=>‘①|②|③|④’

參數介紹:

①:协处理器Jar包路径,要保证所有的RegionServer可读取到。也可以是本地路径,不过建议是放在HDFS上。

②:协处理器的完整类名。

③:协处理器优先级,整数表示。可以为空。

④:传递给协处理器的参数,可以为空。

MyRegionObserver1.java

package com.lmc.aggregation;

import org.apache.hadoop.conf.Configuration;
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.client.coprocessor.AggregationClient;
import org.apache.hadoop.hbase.coprocessor.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.wal.WALEdit;

import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.logging.Logger;

/**
 * @ClassName: MyRegionObserver
 * @author: Leemon
 * @Description: TODO
 * @date: 2021/2/26 16:28
 * @version: 1.0 , RegionCoprocessor
 */
public class MyRegionObserver1 implements RegionObserver, RegionCoprocessor {

    private static final Logger LOG = Logger.getLogger(String.valueOf(MyRegionObserver1.class));

    public static Configuration configuration = null;

    private static Table table = null;

    static {
        configuration = HBaseConfiguration.create();
        // 设置配置参数    localhost寫成IP地址時報錯
        configuration.set("hbase.zookeeper.quorum", "localhost");
        configuration.set("hbase.zookeeper.property.clientPort", "2181");
        try {
            Connection connection = getConnection();
            table = connection.getTable(TableName.valueOf("test1"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void postPut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) throws IOException {
        LOG.info("================start to postPut=============");
        //根據rowKey生成put語句
        Put put_0 = new Put(put.getRow());
        put_0.addColumn(Bytes.toBytes("base"), Bytes.toBytes("post"), Bytes.toBytes(("xxx")));
        table.put(put_0);
        table.close();

    }

    @Override
    public void prePut(ObserverContext<RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) throws IOException {
        LOG.info("================start to prePut=============");
        //根據rowKey生成put語句
        Put put_0 = new Put(put.getRow());
        put_0.addColumn(Bytes.toBytes("base"), Bytes.toBytes("pre"), Bytes.toBytes(("xxx")));
        table.put(put_0);
        table.close();
    }

    @Override
    public void preGetOp(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<Cell> result) {
        LOG.info("================start to preGetOp=============");
    }

    @Override
    public void postGetOp(ObserverContext<RegionCoprocessorEnvironment> c, Get get, List<Cell> result) {
        LOG.info("================start to postGetOp=============");
    }

    @Override
    public Optional<RegionObserver> getRegionObserver() {
        return Optional.of(this);
    }

    /**
     * 获取 HBase 的链接对象,接下来使用链接对象对 HBase 进行操作
     * @return
     * @throws IOException
     */
    public static Connection getConnection() throws IOException {

        return ConnectionFactory.createConnection(configuration);
    }

    /**
     * 连接关闭
     */
    public static void close(Connection _zConn) {
        try {
            if (_zConn != null) {
                _zConn.close();
            }
        } catch (IOException e) {
            System.out.println("连接关闭失败!");
            e.printStackTrace();
        }
    }

//    public static void main(String[] args) throws IOException {
//        Put put_0 = new Put(Bytes.toBytes("key001"));
//        put_0.addColumn(Bytes.toBytes("base"), Bytes.toBytes("pre"), Bytes.toBytes(("xxx")));
//        table.put(put_0);
//        table.close();
//    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值