今天的主要來分析一下HBase的特點,提出一些真實的應用場景,利用HBase去解決應用中的效率問題;
- HBase特點概述
HBase是google的Bigtable的開源實現,建立在HDFS上,提供高可靠性、高性能、列存儲、可伸縮、實時讀寫的數據庫系統。
HBase介於nosql和rdbms之間,僅能通過主鍵(row key)和主鍵的range來檢索數據,僅支持單行事務(可通過hive支持來實現多表join等複雜操作)。
主要用來存儲非結構化和半結構化的鬆散數據。因爲底層是Hadoop所以完全和hadoop一樣,Hbase目標主要依靠橫向擴展,通過不斷增加廉價的商用服務器,來增加計算和存儲能力。HBase中的表一般有這樣的特點:
- 大:一個表可以有上億行,上百萬列;數據量大,並且表很寬;
- 面向列:面向列(族)的存儲和權限控制,列(族)獨立檢索;
- 稀疏:對於爲空(null)的列,並不佔用存儲空間,因此,表可以設計的非常稀疏;
分析我們的業務的時候我們不要從關係數據庫表的結構去構思未來表的結構。我們主要去看我們的數據的特點是否具備我們上面提到三個特點。如果具備的話我們一般認爲這種業務數據適合放到HBase上來存儲。
- 大:一個表可以有上億行,上百萬列;數據量大,並且表很寬;
- HBase應用場景分析
場景1:對變形金剛實時數據監控應用(虛擬場景)
1.場景描述:- 變形金剛上提供數據傳輸模塊,對1000個零部件的狀態的指標進行監控並以1秒/幀實時傳輸到數據中心;
- 假如現在有100個變形金剛,數據量=1000(指標)*100個變形金剛=100000條指標;
- 一年的數據量是31536億條指標,那麼存儲十年的數據的話我就不算了,太大了。
- 從大這個特點上來我們這個場景是滿足的。
- 從寬的特點上來說我們這個場景也是可以滿足的。
我們主要是對某個變形金剛的一段時間內狀態進行分析,實時對變形金剛的狀態進行監控和分析;
假如我們的每一幀數據作爲一行的話,我們的表會很寬,有100個列簇,1000*100列;
我們來看我下設計圖
- 編寫測試實例
package com.hugy.hadoop.invoke; import java.io.IOException; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Random; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Result; import com.hugy.hadoop.hbase.HBaseHelper; public class HBaseInvoke { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println("HBase 操作開始..."); Configuration conf = new Configuration(); conf.set("hbase.zookeeper.quorum", "hadoop"); conf.set("hbase.zookeeper.property.clientPort", "2181"); HBaseHelper hbase = new HBaseHelper(conf); // 2.1創建表 String tableName = "thransformersdata";// 變形金剛指標數據存儲表 hbase.deleteTable(tableName); String colFamilies[] = { "thransformer1","thransformer2","thransformer3","thransformer4","thransformer5"}; hbase.createTable(tableName, colFamilies); Random random = new Random(); Date starttime=new Date(); long rowkey = starttime.getTime()/1000; for (int x = 1; x <=5; x++)// 5秒鐘的數據 { rowkey++; //一秒鐘一幀數據 for (int i = 1; i <= 5; i++)// 5個變形金剛 { for (int j = 1; j <= 100; j++)// 100個指標 { hbase.insertRecord(tableName,Long.toString(rowkey), "thransformer"+i, "quota"+j, Float.toString(0.3f)); } } } // 2.4查詢整個Table List<Result> list = null; list = hbase.getAllRecord(tableName); Iterator<Result> it = list.iterator(); while (it.hasNext()) { Result rs2 = it.next(); for (KeyValue kv : rs2.raw()) { System.out.print("row key is : " + new String(kv.getRow())); System.out.print("family is : " + new String(kv.getFamily())); System.out.print("qualifier is:" + new String(kv.getQualifier())); System.out.print("timestamp is:" + kv.getTimestamp()); System.out.println("Value is : " + new String(kv.getValue())); } } } }
部分輸出結果輸出如下:
row key is : 1406466972 family is : thransformer3 qualifier is:quota91 timestamp is:1406495760290 Value is : 0.3
row key is : 1406466972 family is : thransformer3 qualifier is:quota92 timestamp is:1406495760314 Value is : 0.3
row key is : 1406466972 family is : thransformer3 qualifier is:quota93 timestamp is:1406495760352 Value is : 0.3
row key is : 1406466972 family is : thransformer3 qualifier is:quota94 timestamp is:1406495760366 Value is : 0.3
row key is : 1406466972 family is : thransformer3 qualifier is:quota95 timestamp is:1406495760379 Value is : 0.3
row key is : 1406466972 family is : thransformer3 qualifier is:quota96 timestamp is:1406495760437 Value is : 0.3
row key is : 1406466972 family is : thransformer3 qualifier is:quota97 timestamp is:1406495760450 Value is : 0.3