HBaseのインストールと使用

記事の著者:foochane 

オリジナルリンク:https://foochane.cn/article/2019062801.html

1つのHBaseの基本的な導入

Hbaseこれは、リアルタイムのランダム読み取りを提供し、データを書き込むことができ、分散データベースです。

Hbaseそしてmysqloralcedb2sqlserverであり、他の異なるリレーショナルデータベース、NoSQLデータベース(非リレーショナルデータベース)、および以下の特徴を有します。

  • Hbaseテーブルモデルと異なるリレーショナルデータベーステーブルモデル:
  • Hbaseテーブルには、固定フィールド定義がありません。
  • Hbaseテーブルの各行は、格納された一部であるkey-value
  • Hbase表家族分割列を有し、ユーザがKVに挿入されるグループ列を指定することができ
  • Hbase物理ストレージ内のテーブル、列グループに応じて分割され、データの異なる列のグループは、異なるファイルに格納しなければなりません
  • Hbaseテーブルの各行は、キーの列が固定されており、キーの列は、テーブルの各行は繰り返すことができません
  • Hbaseデータは、回線キーが含まれている含まれkey、含まれているvalue、すべてのbyte[ ]種類の、hbaseそれはユーザーのデータ型の維持に責任を負いません
  • Hbase取引のための悪いサポート

