1. 程式人生 > >HBase快照管理(CDH5.8.0)

HBase快照管理(CDH5.8.0)

摘錄自《HBase不睡覺書》。

    HBase提供了快照(snapshot)功能。可以使用快照來將某個表恢復到某個時刻的結構和資料,而且不需要擔心建立和恢復的郭過程會很緩慢,實際上這個速度非常快,往往只有數秒。

    快照並不實際地複製資料,而是儲存一份檔案列表,通過修改錶鏈接的檔案來修改表的資料,所以這樣做有兩個好處:

  1. 速度
  2. 不額外佔用磁碟空間

    HBase預設開啟了快照功能,可以通過設定hbase.snapshot.enabled為false來禁用。

<property>
    <name>hbase.snapshot.enabled</name>
    <value>true</value>
</property>

    下面我們通過實際案例示範快照相關操作:

需求:對某表建立快照,修改表,恢復表到修改之前的狀態

測試前準備 :

1. 建立測試表:create 'test_snapshot','mycf'

2. 插入一條資料:put 'test_snapshot','row1','mycf:name','jack'

測試完整程式碼:

package com.igdata.hbase;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.List;

/**
 * Author: xianghu.wang
 * Date: 2018/9/27
 * Description:
 */
public class SnapShotDemo {
    public static void main(String[] args) {
        // 獲取配置
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", "idayan00:2181");

        Connection conn = null;

        try {
            conn = ConnectionFactory.createConnection(conf);
            TableName tableName = TableName.valueOf("test_snapshot");
            Table table = conn.getTable(tableName);
            Admin admin = conn.getAdmin();
            Scan scan = new Scan();

            // 讀取表中所有資料
            System.out.println("快照前資料: ");
            printRs(table, scan);

            // 獲取當前快照列表
            System.out.println("當前快照列表: ");
            printSnapshotList(admin);

            // 建立快照testSnapshot
            admin.snapshot("testSnapshot", tableName);
            System.out.println("建立快照後快照列表: ");
            printSnapshotList(admin);


            // 修改資料表
            Put put = new Put(Bytes.toBytes("row2"));
            put.addColumn(Bytes.toBytes("mycf"), Bytes.toBytes("name"), Bytes.toBytes("Delete"));
            table.put(put);

            // 修改後表資料
            System.out.println("修改後表資料: ");
            printRs(table, scan);

            // 恢復快照到 testSnapshot
            // 1. 禁用表
            admin.disableTable(tableName);

            // 2.恢復並啟用表
            System.out.println("開始恢復表...");
            while (true) {
                Thread.sleep(1000);
                if (admin.isTableDisabled(tableName)) {
                    admin.restoreSnapshot("testSnapshot");
                    admin.enableTable(tableName);
                    break;
                }
            }
            System.out.println("表恢復完成...");
            // 檢視恢復後的表資料
            System.out.println("恢復後表資料: ");
            printRs(table, scan);

            // 刪除快照
            admin.deleteSnapshot("testSnapshot");

            // 檢視快照列表
            System.out.println("刪除快照後快照列表:");
            printSnapshotList(admin);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 獲取快照列表
     *
     * @param admin
     */
    public static void printSnapshotList(Admin admin) {
        List<HBaseProtos.SnapshotDescription> SnapshotDescription = null;
        try {
            SnapshotDescription = admin.listSnapshots();
            if (SnapshotDescription == null || SnapshotDescription.size() < 1) {
                System.out.println("當前表沒有快照...");
                return;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        int snapShotCount = 0;
        for (HBaseProtos.SnapshotDescription snapshotDescription : SnapshotDescription) {
            System.out.println(String.format("快照%s :", ++snapShotCount) + snapshotDescription.getName());
        }
        System.out.println();
    }

    /**
     * 打印表中所有資料
     *
     * @param table
     * @param scan
     */
    public static void printRs(Table table, Scan scan) {
        ResultScanner rsBefore = null;
        try {
            rsBefore = table.getScanner(scan);
        } catch (IOException e) {
            e.printStackTrace();
        }
        for (Result r : rsBefore) {
            System.out.println(r);
        }
        System.out.println();
    }
}