為了更好的理解多版本,我們可以把普通的數(shù)據(jù)存儲(chǔ)理解成二維空間,提供了rowkey,列族,列幾個(gè)存儲(chǔ)的維度。那么版本則相當(dāng)于二維空間升華到了三維空間,多了時(shí)間維度的概念。如果按照默認(rèn)的操作,當(dāng)前的時(shí)間戳就是版本號(hào),每個(gè)數(shù)據(jù)都可以保留多個(gè)版本的數(shù)據(jù)。你可以只查詢最新的數(shù)據(jù),也可以查看歷史版本。
話題扯遠(yuǎn)了,回過來我們在看一下多版本如何進(jìn)行讀寫 第一步,創(chuàng)建表并開啟多版本hbase(main):002:0> create_namespace 'xingoo' 0 row(s) in 0.0230 seconds hbase(main):003:0> create 'xingoo:test_v','v' 0 row(s) in 4.5760 seconds => Hbase::Table - xingoo:test_v 創(chuàng)建Hbase表,并查看表結(jié)構(gòu):hbase(main):004:0> describe 'xingoo:test_v' Table xingoo:test_v is ENABLED xingoo:test_v COLUMN FAMILIES DESCRIPTION {NAME => 'v', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TT L => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} 1 row(s) in 0.1040 seconds 需要關(guān)注的是VERSIONS字段,這個(gè)字段默認(rèn)為1,即默認(rèn)只保留一個(gè)版本的數(shù)據(jù),如果不修改,無論你怎么寫,都只能查到一個(gè)版本的數(shù)據(jù)。 更多參數(shù)信息,可以查看HColumnDescriptor的Java Doc 修改版本數(shù)hbase(main):005:0> alter 'xingoo:test_v',NAME=>'v',VERSIONS=>5 Updating all regions with the new schema... 1/1 regions updated. Done. 0 row(s) in 3.1590 seconds hbase(main):006:0> describe 'xingoo:test_v' Table xingoo:test_v is ENABLED xingoo:test_v COLUMN FAMILIES DESCRIPTION {NAME => 'v', BLOOMFILTER => 'ROW', VERSIONS => '5', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TT L => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'} 1 row(s) in 0.0150 seconds 再次查看下,就可以看到支持的版本多了。 基于Shell的讀寫shell寫入多個(gè)版本hbase(main):007:0> put 'xingoo:test_v','1','v:c1','value1' 0 row(s) in 0.0870 seconds hbase(main):008:0> put 'xingoo:test_v','1','v:c1','value2' 0 row(s) in 0.0050 seconds hbase(main):009:0> put 'xingoo:test_v','1','v:c1','value3' 0 row(s) in 0.0040 seconds hbase(main):010:0> put 'xingoo:test_v','1','v:c1','value4' 0 row(s) in 0.0040 seconds hbase(main):011:0> put 'xingoo:test_v','1','v:c1','value5' 0 row(s) in 0.0040 seconds hbase(main):012:0> put 'xingoo:test_v','1','v:c1','value6' 0 row(s) in 0.0030 seconds hbase(main):013:0> put 'xingoo:test_v','1','v:c1','value7' 0 row(s) in 0.0040 seconds shell讀取多個(gè)版本的數(shù)據(jù)注意:如果讀取的版本大于Hbase存儲(chǔ)的版本,那么只會(huì)讀取最大VESIONS個(gè)記錄。 hbase(main):015:0> get 'xingoo:test_v','1',{COLUMN => 'v:c1',VERSIONS=>5} COLUMN CELL v:c1 timestamp=1499088390024, value=value7 v:c1 timestamp=1499088387559, value=value6 v:c1 timestamp=1499088385347, value=value5 v:c1 timestamp=1499088383228, value=value4 v:c1 timestamp=1499088380943, value=value3 5 row(s) in 0.0070 seconds hbase(main):016:0> get 'xingoo:test_v','1',{COLUMN => 'v:c1',VERSIONS=>6} COLUMN CELL v:c1 timestamp=1499088390024, value=value7 v:c1 timestamp=1499088387559, value=value6 v:c1 timestamp=1499088385347, value=value5 v:c1 timestamp=1499088383228, value=value4 v:c1 timestamp=1499088380943, value=value3 5 row(s) in 0.0050 seconds hbase(main):017:0> get 'xingoo:test_v','1',{COLUMN => 'v:c1',VERSIONS=>2} COLUMN CELL v:c1 timestamp=1499088390024, value=value7 v:c1 timestamp=1499088387559, value=value6 2 row(s) in 0.0060 seconds 另外,還可以把版本字段當(dāng)做一個(gè)時(shí)間字段來進(jìn)行范圍查詢,如: hbase> get 't1', 'r1', {COLUMN => 'c1', TIMERANGE => [ts1, ts2], VERSIONS => 4} 基于Java的讀寫首先,需要?jiǎng)?chuàng)建工具類,包含連接的配置 public class HbaseClient { public static final String TABLE = "xingoo:test_v"; private static Configuration conf = null; private static Connection conn = null; static { try { conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.property.clientPort", "2181"); conf.set("hbase.zookeeper.quorum", "zk1,zk2,zk3"); conn = ConnectionFactory.createConnection(conf); } catch (IOException e) { e.printStackTrace(); } } ... } 讀操作public void write(String phone,String listing_id) throws IOException { HTable myTable = new HTable(conf, TableName.valueOf(TABLE)); myTable.setAutoFlush(false, false); myTable.setWriteBufferSize(3 * 1024 * 1024); Put p = new Put(Bytes.toBytes("row_key_1")); //可以自己設(shè)置時(shí)間戳作為版本號(hào),也可以使用默認(rèn)時(shí)間 // p.addColumn(Bytes.toBytes("v"), Bytes.toBytes("c1"), System.currentTimeMillis(), Bytes.toBytes("test1")); p.addColumn(Bytes.toBytes("v"), Bytes.toBytes("c1"), Bytes.toBytes("test2")); System.out.println(System.currentTimeMillis()); myTable.put(p); myTable.flushCommits(); myTable.close(); } 寫操作public List<String> read(String q) throws IOException { Table table = HbaseClient.conn.getTable(TableName.valueOf(TABLE)); Scan scan = new Scan(); scan.addColumn("v".getBytes(),"c1".getBytes()); scan.setMaxVersions(3);//設(shè)置讀取的最大的版本數(shù) RowFilter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,new BinaryComparator(q.getBytes()));//基于過濾器設(shè)置查詢條件 scan.setFilter(rowFilter); ResultScanner r = table.getScanner(scan); List<String> list = new ArrayList<>(); for(Result result : r) { for (KeyValue kv : result.raw()) { list.add(Bytes.toString(kv.getValue())); } } System.out.println(list.size()); table.close(); return list; } 參考1 hbase教程:http://www./hbase/ 2 hbase官方文檔:http://hbase./book.html#appendix_contributing_to_documentation 3 一維到十維空間:http://www.sohu.com/a/116444282_482877 |
|