HBASE(他のデータベースのNoSQLに比べmongodb、、 、redis 特性:ので、格納されたテーブルのデータファイルシステムでは、記憶容量が直線的に拡張することができ、データ・ストレージの高い安全性と信頼性!cassendrahazelcast
HbaseHDFS

2 HBaseのテーブル構造

rowKey:行キー base_info extra_info
001 名前:ZS、年齢:22、性別:男性 hobbiy:読み取り、ADDR:北京
002 名前:laowang、性別:男性

mysqlの差のようなリレーショナルデータベースとHBaseの巨大なテーブルモデルテーブルモデル

HBaseのテーブルモデルは以下のとおりです。ラインの概念であるが、フィールドの概念はありません

ラインデポジットキーで、キーと値のペアの各行は、広く変化させることができる、キーと値のペアです。

重要なモデルテーブルのHBase

  • テーブル名を持つテーブル
  • テーブルは、列のグループの複数の(異なる列グループに格納された異なるデータファイル)に分けることができます
  • テーブルの各行は、「キーのrowKeyを線」があり、OKキーがテーブルに繰り返しません
  • 各対のテーブルがkey-value呼び出されcell
  • HBaseのデータは、歴史(設定することができるバージョンの数の歴史)の複数のバージョンを保存し、最新バージョンのデフォルトを取ることができます
  • 大量のデータテーブル全体ので、領域を複数に横方向に切断される(のrowKey範囲によって識別される)だけでなく、別のファイルに格納されたデータの異なる領域

HBaseのデータが格納されている順番に挿入します。

  • 最初の行であろうソートキー
  • 家族内のKV同じラインがk、その後、ソート、列でソートされます

HBaseのテーブルデータタイプ:

HBaseの唯一の[]、バイトサポートし、ここでのバイトは[]が含ま:のrowKey、キー、値、列ファミリ名、テーブル名を。
テーブルは、異なる領域に分割されています。

3 HBaseの作業メカニズム

作業メカニズムのHBaseの全体的な概略図

HBaseの分散システムは、2本のロールで構成されてい

  • 行政の役割:HMASTER(通常は2、1アクティブ、1つのスタンバイ)
  • データノードの役割:HRegionServer(一緒に、複数の、およびデータノード)

Hbaseデータ処理をしない、それは必要としないyarnyarn計算されたコピーのMapReduceで、Hbaseデータ管理のための唯一の責任があります

4 HBaseのインストール

4.1インストールの準備

まず、でなければならないがHDFS、クラスター、および実行されている; 話すべき一緒に第二に、あなたはまた、必要なクラスタを、そして実行しているので、インストールは最初にインストールする必要がありそれはすでに以前にインストールされています。その後、インストールHbaseregionserverhdfsdatanode
zookeeperHbasezookeeperzookeeper
Hbase

4.2ノード配置

次のように各ノードの役割が割り当てられます。

ノード インストールサービス
マスター 名前ノードデータノードリージョンサーバーHMASTER飼育係
Slave01 データノードのリージョンサーバーの飼育係
Slave02 データノードのリージョンサーバーの飼育係

4.3インストールのHBase

解凍hbaseインストールパッケージをhbase-2.0.5-bin.tar.gz

修正hbase-env.sh

export JAVA_HOME=/usr/local/bigdata/java/jdk1.8.0_211

# 不启动hbase自带的zookeeper,我们自己已经装了
export HBASE_MANAGES_ZK=false

HBaseの-site.xmlのを修正

<configuration>
    <!-- 指定hbase在HDFS上存储的路径 -->
    <property>
        <name>hbase.rootdir</name>
        <value>hdfs://Master:9000/hbase</value>
    </property>
    <!-- 指定hbase是分布式的 -->
    <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
    </property>
    <!-- 指定zk的地址,多个用“,”分割 -->
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>Master:2181,Slave01:2181,Slave02:2181</value>
    </property>
</configuration>

regionserversを変更

Master
Slave01
Slave02

3つのノードに編集した後に、インストールフォルダ/usr/local/bigdata/ディレクトリ

6のHBaseクラスタを起動

チェックhdfszookeeper通常、起動するかどうかを
マスター:

hadoop@Master:~$ jps
4918 DataNode
2744 QuorumPeerMain
4748 NameNode
9949 Jps
5167 SecondaryNameNode
hadoop@Master:~$ /usr/local/bigdata/zookeeper-3.4.6/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/bigdata/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower

Slave01:

hadoop@Slave1:~$ jps
3235 QuorumPeerMain
3779 DataNode
5546 Jps
hadoop@Slave1:~$  /usr/local/bigdata/zookeeper-3.4.6/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/bigdata/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: leader

Slave02:

hadoop@Slave2:~$ jps
11958 DataNode
13656 Jps
11390 QuorumPeerMain
hadoop@Slave2:~$  /usr/local/bigdata/zookeeper-3.4.6/bin/zkServer.sh status
JMX enabled by default
Using config: /usr/local/bigdata/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: follower

そして、実行start-hbase.sh

$ bin/start-hbase.sh

上記のコマンドは、コンフィギュレーション・ファイルを開始しますregionserver手動で使用することができたのいずれかを開始したい場合は、追加するすべてのマシンのを:

$ bin/hbase-daemon.sh start regionserver

起動後、マスタ上で開始HRegionServerし、HMaster2つのサービス、Slave01およびSlave02開始しますHMasterサービスを。

高可用性Hbaseクラスタ構成は、二つのなければならないmasterの一方activeの状態にあるstandby監視用の状態regionserver

私たちは、その後で他の二つのマシンのいずれかから再起動することができますHRegionServerサービス。

$ bin/hbase-daemon.sh start master

新しいマスターを開始しますこれはバックアップです

7コマンドラインクライアントはHBaseのを開始します

コマンドを使用します。hbase shell

bin/hbase shell
Hbase> list     // 查看表
Hbase> status   // 查看集群状态
Hbase> version  // 查看集群版本
問題
ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not running yet
        at org.apache.hadoop.hbase.master.HMaster.checkServiceStarted(HMaster.java:2932)
        at org.apache.hadoop.hbase.master.MasterRpcServices.isMasterRunning(MasterRpcServices.java:1084)
        at org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos$MasterService$2.callBlockingMethod(MasterProtos.java)
        at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:413)
        at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:130)
        at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:324)
        at org.apache.hadoop.hbase.ipc.RpcExecutor$Handler.run(RpcExecutor.java:304)
解きます
$ hdfs dfsadmin -safemode leave

8 HBaseのコマンドラインクライアントの操作

表8.1ビルド

create 't_user_info','base_info','extra_info'
         表名      列族名   列族名
         

8.2挿入データ:

hbase(main):011:0> put 't_user_info','001','base_info:username','zhangsan'
0 row(s) in 0.2420 seconds

hbase(main):012:0> put 't_user_info','001','base_info:age','18'
0 row(s) in 0.0140 seconds

hbase(main):013:0> put 't_user_info','001','base_info:sex','female'
0 row(s) in 0.0070 seconds

