《HBase基本数据实际操作详解.doc》由会员分享,可在线阅读,更多相关《HBase基本数据实际操作详解.doc(47页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、/概述对于建表,和RDBMS类似,HBase也有namespace的概念,可以指定表空间创建表,也可以直接创建表,进入default表空间。对于数据操作,HBase支持四类主要的数据操作,分别是: Put:增加一行,修改一行; Delete:删除一行,删除指定列族,删除指定column的多个版本,删除指定column的制定版本等; Get:获取指定行的所有信息,获取指定行和指定列族的所有colunm,获取指定column,获取指定column的几个版本,获取指定column的指定版本等; Scan:获取所有行,获取指定行键范围的行,获取从某行开始的几行,获取满足过滤条件的行等。这四个类都是or
2、g.apache.hadoop.hbase.client的子类,可以到官网API去查看详细信息,本文仅总结常用方法,力争让读者用20%的时间掌握80%的常用功能。目录1.命名空间Namespace2.创建表3.删除表4.修改表5.新增、更新数据Put6.删除数据Delete7.获取单行Get8.获取多行Scan1. 命名空间Namespace在关系数据库系统中,命名空间namespace指的是一个表的逻辑分组,同一组中的表有类似的用途。命名空间的概念为即将到来的多租户特性打下基础: 配额管理(Quota Management (HBASE-8410)):限制一个namespace可以使用的资源
3、,资源包括region和table等; 命名空间安全管理(Namespace Security Administration (HBASE-9206)):提供了另一个层面的多租户安全管理; Region服务器组(Region server groups (HBASE-6721)):一个命名空间或一张表,可以被固定到一组regionservers上,从而保证了数据隔离性。1.1.命名空间管理命名空间可以被创建、移除、修改。表和命名空间的隶属关系在在创建表时决定,通过以下格式指定::Example:hbase shell中创建命名空间、创建命名空间中的表、移除命名空间、修改命名空间#Create
4、a namespace create_namespace my_ns #create my_table in my_ns namespacecreate my_ns:my_table, fam #drop namespace drop_namespace my_ns #alter namespace alter_namespace my_ns, METHOD = set, PROPERTY_NAME = PROPERTY_VALUE 1.2. 预定义的命名空间有两个系统内置的预定义命名空间: hbase:系统命名空间,用于包含hbase的内部表 default:所有未指定命名空间的表都自动进入
5、该命名空间Example:指定命名空间和默认命名空间#namespace=foo and table qualifier=barcreate foo:bar, fam#namespace=default and table qualifier=barcreate bar, fam2.创建表废话不多说,直接上样板代码,代码后再说明注意事项和知识点: Configurationconf=HBaseConfiguration.create();HBaseAdminadmin=newHBaseAdmin(conf);/createnamespacenamedmy_nsadmin.createNames
6、pace(NamespaceDescriptor.create(my_ns).build();/createtableDesc,withnamespacenamemy_nsandtablenamemytableHTableDescriptortableDesc=newHTableDescriptor(TableName.valueOf(my_ns:mytable); tableDesc.setDurability(Durability.SYNC_WAL);/addacolumnfamilymycfHColumnDescriptorhcd=newHColumnDescriptor(mycf);t
7、ableDesc.addFamily(hcd);admin.createTable(tableDesc);admin.close();关键知识点:1. 必须将HBase集群的hbase-site.xml文件添加进工程的classpath中,或者通过Configuration对象设置相关属性,否则程序获取不到集群相关信息,也就无法找到集群,运行程序时会报错;2. HTableDescriptortableDesc=newHTableDescriptor(TableName.valueOf(my_ns:mytable)代码是描述表mytable,并将mytable放到了my_ns命名空间中,前提是
8、该命名空间已存在,如果指定的是不存在命名空间,则会报错org.apache.hadoop.hbase.NamespaceNotFoundException;3. 命名空间一般在建模阶段通过命令行创建,在java代码中通过admin.createNamespace(NamespaceDescriptor.create(my_ns).build()创建的机会不多;4. 创建HBaseAdmin对象时就已经建立了客户端程序与HBase集群的connection,所以在程序执行完成后,务必通过admin.close()关闭connection;5. 可以通过HTableDescriptor对象设置表的
9、特性,比如:通过tableDesc.setMaxFileSize(512)设置一个region中的store文件的最大size,当一个region中的最大store文件达到这个size时,region就开始分裂;通过tableDesc.setMemStoreFlushSize(512)设置region内存中的memstore的最大值,当memstore达到这个值时,开始往磁盘中刷数据。更多特性请自行查阅官网API;6. 可以通过HColumnDescriptor对象设置列族的特性,比如:通过hcd.setTimeToLive(5184000)设置数据保存的最长时间;通过hcd.setInMem
10、ory(true)设置数据保存在内存中以提高响应速度;通过hcd.setMaxVersions(10)设置数据保存的最大版本数;通过hcd.setMinVersions(5)设置数据保存的最小版本数(配合TimeToLive使用)。更多特性请自行查阅官网API;7. 数据的版本数只能通过HColumnDescriptor对象设置,不能通过HTableDescriptor对象设置;8. 由于HBase的数据是先写入内存,数据累计达到内存阀值时才往磁盘中flush数据,所以,如果在数据还没有flush进硬盘时,regionserver down掉了,内存中的数据将丢失。要想解决这个场景的问题就需要
11、用到WAL(Write-Ahead-Log),tableDesc.setDurability(Durability.SYNC_WAL)就是设置写WAL日志的级别,示例中设置的是同步写WAL,该方式安全性较高,但无疑会一定程度影响性能,请根据具体场景选择使用;9. setDurability(Durability d)方法可以在相关的三个对象中使用,分别是:HTableDescriptor,Delete,Put(其中Delete和Put的该方法都是继承自父类org.apache.hadoop.hbase.client.Mutation)。分别针对表、插入操作、删除操作设定WAL日志写入级别。需要
12、注意的是,Delete和Put并不会继承Table的Durability级别(已实测验证)。Durability是一个枚举变量,可选值参见4.2节。如果不通过该方法指定WAL日志级别,则为默认USE_DEFAULT级别。3.删除表删除表没创建表那么多学问,直接上代码: Configurationconf=HBaseConfiguration.create();HBaseAdminadmin=newHBaseAdmin(conf);Stringtablename=my_ns:mytable;if(admin.tableExists(tablename)tryadmin.disableTable(
13、tablename);admin.deleteTable(tablename);catch(Exceptione)/TODO:handleexceptione.printStackTrace();admin.close();说明:删除表前必须先disable表。4.修改表4.1.实例代码(1)删除列族、新增列族修改之前,四个列族:hbase(main):014:0 describe rd_ns:itableDESCRIPTION ENABLEDrd_ns:itable, NAME = info, DATA_BLOCK_ENCODING = NONE, BLOOMFILTER = ROW, RE
14、PLICATION_SCOPE = 0, V trueERSIONS = 10, COMPRESSION = NONE, MIN_VERSIONS = 0, TTL = 2147483647, KEEP_DELETED_CELLS = false,BLOCKSIZE = 65536, IN_MEMORY = false, BLOCKCACHE = true, NAME = newcf, DATA_BLOCK_ENCODING = NONE, BLOOMFILTER = ROW, REPLICATION_SCOPE = 0, COMPRESSION = NONE, VERSIONS = 10,
15、TTL = 2147483647,MIN_VERSIONS = 0, KEEP_DELETED_CELLS = false, BLOCKSIZE = 65536, IN_MEMORY = false, BLOCKCACHE = true, NAME = note, DATA_BLOCK_ENCODING = NONE, BLOOMFILTER = ROW, REPLICATION_SCOPE = 0, VERSIONS = 10, COMPRESSION = NONE, MIN_VERSIONS = 0, TTL = 2147483647, KEEP_DELETED_CELLS = false
16、, BLOCKSIZE= 65536, IN_MEMORY = false, BLOCKCACHE = true, NAME = sysinfo, DATA_BLOCK_ENCODING = NONE, BLOOMFILTER = ROW, REPLICATION_SCOPE = 0, COMPRESSION = NONE, VERSIONS = 10, TTL = 2147483647, MIN_VERSIONS = 0, KEEP_DELETED_CELLS = true, BLOCKSIZE = 65536, IN_MEMORY = false, BLOCKCACHE = true1 r
17、ow(s) in 0.0450 seconds修改表,删除三个列族,新增一个列族,代码如下: Configurationconf=HBaseConfiguration.create();HBaseAdminadmin=newHBaseAdmin(conf);Stringtablename=rd_ns:itable;if(admin.tableExists(tablename)tryadmin.disableTable(tablename);/gettheTableDescriptoroftargettableHTableDescriptornewtd=admin.getTableDescrip
18、tor(Bytes.toBytes(rd_ns:itable);/remove3uselesscolumnfamiliesnewtd.removeFamily(Bytes.toBytes(note);newtd.removeFamily(Bytes.toBytes(newcf);newtd.removeFamily(Bytes.toBytes(sysinfo);/createHColumnDescriptorfornewcolumnfamilyHColumnDescriptornewhcd=newHColumnDescriptor(action_log);newhcd.setMaxVersio
19、ns(10);newhcd.setKeepDeletedCells(true);/addthenewcolumnfamily(HColumnDescriptor)toHTableDescriptornewtd.addFamily(newhcd);/modifytargettablestrutureadmin.modifyTable(Bytes.toBytes(rd_ns:itable),newtd);admin.enableTable(tablename);catch(Exceptione)/TODO:handleexceptione.printStackTrace();admin.close
20、();修改之后:hbase(main):015:0 describe rd_ns:itableDESCRIPTION ENABLEDrd_ns:itable, NAME = action_log, DATA_BLOCK_ENCODING = NONE, BLOOMFILTER = ROW, REPLICATION_SCOPE = true0, COMPRESSION = NONE, VERSIONS = 10, TTL = 2147483647, MIN_VERSIONS = 0, KEEP_DELETED_CELLS = true, BLOCKSIZE = 65536, IN_MEMORY
21、= false, BLOCKCACHE = true, NAME = info, DATA_BLOCK_ENCODING = NONE, BLOOMFILTER = ROW, REPLICATION_SCOPE = 0, VERSIONS = 10, COMPRESSION = NONE, MIN_VERSIONS = 0, TTL = 2147483647, KEEP_DELETED_CELLS = false, BLOCKSIZE = 65536, IN_MEMORY = false, BLOCKCACHE = true1 row(s) in 0.0400 seconds逻辑很简单:1.
22、通过admin.getTableDescriptor(Bytes.toBytes(rd_ns:itable)取得目标表的描述对象,应该就是取得指向该对象的指针了;2. 修改目标表描述对象;3. 通过admin.modifyTable(Bytes.toBytes(rd_ns:itable),newtd)将修改后的描述对象应用到目标表。(2)修改现有列族的属性(setMaxVersions) Configurationconf=HBaseConfiguration.create();HBaseAdminadmin=newHBaseAdmin(conf);Stringtablename=rd_ns:
23、itable;if(admin.tableExists(tablename)tryadmin.disableTable(tablename);/gettheTableDescriptoroftargettableHTableDescriptorhtd=admin.getTableDescriptor(Bytes.toBytes(rd_ns:itable);HColumnDescriptorinfocf=htd.getFamily(Bytes.toBytes(info);infocf.setMaxVersions(100);/modifytargettablestrutureadmin.modi
24、fyTable(Bytes.toBytes(rd_ns:itable),htd);admin.enableTable(tablename);catch(Exceptione)/TODO:handleexceptione.printStackTrace();admin.close();5.新增、更新数据Put5.1.常用构造函数:(1)指定行键public Put(byte row)参数:row 行键(2)指定行键和时间戳public Put(byte row,long ts)参数:row 行键,ts 时间戳(3)从目标字符串中提取子串,作为行键Put(byte rowArray, int ro
25、wOffset, int rowLength)(4)从目标字符串中提取子串,作为行键,并加上时间戳Put(byte rowArray, int rowOffset, int rowLength, long ts)5.2.常用方法:(1)指定列族、限定符,添加值add(byte family, byte qualifier, byte value) (2)指定列族、限定符、时间戳,添加值add(byte family, byte qualifier, long ts, byte value)(3)设置写WAL(Write-Ahead-Log)的级别public void setDurabilit
26、y(Durability d)参数是一个枚举值,可以有以下几种选择: ASYNC_WAL : 当数据变动时,异步写WAL日志 SYNC_WAL : 当数据变动时,同步写WAL日志 FSYNC_WAL : 当数据变动时,同步写WAL日志,并且,强制将数据写入磁盘 SKIP_WAL : 不写WAL日志 USE_DEFAULT : 使用HBase全局默认的WAL写入级别,即SYNC_WAL5.3.实例代码(1)插入行 Configurationconf=HBaseConfiguration.create();HTabletable=newHTable(conf,rd_ns:leetable);Put
27、put=newPut(Bytes.toBytes(100001);put.add(Bytes.toBytes(info),Bytes.toBytes(name),Bytes.toBytes(lion);put.add(Bytes.toBytes(info),Bytes.toBytes(address),Bytes.toBytes(shangdi);put.add(Bytes.toBytes(info),Bytes.toBytes(age),Bytes.toBytes(30); put.setDurability(Durability.SYNC_WAL);table.put(put);table
28、.close();(2)更新行 Configurationconf=HBaseConfiguration.create();HTabletable=newHTable(conf,rd_ns:leetable);Putput=newPut(Bytes.toBytes(100001);put.add(Bytes.toBytes(info),Bytes.toBytes(name),Bytes.toBytes(lee);put.add(Bytes.toBytes(info),Bytes.toBytes(address),Bytes.toBytes(longze);put.add(Bytes.toByt
29、es(info),Bytes.toBytes(age),Bytes.toBytes(31); put.setDurability(Durability.SYNC_WAL);table.put(put); table.close();注意:1. Put的构造函数都需要指定行键,如果是全新的行键,则新增一行;如果是已有的行键,则更新现有行。2. 创建Put对象及put.add过程都是在构建一行的数据,创建Put对象时相当于创建了行对象,add的过程就是往目标行里添加cell,直到table.put才将数据插入表格;3. 以上代码创建Put对象用的是构造函数1,也可用构造函数2,第二个参数是时间戳;
30、4. Put还有别的构造函数,请查阅官网API。(3)从目标字符串中提取子串,作为行键,构建Put Configurationconf=HBaseConfiguration.create();HTabletable=newHTable(conf,rd_ns:leetable);Putput=newPut(Bytes.toBytes(100001_100002),7,6);put.add(Bytes.toBytes(info),Bytes.toBytes(name),Bytes.toBytes(show);put.add(Bytes.toBytes(info),Bytes.toBytes(add
31、ress),Bytes.toBytes(caofang);put.add(Bytes.toBytes(info),Bytes.toBytes(age),Bytes.toBytes(30);table.put(put);table.close();注意,关于:Putput=newPut(Bytes.toBytes(100001_100002),7,6)1. 第二个参数是偏移量,也就是行键从第一个参数的第几个字符开始截取;2. 第三个参数是截取长度;3. 这个代码实际是从 100001_100002 中截取了100002子串作为目标行的行键。6.删除数据Delete Delete类用于删除表中的一
32、行数据,通过HTable.delete来执行该动作。 在执行Delete操作时,HBase并不会立即删除数据,而是对需要删除的数据打上一个“墓碑”标记,直到当Storefile合并时,再清除这些被标记上“墓碑”的数据。 如果希望删除整行,用行键来初始化一个Delete对象即可。如果希望进一步定义删除的具体内容,可以使用以下这些Delete对象的方法: 为了删除指定的列族,可以使用deleteFamily 为了删除指定列的多个版本,可以使用deleteColumns 为了删除指定列的指定版本,可以使用deleteColumn,这样的话就只会删除版本号(时间戳)与指定版本相同的列。如果不指定时间戳
33、,默认只删除最新的版本 下面详细说明构造函数和常用方法:6.1.构造函数(1)指定要删除的行键Delete(byte row)删除行键指定行的数据。如果没有进一步的操作,使用该构造函数将删除行键指定的行中所有列族中所有列的所有版本!(2)指定要删除的行键和时间戳Delete(byte row, long timestamp)删除行键和时间戳共同确定行的数据。如果没有进一步的操作,使用该构造函数将删除行键指定的行中,所有列族中所有列的时间戳小于等于指定时间戳的数据版本。注意:该时间戳仅仅和删除行有关,如果需要进一步指定列族或者列,你必须分别为它们指定时间戳。(3)给定一个字符串,目标行键的偏移,
34、截取的长度Delete(byte rowArray, int rowOffset, int rowLength)(4)给定一个字符串,目标行键的偏移,截取的长度,时间戳Delete(byte rowArray, int rowOffset, int rowLength, long ts)6.2.常用方法 Delete deleteColumn(byte family, byte qualifier) 删除指定列的最新版本的数据。 Delete deleteColumns(byte family, byte qualifier) 删除指定列的所有版本的数据。 Delete deleteColum
35、n(byte family, byte qualifier, longtimestamp) 删除指定列的指定版本的数据。 Delete deleteColumns(byte family, byte qualifier, longtimestamp) 删除指定列的,时间戳小于等于给定时间戳的所有版本的数据。 Delete deleteFamily(byte family) 删除指定列族的所有列的所有版本数据。 Delete deleteFamily(byte family, long timestamp) 删除指定列族的所有列中时间戳小于等于指定时间戳的所有数据。 Delete deleteF
36、amilyVersion(byte family, long timestamp) 删除指定列族中所有列的时间戳等于指定时间戳的版本数据。 voidsetTimestamp(long timestamp) 为Delete对象设置时间戳。6.3.实例代码(1)删除整行的所有列族、所有行、所有版本 Configurationconf=HBaseConfiguration.create();HTabletable=newHTable(conf,rd_ns:leetable);Deletedelete=newDelete(Bytes.toBytes(000);table.delete(delete);
37、table.close();(2)删除指定列的最新版本以下是删除之前的数据,注意看100003行的info:address,这是该列最新版本的数据,值是caofang1,在这之前的版本值是caofang:hbase(main):007:0 scan rd_ns:leetableROW COLUMN+CELL100001 column=info:address, timestamp=1405304843114, value=longze100001 column=info:age, timestamp=1405304843114, value=31100001 column=info:name,
38、 timestamp=1405304843114, value=leon100002 column=info:address, timestamp=1405305471343, value=caofang100002 column=info:age, timestamp=1405305471343, value=30100002 column=info:name, timestamp=1405305471343, value=show100003 column=info:address, timestamp=1405390959464, value=caofang1100003 column=
39、info:age, timestamp=1405390959464, value=301100003 column=info:name, timestamp=1405390959464, value=show13 row(s) in 0.0270 seconds执行以下代码: Configurationconf=HBaseConfiguration.create();HTabletable=newHTable(conf,rd_ns:leetable);Deletedelete=newDelete(Bytes.toBytes(100003);delete.deleteColumn(Bytes.toBytes(info),Bytes.toBytes(address);table.delete