1. 程式人生 > >HBase總結(1)-- 資料插入與Put物件

HBase總結(1)-- 資料插入與Put物件

一、介紹

HBase的客戶端包中集中了CURD操作,使用者可以通過其中不同種類的API盡心CURD操作。HBase資料插入使用Put物件,Put物件在進行資料插入時,首先會想Hbase叢集傳送一個RPC請求,得到響應後將Put類中的資料通過序列化的方式傳給HBase叢集,叢集節點拿到資料後進行新增功能。

二、資料插入詳解

HBase客戶端擁有多重方式進行資料插入,通過調整不同的屬性從而實現不同插入方式。

1、單行插入:put(Put p)

單行插入即每一次插入一行資料

public void put(String tableName,String rowKey,String family,String column,String value)
	{
		Configuration conf=init();
		try {
			HTable table=new HTable(conf,TableName.valueOf(tableName));
			HBaseAdmin admin=new HBaseAdmin(conf);
			//判斷表是否存在,如果不存在進行建立
			if(!admin.tableExists(Bytes.toBytes(tableName)))
			{
				HTableDescriptor tableDescriptor=new HTableDescriptor(Bytes.toBytes(tableName));
				HColumnDescriptor columnDescriptor=new HColumnDescriptor(Bytes.toBytes(family));
				tableDescriptor.addFamily(columnDescriptor);
				admin.createTable(tableDescriptor);
			}
			table.setAutoFlush(true);
			//進行資料插入
			Put put=new Put(Bytes.toBytes(rowKey));
			put.add(Bytes.toBytes(family),Bytes.toBytes(column),Bytes.toBytes(value));
			table.put(put);
			table.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

HTable.put(Put p)方法想表中新增一行資料。在此過程中會發送一次RPC操作進行請求,並將Put中的資料序列化以後傳送給相應的伺服器進行資料插入。

2、批量插入:put(List<Put> list)

批量插入中生成一個List容器,然後將多行資料全部轉載到該容器中,然後通過客戶端的程式碼一次將多行資料進行提交

public void putList(String tableName,String[] rowKeys,String[] families,String[] columns,String[] values)
	{
		Configuration conf=init();
		try {
			HBaseAdmin admin=new HBaseAdmin(conf);
			HTable table=new HTable(conf,tableName.valueOf(tableName));
			int length=rowKeys.length;
			List<Put> putList=new ArrayList<>();
			if(!admin.tableExists(Bytes.toBytes(tableName)))
			{
				System.err.println("the "+tableName+" is not exist");
				System.exit(1);
			}
			for(int i=0;i<length;i++)
			{
				Put put=new Put(Bytes.toBytes(rowKeys[i]));
				put.add(Bytes.toBytes(families[i]),Bytes.toBytes(columns[i]),Bytes.toBytes(values[i]));
				putList.add(put);
			}
			table.put(putList);
			table.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
多行插入的本質就是對List容器中的所有物件進行迭代,然後通過 HTable.put(Put p)方法進行多次插入操作。這樣的批量操作將會發送多次PRC請求。

3、檢查並寫入:checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put)

該方法提供了一種原子性操作,即該操作如果失敗,則操作中的所有更改都失效。該函式在多個客戶端對同一個資料進行修改時將會提供較高的效率。

public void checkAndPut(String tableName,String row,String family,String column,String value)
	{
		Configuration conf=init();
		try {
			HBaseAdmin admin=new HBaseAdmin(conf);
			if(!admin.tableExists(Bytes.toBytes(tableName)))
			{
				System.err.println("the table "+tableName+" is not exist");
				System.exit(1);
			}
			HTable table=new HTable(conf, TableName.valueOf(tableName));
			Put put=new Put(Bytes.toBytes(row));
			put.addColumn(Bytes.toBytes(family),Bytes.toBytes(column),Bytes.toBytes(value));
			table.checkAndPut(Bytes.toBytes(row),Bytes.toBytes(family),Bytes.toBytes(column),null, put);
			table.flushCommits();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
上述程式碼實現了只有在寫入位置的值為Null的時候將才會將資料寫入到資料庫中。

注意:需要注意的時,checkAndPut方法以及類似的方法(統稱為compact and set(CAS)操作)都只能對一行進行原子性操作。當checkAndPut函式中的引數row和引數put中的row不相同時,即該操作已經不再同一行中時,則會丟擲異常。

org.apache.hadoop.hbase.DoNotRetryIOException: org.apache.hadoop.hbase.DoNotRetryIOException: Action's getRow must match the passed row
	at org.apache.hadoop.hbase.regionserver.HRegion.checkAndMutate(HRegion.java:3276)
	at org.apache.hadoop.hbase.regionserver.RSRpcServices.mutate(RSRpcServices.java:2102)
	at org.apache.hadoop.hbase.protobuf.generated.ClientProtos$ClientService$2.callBlockingMethod(ClientProtos.java:32203)
	at org.apache.hadoop.hbase.ipc.RpcServer.call(RpcServer.java:2114)
	at org.apache.hadoop.hbase.ipc.CallRunner.run(CallRunner.java:101)
	at org.apache.hadoop.hbase.ipc.RpcExecutor.consumerLoop(RpcExecutor.java:130)
	at org.apache.hadoop.hbase.ipc.RpcExecutor$1.run(RpcExecutor.java:107)
	at java.lang.Thread.run(Thread.java:745)

4、快取塊操作

2方法雖然提供了批量操作,但實際的RPC請求次數沒有任何的減少,因此put(List)和多次put(Put p)方法理論上的速率是相同的。而Put物件提供了一種可以開啟Put快取區的方式來提高資料提交的速率。該方式在客戶端的記憶體中提供一塊快取區域,客戶端並設定其大小,然後在使用者每次進行提交時並不立刻將資料提交給Hbase叢集中,而是當所有該快取區已經滿溢的時候將快取區中的資料通過一次RPC操作,一次提交到HBase叢集中去。所以快取塊在進行大量put請求,且資料量較小時將會明顯提高效率。

public void startBufferAndInsert(String tableName,String[] rows,String[] families,String[] columns,String[] values)
    {
        Configuration conf=init();
        try {
            //檢查制定的表是否村存在
            HBaseAdmin admin=new HBaseAdmin(conf);
            if(!admin.tableExists(Bytes.toBytes(tableName)))
            {
                System.err.println("the table "+tableName+" is not exist");
                System.exit(1);
            }
            admin.close();
            //建立表連線
            HTable table=new HTable(conf,TableName.valueOf(tableName));
            //將資料自動提交功能關閉
            table.setAutoFlush(false);
            //設定資料快取區域
            table.setWriteBufferSize(64*1024*1024); 
            //然後開始寫入資料
            int length=rows.length;
            for(int i=0;i<length;i++)
            {
                Put put=new Put(Bytes.toBytes(rows[i]));
                put.addColumn(Bytes.toBytes(families[i]),Bytes.toBytes(columns[i]),Bytes.toBytes(values[i]));
                table.put(put);
            }
            //重新整理快取區
            table.flushCommits();
            //關閉表連線
            table.close();
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
使用快取插入方式時,要注意將table的自動填充屬性進行關閉,並且在資料插入完成後進行一次手動的提交操作。將快取區中的資料手動的提交到HBase伺服器中。

三、Put類詳解

1、主要屬性:KeyValue物件陣列

Put類中主要含有一個KeyValue物件陣列,KeyValue物件是HBase底層儲存的一個重要類,代表了資料在底層儲存時的狀態。KeyValue物件代表了一個Hbase表中的一個數據單元,即含有行值(row)、列簇(family)、列(column)、時間戳(timestamp)和值(value),從這些資訊能夠在表中唯一確定一個數據單元。在KeyValue物件中,Key(鍵)包含了一個value值的row、family、column和timestamp資訊,而value則是該表單元格的資料。

當插入一條資料時,其實就是講KeyValue進行序列化後,然後傳遞後Hbase叢集,叢集在根據KeyValue的值進行相應的操作。

2、主要方法

(1)Put(byte[] row) / Put(byte[] row,RowLock lock)

初始化函式,一個Put物件值代表一行資料,但是因為其內部含有多個KeyValue鍵值對,Put物件可以填充多個列簇(family)、列(qualifier),甚至是多時間戳(timestampe)資料。第二個函式中有行鎖(RowLock)引數,使用者可以通過設定該引數指定一個行鎖。一般來說系統在進行Put時會對put所在的行新增一個行鎖。系統並不提倡使用者自己定義行鎖,因為可能在多個使用者指定多個行鎖時會造成死鎖的情況,導致系統資源在兩個客戶端斷開連線之前一直被佔用。

(2)add(Cell kv) / add(byte[] family, byte[] qualifier, long ts, byte[] value) / )  / (byte[] family, byte[] qualifier, long ts, byte[] value, org.apache.hadoop.hbase.Tag[] tag)

這四種方法都是想Put物件中新增單元資料,即增加一個KeyValue物件。

A、新增Cell物件,Cell類可以引用KeyVakue的物件,因此此處也可以插入KeyValue物件,因此即可將該函式理解為插入一個完整的KeyValue物件即可

B、新增列簇、列、時間戳、值,Put物件會在接收這些資料後將其初始化成一個KeyValue物件,不過該方法已經廢棄,不建議使用

C、該方法和第二方法作用相同

D、新增恆定資料,通過該方法新增一個恆定的KeyValue物件值,具體效果沒有試驗過

(3)has(byte[] family, byte[] qualifier, byte[] value)

判斷Put物件中是否含有制定的value值/列/列簇,返回值為Boolean值

(4)setWriteToWAL(boolean write)

是否將資料寫入到預寫日誌(Write-Ahead-Log)中,預寫日誌是一種資料保護措施,如果當HBase某一個節點故障時,可以通過預寫日誌中的記錄的資料操作進行資料恢復。該選項如果開啟,資料會被寫入到預寫日誌中,安全性增加,但是會損耗一定效能,如果不開啟,則損耗變小,安全性降低

(5)setTTL(long ttl)

ttl毫秒數。該函式對該行中的所有的KeyValue物件設定TTL,TTL(Time-To-Live)的作用是從資料產生起,經過TTL時間後就會被作為廢棄資料而被刪除掉。

(6)setDurability()

該函式對寫入WAL模式進行設定。可填充的值為:Durability.ASYNC_WAL(非同步進行資料寫入)、Durability.SYNC_WAL(同步進行寫入)、Durabiliry.SKIP_WAL(不進行WAL填寫)、Durability.FSYNC_WAL(強制同步進行WAL寫入)、Durability.USE_DEFAULT(預設選項,為SYNC_WAL選項)

(7)其他方法

A、getRow()  獲取建立Put例項時的行健

B、getRowLock()   獲取建立Put例項時的行鎖

C、getLockId()    返回使用rowlock引數傳遞給建構函式的可選的鎖ID,當違背制定時放回-1L

D、getTimeStamp()   獲取相應Put例項的時間戳,改制在建構函式中有ts引數傳入,如果沒有指定的話則返回 Long.MAX_VALUE

E、isEmpty()   返回該Put例項中是否含有KeyValue例項

F、numFamilies()   返回該Put例項中的列簇數量

G、size()   返回本次Put物件新增的KeyValue例項的數量

四、總結

通過Put的設計,我們能夠體會到一些HBase底層的設計結構,因此需要好好理解KeyValue物件。上面便是筆者對Hbase Put進行輸入插入的裂解,如果有什麼錯誤的地方請指出,希望共同進步

相關推薦

HBase總結1-- 資料插入Put物件

一、介紹 HBase的客戶端包中集中了CURD操作,使用者可以通過其中不同種類的API盡心CURD操作。HBase資料插入使用Put物件,Put物件在進行資料插入時,首先會想Hbase叢集傳送一個RPC請求,得到響應後將Put類中的資料通過序列化的方式傳給HBase叢集,叢

HBase總結4--資料掃描Scan物件

一、介紹 Put、Delete與Get物件都是Row的子類,從該繼承關係中我們就可以瞭解到Get、Delete與Pu物件本身就只能進行單行的操作,HBase客戶端還提供了一套能夠進行全表掃描的API,方便使用者能夠快速對整張表進行掃描,以獲取想要的結果---scan 二、流

我的Keras使用總結1——Keras概述常見問題整理

  今天整理了自己所寫的關於Keras的部落格,有沒釋出的,有釋出的,但是整體來說是有點亂的。上週有空,認真看了一週Keras的中文文件,稍有心得,整理於此。這裡附上Keras官網地址:   Keras英文文件:https://keras.io/#installationKeras   Keras中文文件:h

SpringBoot專案總結--1欄位校驗加密

一、多欄位校驗 提供Validator的實現類,並且實現Validator介面的supports和validate方法。supports方法用於判斷當前類是不是需要校驗的類。只有當supports方法返回的結果為true時,validate方法才會執行進行校驗。 p

資料結構演算法1- 資料結構概覽

宣告:雖然本系列部落格與具體的程式語言無關。但是本文作者對c++相對比較熟悉,其次是java,所以難免會有視角上的偏差。舉例也大多是和這兩門語言相關。 今天先來看看有哪些常見的資料結構(C++ STL視角,其他應該也大同小異吧。哈哈,我猜的!)。所以之後的內容大多從STL出發,然後順便對比下ja

Struts2框架頁面的資料互動1--資料封裝

2、Struts2框架與頁面的資料互動(1)--資料封裝 上接Sturts2框架入門學習:https://blog.csdn.net/biggerchong/article/details/84540183 目錄 2、Struts2框架與頁面的資料互動 2.1

基於R的資料探勘方法實踐1——資料準備

1、資料檢查 資料檢查是資料探勘的第1步,從不同的維度檢查資料,找出其中有問題的資料以便對其進行修正。 1.1 資料型別 檢視資料的構成與形態,尤其是各列的屬性。 > library(MASS) > data(ChickWeight) > str(Chic

資料庫設計優化總結1

一、資料庫的設計的幾點措施 1.關聯表的關聯欄位名稱必須相同。 2.欄位的定義的前兩位是表名,第三位是下劃線,保證規範。 3.常用欄位採用固定單詞,如id 4.如果只有一個索引,索引的名字希望和表名相同,如果是多個,那麼就用表明下劃線欄位名。 5.關聯欄位儘可能為數字型別。

FPGA實現串列埠iic控制器總結1

在剖析了《深入淺出玩轉FPGA》的串列埠程式碼和IIC控制器程式碼、xilinx官方的xilinx的iic控制器(參見書《FPGACPLD設計工具──Xilinx ISE使用詳解》)、《片上系統設計思想與原始碼分析》一書中帶有wishbone介面的iic控制器後

java web學習心得總結1——jsp基本語法

java web自學快三個月了,前面的基礎知識都忘了,以後每天寫一篇部落格總結一下. 或者關注下我的新浪微博:Mr翅膀君 一.page指令 1.language屬性 <%@ page language="java" import="java.util.*" page

Spring Cloud微服務學習總結1——Spring Cloud及微服務入門

一、Spring Cloud是什麼鬼? Spring Cloud為開發者提供了快速建立一些常見的模式在分散式系統的工具(如配置管理、服務發現、斷路器、智慧路由、微代理,控制匯流排,一次性令牌,全球鎖,領

Jenkins學習總結1——Jenkins詳細安裝構建部署使用教程

  Jenkins是一個開源軟體專案,旨在提供一個開放易用的軟體平臺,使軟體的持續整合變成可能。Jenkins是基於Java開發的一種持續整合工具,用於監控持續重複的工作,功能包括: 1、持續的軟體版本釋出/測試專案。 2、監控外部呼叫執行的工作。 本文使用的Linux

Java EE 之 過濾器入門學習總結1

ret oct 入門 全局 err throws () XML view 使用Filter技術來配合開發會使得開發變得簡單起來。簡單的一個例子就表現在“亂碼問題”上。不使用Filter的話,我們有可能需要為每一個網頁設置字符編碼集,如request.setCharacte

SQL Server2012 學習之插入修改SQL資料

插入資料是資料庫使用中的常用操作,在對資料庫進行操作時,更經常使用的是用T-SQL語句進行資料插入,視覺化介面的操作較少,因此這篇部落格在介紹資料插入的時候側重於使用T-SQL語句進行。其語法格式如下。1.insert……value語句insert value是基本的新增資料

Hbase的SQL介面之Phoenix使用總結1

#最近在寫操作HBase的介面,順便研究了一下Phoenix,簡單的介紹下Phoenix,Phoenix用Java實現,人們通過Phoenix,可以用自己所熟悉的SQL語言來操作HBase,當然它是開源的。 1.如何讓HBase支援Phoenix? 將phoenix-1.1.jar複製到HBase

資料探勘實戰之天池精準醫療大賽1——賽題資料

首先介紹題目與資料:特別提供一下資料,供後來看到的盆友下載研究(現在官網上剩下的資料是複賽的了),測試資料分AB榜,不瞭解的去看天池平臺的介紹:競賽題目中國是世界上糖尿病患者最多的國家,病人達到1.1億,每年有130萬人死於糖尿病及其相關疾病。每年用於糖尿病的醫療費用佔中國公

2013年自我回顧總結1

本不是喜歡自我總結的人,很多時候認為這也挺矯情的,哈哈,我就是傳說中的簡單直接粗暴一組,女漢子的稱謂也由此而來吧,愛直接也愛簡單,愛coding也愛coding to die,我是女漢子,我為自己代鹽,啊哈哈哈哈。 但是看過大家的總結之後我也是深有感觸的,這一年對於我而言

我的軟考之路——資料結構演算法1之線性

         資料結構與演算法是程式設計的兩大基礎,大型的IT企業面試時也會出資料結構和演算法的題目,它可以說明你是否有良好的邏輯思維,如果你具備良好的邏輯思維,即使技術存在某些缺陷,面試公司也會認

ajax技術整理總結1

col () stat sta pre resp tel html func 1.創建ajax對象 var xhr=new XMLHttpRequest(); 4.監聽狀態信息 xhr.onreadystatechange=function(){ //4接收完畢

Python3入門筆記1 —— windows安裝運行

python安裝 color 聲明 返回值 down 如果 ++ 這一 ges Python的設計哲學是“優雅”、“明確”、“簡單”。這也是我喜歡Python的理由之一 Python的安裝: 1.進入Python官方網站下載安裝包 點擊導航欄的 Downloads 會自動