hbase(main):014:0> put 't_user_info','001','extra_info:career','it'
0 row(s) in 0.0090 seconds

hbase(main):015:0> put 't_user_info','002','extra_info:career','actoress'
0 row(s) in 0.0090 seconds

hbase(main):016:0> put 't_user_info','002','base_info:username','liuyifei'
0 row(s) in 0.0060 seconds

8.3データを照会する方法:スキャンスキャン

hbase(main):017:0> scan 't_user_info'
ROW                               COLUMN+CELL                                                                                     
 001                              column=base_info:age, timestamp=1496567924507, value=18                                         
 001                              column=base_info:sex, timestamp=1496567934669, value=female                                     
 001                              column=base_info:username, timestamp=1496567889554, value=zhangsan                              
 001                              column=extra_info:career, timestamp=1496567963992, value=it                                     
 002                              column=base_info:username, timestamp=1496568034187, value=liuyifei                              
 002                              column=extra_info:career, timestamp=1496568008631, value=actoress                               
2 row(s) in 0.0420 seconds

8.4クエリデータは、第二の方法:単一の行を取得します

hbase(main):020:0> get 't_user_info','001'
COLUMN                            CELL                                                                                            
 base_info:age                    timestamp=1496568160192, value=19                                                               
 base_info:sex                    timestamp=1496567934669, value=female                                                           
 base_info:username               timestamp=1496567889554, value=zhangsan                                                         
 extra_info:career                timestamp=1496567963992, value=it                                                               
4 row(s) in 0.0770 seconds

8.5 KVのデータを削除するには

hbase(main):021:0> delete 't_user_info','001','base_info:sex'
0 row(s) in 0.0390 seconds

删除整行数据:
hbase(main):024:0> deleteall 't_user_info','001'
0 row(s) in 0.0090 seconds

hbase(main):025:0> get 't_user_info','001'
COLUMN                            CELL                                                                                            
0 row(s) in 0.0110 seconds

3.4.1.6.    删除整个表:
hbase(main):028:0> disable 't_user_info'
0 row(s) in 2.3640 seconds

hbase(main):029:0> drop 't_user_info'
0 row(s) in 1.2950 seconds

hbase(main):030:0> list
TABLE                                                                                                                             
0 row(s) in 0.0130 seconds

=> []

8.6 HBaseの重要な特徴 - ソート特性(行キー)

挿入されたhbaseデータに、hbase自動的にソートストレージ:
照合:最初のルック行キー、カラム(見て、次に、列グループ名を見てkey)名前、辞書

クエリの効率でこの機能のHBaseのは素晴らしい関係を持っています

例えば:名前、住所、年齢、職業、その他の情報を格納するユーザー情報に使用されるテーブル、....
その後、多くの場合、ビジネス・システムを必要とする:
すべてのユーザーの地域を照会するには
、多くの場合、クエリ省を指定する必要がありますすべてのユーザーの姓

アイデア:ユーザーが同じ保存することができた場合にhbase連続して格納ストレージファイルを、そして継続的に保存された同じ名前のユーザーの同郷することができ、その後、2つのクエリ要求の効率が向上します!

プラクティス:クエリに対する戦いrowkeyの中

9 HBaseのクライアントAPIの操作

9.1 DDL操作

コードの流れ:

  • 接続を作成します。Connection conn = ConnectionFactory.createConnection(conf);
  • 表マネージャー:DDLを取得するための演算子:adminAdmin admin = conn.getAdmin();
  • APIテーブルマネージャを使用すると、テーブルを構築し、テーブルを削除し、テーブル定義を変更するには:admin.createTable(HTableDescriptor descriptor);
@Before
public void getConn() throws Exception{
    // 构建一个连接对象
    Configuration conf = HBaseConfiguration.create(); // 会自动加载hbase-site.xml
    conf.set("hbase.zookeeper.quorum", "192.168.233.200:2181,192.168.233.201:2181,192.168.233.202:2181");
    
    conn = ConnectionFactory.createConnection(conf);
}


/**
 * DDL
 * @throws Exception 
 */
