ApacheHbaseとJavaAPIの基本概念

1. ApacheHbaseの基本的な概要

Apache Hbaseは、Hadoopベースのデータベースです。信頼性が高く、マルチバージョンであり、構造化されたビッグデータのストレージに適した分散型です。ApacheHbaseは、列ストレージに基づくフィリピンのリレーショナルデータベースであるGoogleBigTableのオープンソース実装です。

(1)行ストレージと行ストレージの違い

列ストレージと行ストレージは、データサブストレージメディアのストレージ量を指し
ます**・**リレーショナルデータベース(行ストレージ):Oracle、mysqlなど
**・**非リレーショナルデータベース(列ストレージ): Hbase、Redis
ここに画像の説明を挿入します

(2)Hbaseデータモデルとコンセプト

ここに画像の説明を挿入します
(1)主キーrowkey:データの一意の識別子を取得します。データは繰り返すことができず、辞書の順序に従って自動的にソートされ、最下位のストレージはバイト[]です。
(2)列ファミリー:複数の列のコレクション。通常、類似の機能または類似のビジネスのグループが列クラスターに格納されます。
(3)セル:行キー+列ファミリー+セルを検索する列。セルには複数のバージョンがあり、デフォルトは1つです。
(4)複数のバージョン:セルでは、1つのデータバージョンを読み取ることができます。
(5)バージョン番号:システムの現在のタイムスタンプ。デフォルトでは、最新のタイムスタンプを持つセルデータがユーザーに返されます。
(6)列:特定のカテゴリのデータを格納するために使用される列クラスター内のフィールド。

(3)Hbaseの機能:

(1)大:テーブルには、数百億の行と数百万の列を含めることができます。
(2)列指向:リスト指向(列クラスター)のストレージおよび制御のアクセス許可
(3)スパース構造:空(NULL)列の場合、ストレージスペースを占有しないため、テーブルを非常にスパースに設計できます。
(4)モードなし:各行には、ソート可能な主キーと任意の数の列があります。列は、必要に応じて動的に追加できます。同じテーブル内の異なる行は、完全に異なる列を持つことができます。
(5)データの複数のバージョン:各セルのデータには複数のバージョンを含めることができます。デフォルトでは、バージョン番号が自動的に割り当てられ、バージョンはセルが挿入されたときのタイムスタンプです。
(6)単一データ型:Hbaseのデータは、あらゆるタイプのデータを格納できるバイト[]として最下層に格納されます。

(4)詳細なHbaseアーキテクチャと完全に分散された構造

完全に分散された構造:
ここに画像の説明を挿入します
zookeeperはhbaseクラスターへの入り口として機能します(後のjava apiはhbaseへの接続方法から見ることができます)

hbaseアーキテクチャの詳細な説明:
ここに画像の説明を挿入します
HBaseの各テーブルは、rowKeyによって特定の範囲に従って複数のサブテーブル(HRegion)に分割されます。デフォルトでは、256Mを超えるHRegionは2つに分割されます。このプロセスはHRegionServerとHRegionによって管理されます。割り当てられます。HMasterによって管理されます。

HMasterの役割:

(1)HRegionをHRegionServerに割り当てます
(2)HRegionServerの負荷分散を担当します
(3)無効なHRegionServerを見つけて再配布します
(4)HDFSでのガベージファイルの収集
(5)プロセススキーマの更新要求

HRegionServerの役割:

(1)HMasterによって割り当てられたHRegionを維持し、これらのHRegionのIO要求を処理します。
(2)操作中に大きくなりすぎたHRegionをセグメント化する責任があります。

HBase上のデータへのクライアントアクセスはHMasterの参加を必要とせず、ZooKeeperとHRegionServerへのアクセス、HRegionServerへのデータの読み取りと書き込みアクセス、HMasterはテーブルとリージョンのメタデータ情報、およびテーブルのメタデータ情報のみを維持することがわかります。 ZooKeeperに保存されています。負荷は非常に低くなっています。HRegionServerがサブテーブルにアクセスすると、HRegionオブジェクトが作成され、テーブルの列クラスターごとにHStoreオブジェクトが作成されます。各HStoreにはMemStoreとそれに対応する0個以上のStoreFileがあり、各StoreFileは1つに対応します。 HFile、HFileは実際のストレージファイルです。したがって、HRegionの列クラスターと同じ数のストアがあります。1つのHRegionServerには、複数のHRegionと1つのHLogがあります。

HRegion

テーブルは行方向で複数のHRegionに分割されます。HRegionはHBaseの分散ストレージと負荷分散の最小単位です。つまり、異なるHRegionを異なるHRegionServerに配置できますが、同じHRegionが複数のOnHRegionServerに分割されることはありません。HRegionはサイズで分割されます。通常、各テーブルには1つのHRegionしかありません。データがテーブルに継続的に挿入されると、HRegionは増加し続け
ます。HRegionの特定の列クラスターがしきい値(デフォルトは256M)に達すると、2つの新しいHRegionに分割されます。 。

1、<表名,StartRowKey, 创建时间>
2、由目录表(-ROOT-和.META.)记录该Region的EndRowKey

