学习Hadoop时,了解一些有关NoSQL的知识,今天一个实验就有关Hbase。这部分不是重点,掌握Shell控制方法就足够了,不过我还是希望尝试一下用Java API进行控制。还是上次的理由(再Cue一次Surface渣性能),下面记录一下如何配置才能在Windows上远程连接虚拟机中的HBase,并进行操作。
我虚拟机中安装的Hadoop版本为2.7.7,Hbase与Hadoop的版本有一定兼容性要求,这里选择Hbase 2.2.6版本。
下载之后将其解压到/usr/local(你自己定),然后配置环境变量,修改权限:
vi ~/.bashrc
# 以下为添加内容
export HBASE_HOME=/usr/local/hbase
export PATH=${HBASE_HOME}/bin:$PATH
# 修改完成后
source ~/.bashrc
# 修改权限
cd /usr/local
sudo chown -R 你的用户名 ./hbase
# 检查配置是否成功
hbase version
注意,如果你同时设置过HADOOP_HOME和HBASE_HOME的环境变量,并添加到PATH中,那么运行hbase version时很可能会给你出一些警告,告诉你有一些jar包“Found binding”(一般是SLF4J),意思是Hadoop目录下和Hbase目录下都有,冲突了。
你只需要将Hbase的那个版本删除,或者重命名成.bak的就可以了
由于Hadoop是伪分布式配置的,因此HBase与其保持一致。
/usr/local/hbase/conf/hbase-env.sh
export JAVA_HOME=${JAVA_HOME}
export HBASE_CLASSPATH=/usr/local/hadoop/conf
export HBASE_MANAGES_ZK=true
/usr/local/hbase/conf/hbase-site.xml
,在其
部分如下配置:<Configuration>
<property>
<name>hbase.cluster.distributedname>
<value>truevalue>
property>
<property>
<name>hbase.master.ipc.addressname>
<value>0.0.0.0value>
property>
<property>
<name>hbase.regionserver.ipc.addressname>
<value>0.0.0.0value>
property>
<property>
<name>hbase.rootdirname>
<value>hdfs://192.168.1.29:9000/hbasevalue>
property>
<property>
<name>hbase.zookeeper.quorumname>
<value>192.168.1.29:2181value>
property>
Configuration>
注意将192.168.1.29
替换为你虚拟机的ip(虚拟机和主机使用桥接),另外保证hadoop那边core-site.xml的设置也是使用的ip,而不是localhost。
这是十分重要的一步,不要跳过。
主机名就是shell里面你用户名后面@的那个名字,比如root@Morphlng的Morphlng,我们需要将其修改为master,对于ubuntu来说:
vi /etc/hostname
将其中的名字修改为master
这一步的目的是映射ip与hostname:
vi /etc/hosts
# 添加映射关系
192.168.1.29 master
修改完成后,重启虚拟机
在C:\Windows\System32\drivers\etc\hosts
,同样向其中加入192.168.1.29 master。
HBase启动后会运行在主节点的16000端口,如果不作上述设置,那么他将运行在localhost/127.0.0.1:16000
,然后你远程调用时就会出现连接失败:
org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000
它本机地址你当然连不上去了,所以我们要把主节点手动映射到一个可以访问的ip上去。
首先需要启动hadoop,start-dfs.sh
,输入jps成功看到4项后表示启动成功。然后再启动Hbase,start-hbase.sh
,再次输入jps,看到7项就成功了。
我们首先检查一下用hbase shell会不会有问题:
hadoop@master:~$ hbase shell
hbase(main):001:0> create "test_table","test_column"
如果成功创建表test,那么Hbase的配置截止于此都没有问题。
这里各位可能会遇到创建表失败的问题,其错误提示如下:
org.apache.hadoop.hbase.PleaseHoldException: Master is initializing
这个问题网上有一堆解决方法,鉴于我们是学习环境没什么重要资料,所以最快捷简单的方法就是:
hbase zkcli
,进入Zookeeper的控制台,ls /
查看文件,将其中的hbase删除,即rmr /hbase
hdfs dfs -ls /
,查看hdfs中的文件,将其中的hbase删除,即hdfs dfs -rm -r /hbase
老朋友了,不过这次没有插件可以方便我们用了(或者有我没找hhh),需要手动导包。
我们首先需要把与虚拟机中安装的相同版本的Hbase解压到Windows的一个目录下,然后进行下面的操作
新建一个Java项目,书写项目名称后点击Next,在Libraries里面点击ClassPath,然后Add Library:
选择User Library,点击右侧的User Libraries,在这里我们New一个新的包资源:
点击Add External JARs,然后把/hbase/lib
下的所有jar包都添加进来即可。
给各位一个测试用的代码:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import java.io.IOException;
public class ExampleforHbase {
public static Configuration configuration;
public static Connection connection;
public static Admin admin;
public static void main(String[] args)throws IOException {
// 创建一个表,表名Score,列族为sname,course
createTable("Score",new String[]{
"sname","course"});
}
// 建立连接
public static void init()
{
// 注意修改此处的ip为你虚拟机的ip
configuration = HBaseConfiguration.create();
configuration.set("hbase.rootdir", "hdfs://192.168.1.29:9000/hbase");
configuration.set("hbase.zookeeper.quorum", "192.168.1.29:2181");
configuration.set("hbase.master", "192.168.1.29:16000");
configuration.setInt("timeout", 120000);
try {
connection = ConnectionFactory.createConnection(configuration);
admin = connection.getAdmin();
}catch(IOException e)
{
e.printStackTrace();
}
}
// 关闭连接
public static void close()
{
try {
if(admin!=null)
{
admin.close();
}
if(null!=connection)
{
connection.close();
}
}catch(IOException e)
{
e.printStackTrace();
}
}
public static void createTable(String myTableName,String[] colFamily)throws IOException{
init();
TableName tableName = TableName.valueOf(myTableName);
if(admin.tableExists(tableName)) {
System.out.println("table is exists!");
}else {
HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
for(String str:colFamily) {
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
hTableDescriptor.addFamily(hColumnDescriptor);
}
admin.createTable(hTableDescriptor);
System.out.println("create table success");
}
close();
}
}
运行结果如下: