hbase(二)

1、HBase簡介

1.1簡介

hbase是bigtable的開源山寨版本。是創建的hdfs之上,提供高可靠性、高性能、列存儲、可伸縮、實時讀寫的數據庫系統。
它介於nosql和RDBMS之間,僅能經過主鍵(row key)和主鍵的range來檢索數據,僅支持單行事務(可經過hive支持來實現多表join等複雜操做)。主要用來存儲非結構化和半結構化的鬆散數據。與hadoop同樣,Hbase目標主要依靠橫向擴展,經過不斷增長廉價的商用服務器,來增長計算和存儲能力。node

1.2 Hbase與傳統數據庫的對比

HBase以表的形式存儲數據。表有行和列組成。列劃分爲若干個列族(row family)。sql

咱們能夠先來看一下傳統的關係型數據庫中的表:shell

 

而後與HBase的表進行對比,hbase的表結構,與傳統的關係型數據庫有較大的差異數據庫

咱們就能夠發現不少不一樣地方:數組

hbase不支持sql語句,它是一個nosql的一種,若是沒有學過nosql或rubey,咱們能夠用help
一、定義表時不指定字段
二、定義表的時候只要指定列族名,列族數量不限
三、每一行都有一個固定的字段(行鍵),具備惟一性
四、對值的修改,原來的值是保留着的,每一個值能夠保留多個版本。默認查詢的是最新版本的的值。(默認保留一個版本)緩存

1.3 HBase中的重要概念

列族:hbase表中的每一個列,都歸屬與某個列族。列族是表的chema的一部分(而列不是),必須在使用表以前定義。列名都以列族做爲前綴。例如courses:history , courses:math 都屬於 courses 這個列族。服務器

訪問控制、磁盤和內存的使用統計都是在列族層面進行的。實際應用中,列族上的控制權限能幫助咱們管理不一樣類型的應用:咱們容許一些應用能夠添加新的基本數據、一些應用能夠讀取基本數據並建立繼承的列族、一些應用則只容許瀏覽數據(甚至可能因 爲隱私的緣由不能瀏覽全部數據)。app

時間戳:HBase中經過row和columns肯定的爲一個存貯單元稱爲cell。每一個 cell都保存着同一份數據的多個版本。版本經過時間戳來索引。時間戳的類型是 64位整型。時間戳能夠由hbase(在數據寫入時自動 )賦值,此時時間戳是精確到毫秒的當前系統時間。時間戳也能夠由客戶顯式賦值。若是應用程序要避免數據版本衝突,就必須本身生成具備惟一性的時間戳。每一個 cell中,不一樣版本的數據按照時間倒序排序,即最新的數據排在最前面。負載均衡

爲了不數據存在過多版本形成的的管理 (包括存貯和索引)負擔,hbase提供了兩種數據版本回收方式。一是保存數據的最後n個版本,二是保存最近一段時間內的版本(好比最近七天)。用戶能夠針對每一個列族進行設置。eclipse

Cell:由{row key, column( =<family> + <label>),version} 惟一肯定的單元。cell中的數據是沒有類型的,所有是字節碼形式存貯。

 

2、HBase體系結構

一、一個表會按照行劃分爲若干個region,每個region分配給一臺特定的regionserver管理
二、每個region內部還要一句列族劃分爲若干個HStore
三、每一個HStore中的數據會落地到若干個HFILE文件中
四、region體積會隨着數據插入而不斷增加,到必定閾值後分裂
五、隨着region的分裂,一臺regionserver上管理的region會愈來愈多
六、HMASTER會根據regionserver上管理的region數作負載均衡
七、region中的數據擁有一個內存緩存:memstore,數據的訪問優先在memstore中進行
八、memstore中的數據由於空間有限,因此須要按期flush到文件storefile中,每次flush都是生成新的storefile
九、storefile的數量隨着時間也會不斷增長,regionserver會按期將大量storefile進行合併(merge)

行鍵的設計對數據查詢效率的影響很是大。
HBase具備很好的可伸縮性:若是存儲容量不夠的時候,直接加datanode或者regionservers
hbase能夠做爲一個線上系統的底層系統的功能。

Hmaster能夠作負載均衡,監控到各個節點之間的數據存儲狀況。
每個store(列族)會有一個內存緩存,存放的是一些最熱的數據(最近訪問的),這樣的話讀取數據的速度會快不少。

文件都是有索引的,因此查起來會比較快的。

region會在storefile按期進行合併操做。

3、HBase   shell的使用

 create 'user-info',{NAME=>'base_info',VERSIONS=>3},{NAME=>'extra_info'}  
 put 'user-info','rk-100001','base_info:name','huang****'
 put 'user-info','rk-100001','base_info:age','30'  
 put 'user-info','rk-100001','base_info:address','Xinyang'   
 put 'user-info','rk-100001','base_info:tel','13000000000'   

 

scan 'user-info' 

4、eclipse中使用HBase

  1 // 與HBase數據庫的鏈接對象
  2     Connection conn;
  3     @Before
  4     public void setUp() throws Exception {
  5 
  6         // 取得一個數據庫鏈接的配置參數對象
  7         Configuration conf = HBaseConfiguration.create();
  8         // 設置鏈接參數:HBase數據庫所在的主機IP
  9         conf.set("hbase.zookeeper.quorum", "master,node1,node2");
 10         // 設置鏈接參數:HBase數據庫使用的端口
 11         conf.set("hbase.zookeeper.property.clientPort", "2181");
 12 
 13         // 取得一個數據庫鏈接對象
 14         conn = ConnectionFactory.createConnection(conf);
 15     }
 16 
 17     @Test
 18     public void put() throws Exception {
 19         
 20         // 經過鏈接工廠建立鏈接對象
 21         //conn = ConnectionFactory.createConnection(conf);
 22         // 經過鏈接查詢tableName對象
 23         TableName tname = TableName.valueOf("ns1:t1");
 24         // 得到table
 25         Table table = conn.getTable(tname);
 26 
 27         // 經過bytes工具類建立字節數組(將字符串)
 28         byte[] rowid = Bytes.toBytes("row3");
 29 
 30         // 建立put對象
 31         Put put = new Put(rowid);
 32 
 33         byte[] f1 = Bytes.toBytes("f1");
 34         byte[] id = Bytes.toBytes("id");
 35         byte[] value = Bytes.toBytes(102);
 36         put.addColumn(f1, id, value);
 37 
 38         // 執行插入
 39         table.put(put);
 40     }
 41 
 42     @Test
 43     public void bigInsert() throws Exception {
 44 
 45         DecimalFormat format = new DecimalFormat();
 46         format.applyPattern("0000");
 47 
 48         long start = System.currentTimeMillis();
 49         TableName tname = TableName.valueOf("ns1:t1");
 50         HTable table = (HTable) conn.getTable(tname);
 51         // 不要自動清理緩衝區
 52         table.setAutoFlush(false);
 53 
 54         for (int i = 1; i < 10000; i++) {
 55             Put put = new Put(Bytes.toBytes("row" + format.format(i)));
 56             // 關閉寫前日誌
 57             put.setWriteToWAL(false);
 58             put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("id"), Bytes.toBytes(i));
 59             put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("name"), Bytes.toBytes("tom" + i));
 60             put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("age"), Bytes.toBytes(i % 100));
 61             table.put(put);
 62 
 63             if (i % 2000 == 0) {
 64                 table.flushCommits();
 65             }
 66         }
 67         //
 68         table.flushCommits();
 69         System.out.println(System.currentTimeMillis() - start);
 70     }
 71     
 72     /**
 73      * 遍歷
 74      */
 75     @Test
 76     public void scan() throws IOException {
 77         TableName tname = TableName.valueOf("ns1:t1");
 78         Table table = conn.getTable(tname);
 79         Scan scan = new Scan();
 80         scan.setStartRow(Bytes.toBytes("row5000"));
 81         scan.setStopRow(Bytes.toBytes("row8000"));
 82         ResultScanner rs = table.getScanner(scan);
 83         Iterator<Result> it = rs.iterator();
 84         while (it.hasNext()) {
 85             Result r = it.next();
 86             byte[] name = r.getValue(Bytes.toBytes("f1"), Bytes.toBytes("name"));
 87             System.out.println(Bytes.toString(name));
 88         }
 89     }
 90     
 91     /**
 92      * 動態遍歷
 93      */
 94     @Test
 95     public void scan2() throws IOException {
 96         //Configuration conf = HBaseConfiguration.create();
 97         //Connection conn = ConnectionFactory.createConnection(conf);
 98         TableName tname = TableName.valueOf("ns1:t1");
 99         Table table = conn.getTable(tname);
100         Scan scan = new Scan();
101         scan.setStartRow(Bytes.toBytes("row5000"));
102         scan.setStopRow(Bytes.toBytes("row8000"));
103         ResultScanner rs = table.getScanner(scan);
104         Iterator<Result> it = rs.iterator();
105         while (it.hasNext()) {
106             Result r = it.next();
107             Map<byte[],byte[]> map = r.getFamilyMap(Bytes.toBytes("f1"));
108             for(Map.Entry<byte[],byte[]> entrySet : map.entrySet()){
109                 String col = Bytes.toString(entrySet.getKey());
110                 String val = Bytes.toString(entrySet.getValue());
111                 System.out.print(col + ":" + val + ",");
112             }
113 
114             System.out.println();
115         }
116     }

 

 參考:http://blog.csdn.net/sdksdk0/article/details/51680296

            http://blog.csdn.net/u011308691/article/details/51476383

相關文章
相關標籤/搜索