@Test
public void testCreateTable() throws Exception{

    // 从连接中构造一个DDL操作器
    Admin admin = conn.getAdmin();
    
    // 创建一个表定义描述对象
    HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("user_info"));
    
    // 创建列族定义描述对象
    HColumnDescriptor hColumnDescriptor_1 = new HColumnDescriptor("base_info");
    hColumnDescriptor_1.setMaxVersions(3); // 设置该列族中存储数据的最大版本数,默认是1
    
    HColumnDescriptor hColumnDescriptor_2 = new HColumnDescriptor("extra_info");
    
    // 将列族定义信息对象放入表定义对象中
    hTableDescriptor.addFamily(hColumnDescriptor_1);
    hTableDescriptor.addFamily(hColumnDescriptor_2);
    
    
    // 用ddl操作器对象:admin 来建表
    admin.createTable(hTableDescriptor);
    
    // 关闭连接
    admin.close();
    conn.close();
    
}


/**
 * 删除表
 * @throws Exception 
 */
@Test
public void testDropTable() throws Exception{
    
    Admin admin = conn.getAdmin();
    
    // 停用表
    admin.disableTable(TableName.valueOf("user_info"));
    // 删除表
    admin.deleteTable(TableName.valueOf("user_info"));
    
    
    admin.close();
    conn.close();
}

// 修改表定义--添加一个列族
@Test
public void testAlterTable() throws Exception{
    
    Admin admin = conn.getAdmin();
    
    // 取出旧的表定义信息
    HTableDescriptor tableDescriptor = admin.getTableDescriptor(TableName.valueOf("user_info"));
    
    
    // 新构造一个列族定义
    HColumnDescriptor hColumnDescriptor = new HColumnDescriptor("other_info");
    hColumnDescriptor.setBloomFilterType(BloomType.ROWCOL); // 设置该列族的布隆过滤器类型
    
    // 将列族定义添加到表定义对象中
    tableDescriptor.addFamily(hColumnDescriptor);
    
    
    // 将修改过的表定义交给admin去提交
    admin.modifyTable(TableName.valueOf("user_info"), tableDescriptor);
    
    
    admin.close();
    conn.close();
    
}

9.2 DML操作

