单机配置HBase的心得

使用HBase的原因

同学的科研中会处理卫星遥感图片,数据量很大,而一台机器的内存和硬盘不够用来处理,所以他的科研成果受到了一定的限制,我打算帮他做一个存储中间件,希望通过一个集群和简单好用的API来帮助提高科研效果。

如何配置HBase

我相信类似的文章肯定很多了,所以我不需要把我自己的过程再写一遍。大概就是先安装配置HDFS(HaDoop File System), 这个基础设施建设要以后,再安装配置HBase, 要知道HBase是一个运行在HDFS上的应用程序。

配置Hadoop用的Hadoop的官方文档,还挺好用的,没什么坑,配HBase也是用的官方文档 ,一样没毛病。如果你跟着文档走,基本上单机的HBase能够很好跑起来;当然你需要一个mac或者linux,windows就不能保证结果了。

如果你顺利的话,到最后会用

sbin/start-dfs.sh

来启动HDFS,用

sbin/stop-dfs.sh

来关闭HDFS;用

./bin/start-hbase.sh

来启动HBase,用

./bin/stop-hbase.sh

来关闭HBase。同样你也会用jps 来查看当前整个Hadoop相关的软件的运行情况。我很建议你顺着文档把小细节都过下来,虽然有些用不到,但会让你对整个Hadoop更有了解。

把HBase加入业务逻辑

我们需要做对是key-value pair的大规模存储,语言是Java,我参考的文章是这个 。由于我经常用Berkeley DB做简易数据存储,对于NoSQL的存储方式已经很熟悉了,简单来说就是用分级别的索引来存储object。一个object 可以有多个级别的索引,当然,一般简单起见都只用第一级别的索引,比如一个类是这样的:

class Account {
    String account;
    String password;
}

Berkeley DB就是把这个类的实例存到磁盘上,不要你去思考转移成SQL里面的表。一个Account类,一般会用account这个变量作为索引,加好annotation 的类是这样的:

@Entity
class Account {
    @PrimaryIndex
    String account;
    String password;
}

如果你存了一个account是”TOM”, password是”123” 的实例进入数据库,用index.get(“TOM”), 就能够把这个对象提取出来, 数据库会提供index的factory,总之看到这里我相信读者能理解NoSQL大概的样子。

HBase里的数据组织方法和Berkeley DB略有不同,它的第一级索引叫做row,数据类型是byte[]. 第二级索引叫family, 第三级索引叫qualifier. 由于我们的业务逻辑比较简单,只要存key-value, 所以我让所有存储的记录都用同样的family和qualifier, 让row成为唯一区分他们的东西。

重写的代码

Baeldung.com/hbase 里面的代码跟我自己的整合之后发现了一个问题。我要存储的是key-value pair, key和value都是String类型,而HBase里规定row(就是key)的数据类型是byte[], baeldung的样例代码里用了HBase的库里的一个Bytes.toBytes(string) 方法来把字符串转化成byte array. 但是两个有相同值的string literal,传入这个方法以后得到的结果不一样,导致我无法从HBase里面提取出数据,这就让我必须要重写toBytes() 方法和 Bytes.toString() 方法。

重写是简单的,只要遵从自己统一好的规定就行,由于我的key都是数字加空格,value都是数字,我直接把string里每一个char映射成它对应ASCII值,这就完成了toBytes() 方法;转回来就是从ASCII值回到字符的过程。

可能读者会对于我遇到的问题不是很懂,那我这里仔细讲一下,看懂的读者可以略过这一段。

table.put(Bytes.toBytes('key1'), Bytes.toBytes('value1'));

假设我们是用上面这一行代码向HBase里存入object的,再用

table.get(Bytes.toBytes('key1'));

去取这个object的时候会返回null。

为了解释这个问题,我特意写了另外一个测试程序:

System.out.println(Bytes.toBytes('key1'));
System.out.println(Bytes.toBytes('key2'));

发现输出是两个东西,他们的哈希值不一样,可能Bytes这个类就是按照哈希值来判断两个object是否相等,而新建的string literal再转化成byte[], 肯定是有不同的哈希值,所以会出错;我的代码跟哈希值无关,所以就容易成功。

你可能感兴趣的:(Hadoop,HBase)