今天刚刚过完HBase入门阶段,本来应该周内搞完的,但中途自己的电脑配置太低了以至于虚拟机开个IDEA都卡到爆...好在室友的电脑可用,比预期慢了三天左右完成入门,但学的还算扎实,现就一些常用的程序搞个总结以供以后参考使用。
1. project配置:IDEA创建maven project,在main目录下的resource中添加hbase-site.xml文件,同时project加入hbase安装目录下lib目录到libraries目录,在pom.xml配置文件中加入有关hbase-server和hbase-client的dependency说明(以供maven下载相应的jar包),注意要和系统使用的HBase版本保持一致。
org.apache.hbase
hbase-server
2.0.0
org.apache.hbase
hbase-client
2.0.0
2. 连接HBase
一般情况下,在类中会将连接过程直接作为静态方法使用static(其他HBase操作方法都会使用到这些过程),configuration、connection、admin对象也都会使用到,因此多提出来作为private static全局静态变量使用。connection和admin的资源关闭也可以新建一个static方法完成,其余方法直接调用即可。(Java中,static方法只能调用static方法,非static方法可调用static方法,多多学习提高代码的可复用性、可读性和可移植性)
首先创建Configuration对象,完成配置,对configuration对象使用set方法配置连接zookeeper的quorum和clientPort。(HBase数据访问主要是客户端通过ZooKeeper访问RegionServer完成的,和Master没啥关系,因此没有对master的配置)
其中,quorum为HBase服务器的hostname或者ip地址(集群的话写每个服务器的ip/hostname即可,用逗号隔开);clientPort为ZooKeeper访问端口,一般为2181(一般需要在hbase-site.xml中有配置,自行百度)
创建好配置Configuration对象后,创建Connection连接对象,建立和HBase数据库的连接(过程其实和关系型数据连接配置过程相似)
最后创建Admin对象即客户端管理员对象,其后的HBase数据库操作基本全是由Admin发出。
注意:connection和admin均占用系统资源,在使用完以后一定注意使用close方法关闭资源,以免造成资源短缺。
创建表名对象TableName,使用HBase API中的tableExists()方法查看获取boolean值完成表是否存在的判断。
首先判断表是否存在,若存在则直接返回不再执行后续代码,若不存在则新建HTableDescriptor对象和HColumnDescriptor对象,新建HColumnDescriptor对象加入cf列族(可使用for循环加入多个列族),将HColumnDescriptor对象通过addFamily方法加入到HTableDescriptor对象中,最后使用HBase API中的createTable方法完成表的创建。
首先判断表是否不存在,若不存在则直接返回,若存在则调用HBase API中的disableTable方法和deleteTable方法完成表的删除操作。注意一定要先disable掉表再deleteTable,否则会直接报错。
这里还需要注意的一点是需要先判断这个表的状态是否为enabled的,如果是的话先disable再delete,不是的话则直接delete;不判断统一disable再delete处理的话万一遇到本身disable的表在做disable操作的时候会直接报错。
通过Connection对象的getTable方法建立Table对象,然后以rowkey为参数创建一个put对象,并对这个put对象调用addColumn方法,最后调用Table对象的put方法,将put对象加入到table对象中即可。注意更新数据在HBase中也是增加一条数据,只是这条数据的版本更高一点。同时在HBase中数据都是以byte[]字节数组的形式存储的,因此需要通过Bytes.toBytes方法进行数据类型转换。
分为删除整行、删除整个列族、删除某列的最新版本/指定版本、删除某列的所有版本。流程为创建Table对象,以rowkey为参数创建delete对象,通过addColumns方法对delete对象添加删除的目标,最后通过table对象调用以delete对象为参数的delete方法完成数据删除。注意delete删除表的具体某个列时需要明确addColumns方法和addColumn方法的不同,前者是删除该列的所有版本,后者是删除该列数据的最新版本或添加ts时间参数删除某个指定版本。一般生产环境中使用前者。
七、全表扫描scan
创建table对象、创建scan对象,以scan对象为参数通过table对象的 getScanner方法获取全表扫描集合ResultScanner对象(一个集合),通过for循环获取scanner对象的cell数组(行键:列族:列:版本号)和row(byte[]字节数组类型)(对Results集合遍历后获得的Result数据同样可拆分为rowkey和cell数组,本身也是一个集合),最后通过对cell数组遍历打印出全表所有的数据(通过CellUtil类的cloneRow、cloneFamily、cloneQualifier、cloneValue获取数据的行键、列族、列和值。注意此处cloneXXX方法获取的是byte[]字节数组类型数据,如果需要直接打印则要做Bytes.toString方法的类型转换
创建table对象,以rowkey为参数创建get对象,为get对象通过addColumn方法添加列族、列的查询限制。以get对象为参数通过table对象的get方法获取Result对象,对result对象使用rawCells方法获取Cell单元格数组,对其进行遍历获取打印get目标行键目标列族目标列的所有数据。注意也可只定义到get对象,不添加cf和cn的限制遍历获取目标rowkey一整行的数据,也可以通过addFamily方法查询某列族所有列的所有数据。
其实总的来看,方法都挺简单的,但是还是需要多多练习,熟练掌握HBase API的使用,多多参考官方API文档掌握最新版本的API使用方法,使自己的代码质量更高。
当然此处的这些方法在适当的时候需要根据实际情况需要对参数、返回类型、方法内容等等进行更新修改,但是例如throws IOException和HBase数据库连接等基本的还是需要牢牢掌握。
回顾整个HBase入门阶段,不到两周时间,学的还算不错,后续升级阶段和运维阶段也要继续加油呀!