HBase实现谷粒微博案例
前言
最近刚刚在b站上看完了尚硅谷hbase相关课程,在这里记录一下,完成这个项目遇到的坑,以及案例结果(而且不要吐槽的英语注释,我是个英语渣,大家尽量意会一下…)。如果博客有什么不对的地方,欢迎大佬指正。
一、启动集群
由于HBase是基于hadoop的一个非结构化数据库,所以需要启动hadoop集群,并且还需要启动我们的“润滑器” zookeeper。
我使用的版本是
CentOS 6
Hadoop 3
HBase 3
Zookeeper 3 (每一个虚拟机都要启动zookeeper)
虚拟机一共三台,分别是hadoop102,hadoop103,hadoop104
编译器使用的是IDEA。
二、功能实现
1.创建工程
这里我只是给出代码以及一些相关解释,具体的需求分析以及更加详细的解释,可以看后面的参考链接,我将会给出b站尚硅谷视频的链接,有兴趣的可以去看看。
打开IDEA,创建一个新的maven工程,然后进行pom.xml格式如下。这里是需要导入相关的依赖包,以及各种依赖的版本,build一下就会开始进行下载。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>HBase</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>guli-weibo</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
</project>
然后在工程中创建5个文件夹(其中一个是空的,也可以不创建),后续需要添加代码。如图:
ok,现在我们就可以快乐的编写代码了。
2.constants包
在这里我们定义的是一些常量,例如是命名空间、表明、列名等,以便后面我们需要使用的时候反复重写,防止写错,也可以进行一个解耦合。
package constants;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
public class Constants {
public static Configuration CONFIGURATION = null;
// HBase setting 这里不知道为什么要这要写才可以,视频里面没有写这个也可以运行,
// 但是我就会报错,说无法连接,希望有大佬可以解释一下。
// 那个set里面第二个放的是你们集群的名称,可能会不一样,看你们自己的命名了。
static {
CONFIGURATION = HBaseConfiguration.create();
CONFIGURATION.set("hbase.zookeeper.quorum", "hadoop102,hadoop103,hadoop104");
}
// HBase namespace 这个是命名空间
public static final String NAMESPACE = "weibo";
// weibo content table 这个是内容表
public static final String CONTENT_TABLE = "weibo:content";
public static String CONTENT_TABLE_CF = "info";
public static int CONTENT_TABLE_VERSIONS = 1;
// user relationship table 这个是关系表
public static final String RELATION_TABLE = "weibo:relation";
public static final String RELATION_TABLE_CF1 = "attends";
public static final String RELATION_TABLE_CF2 = "fans";
public static final int RELATION_TABLE_VERSIONS = 1;
// receipt email box 这个是收件表
public static final String INBOX_TABLE = "weibo:inbox";
public static final String INBOX_TABLE_CF = "info";
public static final int INBOX_TABLE_VERSIONS = 2;
}
3.utils包
这里主要是进行DDL的操作,例如创建命名空间,以及对表之类的操作。
代码总览,下面再分段解释:
package utils;
import constants.Constants;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import java.io.IOException;
/**
* 1 create namespace
* 2 judge table exist or not
* 3 create three tables
* 4
*/
public class HBaseUtil {
// 1 create namespace
public static void createNameSpace(String namespace) throws IOException {
// 1 get the connection object
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2 get the admin object
Admin admin = connection.getAdmin();
// 1 create namespace description
NamespaceDescriptor build = NamespaceDescriptor.create(namespace).build();
// 2 create namespace
admin.createNamespace(build);
// 3 close resource
admin.close();
connection.close();
}
// 2 judge the table exist or not
private static boolean isTableExist(String tableName) throws IOException {
// 1 get the connection object
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2 get the admin object
Admin admin = connection.getAdmin();
// 3 judge the table exist or not
boolean result = admin.tableExists(TableName.valueOf(tableName));
// 4 close resource
admin.close();
connection.close();
// return value
return result;
}
// 3 create table
public static void createTable(String tableName, int versions, String... cfs) throws IOException {
// 1 judge the command value
if (cfs.length <= 0) {
System.out.println("column information is not available.");
return ;
}
// 2 judge the table exist or not
if (isTableExist(tableName)) {
System.out.println(tableName + "table is exist.");
return;
}
// 3 get the connection object
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 4 get the admin object
Admin admin = connection.getAdmin();
// 5 create table description
HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));
// 6 cycle add column information
for (String cf : cfs) {
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(cf);
// 7 set the version
hColumnDescriptor.setMaxVersions(versions);
hTableDescriptor.addFamily(hColumnDescriptor);
}
// 8 create table
admin.createTable(hTableDescriptor);
// close resource
admin.close();
connection.close();
}
}
3.1 createNameSpace 创建命名空间
// 1 create namespace
public static void createNameSpace(String namespace) throws IOException {
// 1 get the connection object 创建一个连接的对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2 get the admin object 创建一个admin的对象,
// 对hbase操作基本上通admin来操作
Admin admin = connection.getAdmin();
// 1 create namespace description 创建一个命名空间的解释器
NamespaceDescriptor build = NamespaceDescriptor.create(namespace).build();
// 2 create namespace 创建命名空间
admin.createNamespace(build);
// 3 close resource 关闭资源
admin.close();
connection.close();
}
3.2 isTableExist 判断表是否存在
// 2 judge the table exist or not
private static boolean isTableExist(String tableName) throws IOException {
// 1 get the connection object
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2 get the admin object
Admin admin = connection.getAdmin();
// 3 judge the table exist or not.
// tableExists这个函数是需要传入TableName参数的,所以需要转换。
boolean result