HBaseCRUD

    Connection conn = null;
    
    @Before
    public void getConn() throws Exception{
        // 构建一个连接对象
        Configuration conf = HBaseConfiguration.create(); // 会自动加载hbase-site.xml
        conf.set("hbase.zookeeper.quorum", "Master:2181,Slave01:2181,Slave02:2181");
        
        conn = ConnectionFactory.createConnection(conf);
    }
    
    
    /**
     * 增
     * 改:put来覆盖
     * @throws Exception 
     */
    @Test
    public void testPut() throws Exception{
        
        // 获取一个操作指定表的table对象,进行DML操作
        Table table = conn.getTable(TableName.valueOf("user_info"));
        
        // 构造要插入的数据为一个Put类型(一个put对象只能对应一个rowkey)的对象
        Put put = new Put(Bytes.toBytes("001"));
        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("张三"));
        put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes("18"));
        put.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"), Bytes.toBytes("北京"));
        
        
        Put put2 = new Put(Bytes.toBytes("002"));
        put2.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("李四"));
        put2.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes("28"));
        put2.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"), Bytes.toBytes("上海"));
    
        
        ArrayList<Put> puts = new ArrayList<>();
        puts.add(put);
        puts.add(put2);
        
        
        // 插进去
        table.put(puts);
        
        table.close();
        conn.close();
        
    }
    
    
    /**
     * 循环插入大量数据
     * @throws Exception 
     */
    @Test
    public void testManyPuts() throws Exception{
        
        Table table = conn.getTable(TableName.valueOf("user_info"));
        ArrayList<Put> puts = new ArrayList<>();
        
        for(int i=0;i<100000;i++){
            Put put = new Put(Bytes.toBytes(""+i));
            put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("username"), Bytes.toBytes("张三"+i));
            put.addColumn(Bytes.toBytes("base_info"), Bytes.toBytes("age"), Bytes.toBytes((18+i)+""));
            put.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"), Bytes.toBytes("北京"));
            
            puts.add(put);
        }
        
        table.put(puts);
        
    }
    
    /**
     * 删
     * @throws Exception 
     */
    @Test
    public void testDelete() throws Exception{
        Table table = conn.getTable(TableName.valueOf("user_info"));
        
        // 构造一个对象封装要删除的数据信息
        Delete delete1 = new Delete(Bytes.toBytes("001"));
        
        Delete delete2 = new Delete(Bytes.toBytes("002"));
        delete2.addColumn(Bytes.toBytes("extra_info"), Bytes.toBytes("addr"));
        
        ArrayList<Delete> dels = new ArrayList<>();
        dels.add(delete1);
        dels.add(delete2);
        
        table.delete(dels);
        
        
        table.close();
        conn.close();
    }
    
    /**
     * 查
     * @throws Exception 
     */
    @Test
    public void testGet() throws Exception{
        
        Table table = conn.getTable(TableName.valueOf("user_info"));
        
        Get get = new Get("002".getBytes());
        
        Result result = table.get(get);
        
        // 从结果中取用户指定的某个key的value
        byte[] value = result.getValue("base_info".getBytes(), "age".getBytes());
        System.out.println(new String(value));
        
        System.out.println("-------------------------");
        
        // 遍历整行结果中的所有kv单元格
        CellScanner cellScanner = result.cellScanner();
        while(cellScanner.advance()){
            Cell cell = cellScanner.current();
            
            byte[] rowArray = cell.getRowArray();  //本kv所属的行键的字节数组
            byte[] familyArray = cell.getFamilyArray();  //列族名的字节数组
            byte[] qualifierArray = cell.getQualifierArray();  //列名的字节数据
            byte[] valueArray = cell.getValueArray(); // value的字节数组
            
            System.out.println("行键: "+new String(rowArray,cell.getRowOffset(),cell.getRowLength()));
            System.out.println("列族名: "+new String(familyArray,cell.getFamilyOffset(),cell.getFamilyLength()));
            System.out.println("列名: "+new String(qualifierArray,cell.getQualifierOffset(),cell.getQualifierLength()));
            System.out.println("value: "+new String(valueArray,cell.getValueOffset(),cell.getValueLength()));
            
        }
        
        table.close();
        conn.close();
        
    }
    
    
    /**
     * 按行键范围查询数据
     * @throws Exception 
     */
    @Test
    public void testScan() throws Exception{
        
        Table table = conn.getTable(TableName.valueOf("user_info"));
        
        // 包含起始行键,不包含结束行键,但是如果真的想查询出末尾的那个行键,那么,可以在末尾行键上拼接一个不可见的字节(\000)
        Scan scan = new Scan("10".getBytes(), "10000\001".getBytes());
        
        ResultScanner scanner = table.getScanner(scan);
        
        Iterator<Result> iterator = scanner.iterator();
        
        while(iterator.hasNext()){
            
            Result result = iterator.next();
            // 遍历整行结果中的所有kv单元格
            CellScanner cellScanner = result.cellScanner();
            while(cellScanner.advance()){
                Cell cell = cellScanner.current();
                
                byte[] rowArray = cell.getRowArray();  //本kv所属的行键的字节数组
                byte[] familyArray = cell.getFamilyArray();  //列族名的字节数组
                byte[] qualifierArray = cell.getQualifierArray();  //列名的字节数据
                byte[] valueArray = cell.getValueArray(); // value的字节数组
                
                System.out.println("行键: "+new String(rowArray,cell.getRowOffset(),cell.getRowLength()));
                System.out.println("列族名: "+new String(familyArray,cell.getFamilyOffset(),cell.getFamilyLength()));
                System.out.println("列名: "+new String(qualifierArray,cell.getQualifierOffset(),cell.getQualifierLength()));
                System.out.println("value: "+new String(valueArray,cell.getValueOffset(),cell.getValueLength()));
            }
            System.out.println("----------------------");
        }
    }
    
    @Test
    public void test(){
        String a = "000";
        String b = "000\0";
        
        System.out.println(a);
        System.out.println(b);
        
        
        byte[] bytes = a.getBytes();
        byte[] bytes2 = b.getBytes();
        
        System.out.println("");
        
    }
    
    

おすすめ

転載: www.cnblogs.com/foochane/p/11110567.html