HRegion定位:HRegion被分配给哪个HRegionServer是完全动态的,所以需要机制来定位HRegion具体在哪个HRegionServer,HBase使用三层结构来定位HRegion:
    1、通过zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一个region。
    2、通过-ROOT-表查找.META.表的第一个表中相应的HRegion位置。其实-ROOT-表是.META.表的第一个region;
         .META.表中的每一个Region在-ROOT-表中都是一行记录。
    3、通过.META.表找到所要的用户表HRegion的位置。用户表的每个HRegion在.META.表中都是一行记录。

    -ROOT-表永远不会被分隔为多个HRegion,保证了最多需要三次跳转,就能定位到任意的region。Client会将查询的位置信息保存缓存起来,缓存不会主动失效,
    因此如果Client上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的HRegion,其中三次用来发现缓存失效,另外三次用来获取位置信息。

HStoreHBase
内のデータアクセスを持つ1つ以上の少なくともHStoreで構成される各HRegionHStoreは、内部にHStoreを作成します。つまり、各ColumnFamilyはHStoreを構築します。複数のColumnFamilyがある場合は、複数のHStoreがあります。ストアは、MemStoreと0個以上のStoreFileで構成されます。HBaseは、ストアのサイズを使用して、HRegionを分割するかどうかを決定します。

MemStore
MemStoreはメモリに保存され、変更されたデータはkeyValuesです。MemStoreのサイズがしきい値(デフォルトでは64MB)に達すると、MemStoreがファイルにフラッシュされます。つまり、スナップショットが生成されます。現在、HBaseには、MemStoreのフラッシュ操作を担当するスレッドがあります。

StoreFile
  MemStoreメモリ内のデータはStoreFileとしてファイルに書き込まれ、StoreFileの最下層はHFile形式で保存されます。

HLog
  HLog(WALログ):WALは、ディザスタリカバリに使用される先行書き込みログを意味します。HLogはすべてのデータ変更を記録します。リージョンサーバーがダウンすると、ログからリカバリできます。


Hbase障害回復のプロセスを簡単に説明します。Hmasterは、一部のHregionServerが使用できないことを検出して障害回復を開始し、障害が発生したHregionServerのHlogを取得し、各HRegion書き込みコマンドを分離し、Hregionを再配布し、HregionServer内のHRegionデータを復元し、分離を実行します。 HRegion書き込みコマンドはMemStoreを復元し、永続化されたデータはHDFSから直接取得できます。

)二)Hbase Java API

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-common</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-protocol</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-server</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-common</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-protocol</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-server</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
package com.learn;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

public class HbaseAPI {
    private Admin admin;
    private Connection connection;

    @Before
    public void doBefore() throws IOException {
        Configuration configuration = HBaseConfiguration.create();
        configuration.set(HConstants.ZOOKEEPER_QUORUM,"192.168.139.156:2181");
        connection = ConnectionFactory.createConnection(configuration);
        admin = connection.getAdmin();
    }

    @Test
    public void testCreateNameSpace() throws IOException {
        NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create("gaoj").addConfiguration("author", "gaojian").build();
        admin.createNamespace(namespaceDescriptor);
    }

    @Test
    public void testCreateTable() throws IOException {
        HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("gaoj:t_order"));
        HColumnDescriptor cf1 = new HColumnDescriptor("cf1");
        cf1.setMaxVersions(3);
        HColumnDescriptor cf2 = new HColumnDescriptor("cf2");
        cf2.setTimeToLive(1800);
        hTableDescriptor.addFamily(cf1);
        hTableDescriptor.addFamily(cf2);
        admin.createTable(hTableDescriptor);
    }

    @Test
    public void testInsert() throws IOException {
        Table table = connection.getTable(TableName.valueOf("gaoj:t_order"));
        Put put = new Put(Bytes.toBytes("order101"));
        put.addColumn(Bytes.toBytes("cf1"),Bytes.toBytes("count"),Bytes.toBytes(123));
        table.put(put);
    }

    @Test
    public void testSelect() throws IOException {
        Table table = connection.getTable(TableName.valueOf("gaoj:t_order"));
        Get get = new Get(Bytes.toBytes("order101"));
        Result result = table.get(get);
        String name = Bytes.toString(result.getValue(Bytes.toBytes("cf1"), Bytes.toBytes("name")));
        System.out.println(name);
    }

    @Test
    public void testDelete() throws IOException {
        Table table = connection.getTable(TableName.valueOf("gaoj:t_order"));
        Delete delete = new Delete(Bytes.toBytes("order101"));
        ArrayList<Delete> list = new ArrayList<Delete>();
        list.add(delete);
        table.delete(list);
    }

    @Test
    public void testScan() throws IOException {
        Table table = connection.getTable(TableName.valueOf("gaoj:t_order"));
        Scan scan = new Scan();
        ResultScanner scanner = table.getScanner(scan);
        Iterator<Result> iterator = scanner.iterator();
        while (iterator.hasNext()){
            Result next = iterator.next();
            String row = Bytes.toString(next.getRow());
            String name = Bytes.toString(next.getValue(Bytes.toBytes("cf1"), Bytes.toBytes("name")));
            System.out.println(row + "*" + name);
        }
    }
    @After
    public void doAfter() throws IOException {
        if(admin != null){
            admin.close();
        }
        if(connection != null){
            connection.close();
        }
    }
}

上記のAPIは、データの追加、削除、変更、およびチェックを実装します。Hbaseに関しては、APIの使用をより細かく制御できます。学習プロセス中に、helpコマンドを使用して学習を支援できます。

おすすめ

転載: blog.csdn.net/qq_44962429/article/details/108702353