Hbase 项目
需求分析
表结构
代码实现
项目结构
pom.xml 文件:
<?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">
<modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId>
<artifactId>hbase-pro</artifactId>
<version>1.0-SNAPSHOT</version> <properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency> <dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency> <dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>2.4.4</version>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency> <dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.3.1</version>
</dependency> <dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.3.1</version>
</dependency> </dependencies> </project>
1. 常量类 Constants
package deng.com.constants; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration; public class Constants {
// HBase 的配置信息
public static final Configuration CONFIGURATION = HBaseConfiguration.create();
static {
CONFIGURATION.set("hbase.zookeeper.quorum", "192.168.10.102");
CONFIGURATION.set("hbase.zookeeper.property.clientPort", "2181");
}
// 命名空间
public static final String NAMESPACE="weibo";
// 微博内容表
public static final String CONTENT_TABLE="weibo:content";
public static final String CONTENT_TABLE_CF="info";
public static final int CONTENT_TABLE_VERSIONS=1;
// 用户关系表
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;
// 收件箱表
public static final String INBOX_TABLE="weibo:info";
public static final String INBOX_TABLE_CF="info";
public static final int INBOX_TABLE_VERSIONS=2; }
2. HBaseUtils 类(创建表,判断表是否存在等)
package deng.com.utils; import deng.com.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 java.io.IOException; public class HBaseUtils { //创建命名空间
public static void createNameSpace(String nameSpace) throws IOException {
// 1. 获取连接对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2. 获取admin
Admin admin = connection.getAdmin();
// 3. 构建命名空间描述器
NamespaceDescriptor namespaceDescriptor = NamespaceDescriptor.create(nameSpace).build();
// 4. 创建命名空间
admin.createNamespace(namespaceDescriptor);
// 5. 关闭资源
admin.close();
connection.close();
} // 2. 判断表是否存在
private static boolean isTableExist(String tableName) throws IOException {
// 1. 获取连接对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2. 获取admin
Admin admin = connection.getAdmin();
// 3.判读是否存在
boolean b = admin.tableExists(TableName.valueOf(tableName));
// 4. 关闭资源
admin.close();
connection.close();
return b;
} // 3. 创建表
public static void createTable(String tableName, int versions, String... cf) throws IOException {
// 判读是否传入了列族信息
if (cf.length <= 0) {
System.out.println("请传入列族信息");
return;
} // 判断表是否存在
if (isTableExist(tableName)) {
System.out.println(tableName + "表已存在");
return;
} // 1. 获取连接对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 2. 获取admin
Admin admin = connection.getAdmin();
// 3. 创建表描述器
HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf(tableName));
// 4. 循环添加列族信息
for (String s : cf) {
// 获取列族描述器
HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(s);
// 设置版本
hColumnDescriptor.setMaxVersions(versions);
hTableDescriptor.addFamily(hColumnDescriptor); } // 创建表
admin.createTable(hTableDescriptor);
admin.close();
connection.close();
}
}
3. HbaseDao类(业务操作)
package deng.com.dao; /*
* 1.发布微博
* 2. 删除微博
* 3. 关注用户
* 4. 取关用户
* 5.获取用户微博详情
* 6.获取用户的初始页面
*/ import com.sun.xml.internal.bind.v2.runtime.reflect.opt.Const;
import deng.com.constants.Constants;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.filter.CompareFilter;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SubstringComparator;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.yarn.webapp.hamlet.HamletSpec; import java.io.IOException;
import java.util.ArrayList; public class HBaseDao {
// 1. 发布微博
public static void publishWeiBo(String uuid, String content) throws IOException {
// 获取Connection 对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 第一部分 操作微博内容表 // 获取微博内容表对象
Table conTable = connection.getTable(TableName.valueOf(Constants.CONTENT_TABLE));
// content 表的rowkey 是用户id+时间戳
// 获取当前时间
long ts = System.currentTimeMillis();
// 拼接rowKey
String rowKey = uuid + "_" + ts;
// 创建Put 对象
Put conPut = new Put(Bytes.toBytes(rowKey));
// 给put 对象赋值
conPut.addColumn(Bytes.toBytes(Constants.CONTENT_TABLE_CF), Bytes.toBytes("content"), Bytes.toBytes(content)); // 插入数据
conTable.put(conPut); // 第二部分 操作微博收件箱表
// 1. 获取用户关系表对象
Table relationTable = connection.getTable(TableName.valueOf(Constants.RELATION_TABLE));
// 2. 获取当前发布微博人的fans列族数据
Get get = new Get(Bytes.toBytes(uuid));
get.addFamily(Bytes.toBytes(Constants.RELATION_TABLE_CF2)); // 指定fans 那个列族
Result result = relationTable.get(get);
// 创建一个集合用于存放微博内容表Put对象
ArrayList<Put> inboxPuts = new ArrayList<>();
Cell[] cells = result.rawCells();
// 遍历粉丝
for (Cell cell : cells) {
// 构建微博收件箱表的put对象
Put inboxPut = new Put(CellUtil.cloneQualifier(cell));
// 给收件箱的putd对象赋值
inboxPut.addColumn(Bytes.toBytes(Constants.INBOX_TABLE_CF), Bytes.toBytes(uuid), Bytes.toBytes(rowKey));
// 收件箱表的put对象存入表中
inboxPuts.add(inboxPut); }
// 判断是否有粉丝
if (inboxPuts.size() > 0) {
// 获取收件箱表对象
Table inboxTable = connection.getTable(TableName.valueOf(Constants.INBOX_TABLE));
//执行收件箱表数据插入
inboxTable.put(inboxPuts);
// 关闭收件箱表
inboxTable.close();
}
// 关闭资源
relationTable.close();
conTable.close();
connection.close(); } public static void addAttends(String uuid, String... attends) throws IOException {
// 校验
if (attends.length <= 0) {
System.out.println("请选择关注的人!");
return;
}
// 第一部分:操作用户关系表
//1. 获取用户关系表对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
Table relaTable = connection.getTable(TableName.valueOf(Constants.RELATION_TABLE)); //2. 创建一个集合用于存放用户关系表对象
ArrayList<Put> relaPuts = new ArrayList<>();
//3. 创建操作者的Put对象
Put uuidPut = new Put(Bytes.toBytes(uuid));
//4. 循环创建被关注者的put 对象
for (String attend : attends) { //5. 给操作者put 对象赋值
uuidPut.addColumn(Bytes.toBytes(Constants.RELATION_TABLE_CF1), Bytes.toBytes(attend), Bytes.toBytes(attend));
//6. 创建被关注者的put对象
Put attendPut = new Put(Bytes.toBytes(attend));
//7. 给被关注者对象赋值
attendPut.addColumn(Bytes.toBytes(Constants.RELATION_TABLE_CF2), Bytes.toBytes(uuid), Bytes.toBytes(uuid));
//8. 将被关注者对象放入集合
relaPuts.add(attendPut);
} //9 .将操作者的put对象添加至集合
relaPuts.add(uuidPut); //10. 执行用户关系表的插入操作
relaTable.put(relaPuts); // 第二部分:收件箱表
// 1. 获取微博内容表对象
Table conTable = connection.getTable(TableName.valueOf(Constants.CONTENT_TABLE));
// 2. 创建收件箱表的put对象
Put inboxPut = new Put(Bytes.toBytes(uuid));
// 3. 循环attends 获取每个被关注者近期发布的微博内容
for (String attend : attends) {
// 4. 获取当前被关注近期发布的微博内容
Scan scan = new Scan(Bytes.toBytes(attend + "_"), Bytes.toBytes(attend + "|"));// startrow ,endrow
ResultScanner resultScanner = conTable.getScanner(scan);
// 定义一个时间戳
long ts = System.currentTimeMillis();
//5. 对获取的值进行遍历
for (Result result : resultScanner) {
// 6. 给收件箱表put 对象赋值
inboxPut.addColumn(Bytes.toBytes(Constants.INBOX_TABLE_CF), Bytes.toBytes(attend), ts++, result.getRow()); }
//7. 判断当前的put的对象是否为空
if (!inboxPut.isEmpty()) {
// 获取收件箱表对象
Table inboxTable = connection.getTable(TableName.valueOf(Constants.INBOX_TABLE));
// 插入数据
inboxTable.put(inboxPut);
// 关闭资源
inboxTable.close();
}
// 关闭资源
conTable.close();
relaTable.close();
connection.close(); }
} // 取关
public static void delAttends(String uid, String... dels) throws IOException {
if(dels.length<=0){
System.out.println("请添加取关用户!");
return;
}
//获取连接对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 第一部分:操作用户关系表
// 1. 获取用户关系表对象
Table relTable = connection.getTable(TableName.valueOf(Constants.RELATION_TABLE));
// 2. 创建一个集合,用户存放用户关系表的delete对象
ArrayList<Delete> relDeletes = new ArrayList<>();
// 3. 创建操作delete对象
Delete uidDelete = new Delete(Bytes.toBytes(uid));
// 4. 循环创建被取关的delete对象
for (String del : dels) {
// 5. 给操作者delete对象赋值
uidDelete.addColumns(Bytes.toBytes(Constants.RELATION_TABLE_CF1), Bytes.toBytes(del));
// 6. 创建被取关者的delete对象
Delete delDelete = new Delete(Bytes.toBytes(del));
// 7. 给被取关者delete对象赋值
delDelete.addColumns(Bytes.toBytes(Constants.RELATION_TABLE_CF2), Bytes.toBytes(uid));
// 8. 将被取关者delete对象添加至集合
relDeletes.add(delDelete); }
// 9. 将操作者的Delete对象添加至集合
relDeletes.add(uidDelete);
// 10.执行删除操作
relTable.delete(relDeletes); // 第二部分:操作收件箱表
// 1. 获取收件箱表对象
Table inboxTable = connection.getTable(TableName.valueOf(Constants.INBOX_TABLE));
// 2. 创建操作者的delete对象
Delete inboxDelete = new Delete(Bytes.toBytes(uid)); // 3. 给操作者的delete 对象赋值
for (String del : dels) {
inboxDelete.addColumns(Bytes.toBytes(Constants.INBOX_TABLE_CF), Bytes.toBytes(del)); }
// 4. 执行收件箱表删除操作
inboxTable.delete(inboxDelete); // 5. 关闭资源
inboxTable.close();
relTable.close();
connection.close();
}
// 获取某人的初始化页面数据
public static void getInt(String uid) throws IOException {
//获取connection 对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 1. 收件箱表对象
Table inboxTable = connection.getTable(TableName.valueOf(Constants.INBOX_TABLE)); // 2. 获取内容表对象
Table conTable = connection.getTable(TableName.valueOf(Constants.CONTENT_TABLE));
// 3. 创建收件箱表的Get对象,并获取数据(set最大版本获取)
Get inboxGet = new Get(Bytes.toBytes(uid));
inboxGet.setMaxVersions();
// 4. 获取该get对象的内容
Result result = inboxTable.get(inboxGet);
// 5. 遍历获取到数据
for (Cell cell : result.rawCells()) {
// 6. 构建微博内容表get对象
Get conGet = new Get(CellUtil.cloneValue(cell));
// 7. 获取该get对象的内容
Result result1 = conTable.get(conGet);
// 8. 解析并打印
for (Cell rawCell : result1.rawCells()) {
System.out.println(
"RK:"+Bytes.toString(CellUtil.cloneRow(rawCell))+","+
"CF:"+Bytes.toString(CellUtil.cloneFamily(rawCell))+","+
"cn:"+Bytes.toString(CellUtil.cloneQualifier(rawCell))+","+
"value:"+Bytes.toString(CellUtil.cloneValue(rawCell))
);
} }
//6. 关闭资源
inboxTable.close();
conTable.close();
connection.close(); }
// 获取某人的所有微博详情
public static void getWeiBo(String uid) throws IOException {
// 获取连接对象
Connection connection = ConnectionFactory.createConnection(Constants.CONFIGURATION);
// 1. 获取内容表 Table conTable = connection.getTable(TableName.valueOf(Constants.CONTENT_TABLE));
// 2. 构建scan 对象
Scan scan = new Scan();
// 构建过滤器
Filter rowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,new SubstringComparator(uid+"_"));
scan.setFilter(rowFilter); // 3. 获取数据
ResultScanner scanner = conTable.getScanner(scan);
// 4. 解析数据并打印
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
System.out.println(
"RK:"+Bytes.toString(CellUtil.cloneRow(cell))+","+
"CF:"+Bytes.toString(CellUtil.cloneFamily(cell))+","+
"cn:"+Bytes.toString(CellUtil.cloneQualifier(cell))+","+
"value:"+Bytes.toString(CellUtil.cloneValue(cell))
);
}
}
// 5. 关闭资源
conTable.close();
connection.close(); }
}
4. 测试类TestWeiBo
package deng.com.test; import deng.com.constants.Constants;
import deng.com.utils.HBaseUtils; import java.io.IOException; import static deng.com.dao.HBaseDao.*; public class TestWeiBO {
public static void init() throws IOException {
// 创建命名空间
// HBaseUtils.createNameSpace(Constants.NAMESPACE);
// 创建微博内容表
HBaseUtils.createTable(Constants.CONTENT_TABLE,Constants.CONTENT_TABLE_VERSIONS,Constants.CONTENT_TABLE_CF); // 创建用户关系表
HBaseUtils.createTable(Constants.RELATION_TABLE,Constants.RELATION_TABLE_VERSIONS,Constants.RELATION_TABLE_CF1,Constants.RELATION_TABLE_CF2); // 创建收件箱表
HBaseUtils.createTable(Constants.INBOX_TABLE,Constants.INBOX_TABLE_VERSIONS,Constants.INBOX_TABLE_CF);
} public static void main(String[] args) throws IOException {
// 初始化
init();
// 1001 发布微博
publishWeiBo("1001","快来上课"); // 1002 关注1001和1003
// addAttends("1002","1001","1003"); // 获取1002 初始化页面
getInt("1002");
System.out.println("================1111================");
// getWeiBo("1001"); // 1003 发布3条微博 。同时1001 发布两条微博v哦
publishWeiBo("1003","我是1003 : 今天天气真好");
publishWeiBo("1003","我是1003 : 一起去海边玩吧");
publishWeiBo("1003","我是1003 : 走,开车去");
publishWeiBo("1001","我是1001:我才不去");
publishWeiBo("1001","我是1001:要去你自己去");
// 获取1002 初始化页面
getInt("1002");
System.out.println("================2222================"); // 1002 取关1003
delAttends("1002","1003"); // 获取1002 初始化页面
getInt("1002");
System.out.println("================3333================");
// 1002 再次关注1003
addAttends("1002","1003");
System.out.println("================4444===============");
// 获取1001 详情
getWeiBo("1001"); }
}
Hbase 项目的更多相关文章
- hbase项目
四.HBase 项目4.1.涉及概念梳理:命名空间4.1.1.命名空间的结构 1) Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定, 则在 default 默认的命名 ...
- 【HBase学习】Apache HBase项目简介
原创声明:转载请注明作者和原始链接 http://www.cnblogs.com/zhangningbo/p/4068957.html 英文原版:http://hbase.apache.o ...
- Hadoo生态中pHive HBase 项目的区别
http://jenmhdn.iteye.com/blog/1678789 导读:Apache Hive是一个构建于Hadoop(分布式系统基础架构)顶层的数据仓库,Apache HBase是运行于H ...
- Hbase项目(完整版)
涉及概念梳理:命名空间 4.1.1.命名空间的结构 1) Table:表,所有的表都是命名空间的成员,即表必属于某个命名空间,如果没有指定,则在default默认的命名空间中. 2) RegionSe ...
- 【Hadoop学习】Apache HBase项目简介
正在撰写,稍后来访……
- HBase笔记:对HBase原理的简单理解
早些时候学习hadoop的技术,我一直对里面两项技术倍感困惑,一个是zookeeper,一个就是Hbase了.现在有机会专职做大数据相关的项目,终于看到了HBase实战的项目,也因此有机会搞懂Hbas ...
- HBase应用开发回顾与总结系列之一:概述HBase设计规范
概述 笔者本人接触研究HBase也有半年之久了,虽说不上深入和系统,但至少算是比较沉迷.作为部门里大数据技术的探路者,笔者还要承担起技术传播的职责,所以在摸索研究的过程中总是不断地进行总结和测试, ...
- HBase学习(十四)LINUX下用Eclipse构建HBase开发环境
Eclipse,HBase版本号眼下没有发现须要特别指定 1:从HBase集群中复制一份Hbase部署文件,放置在开发端某一文件夹下(如在/app/hadoop/hbase096文件夹下). 2:在e ...
- Phoenix(sql on hbase)简单介绍
Phoenix(sql on hbase)简单介绍 介绍: Phoenix is a SQL skin over HBase delivered as a client-embedded JDBC d ...
随机推荐
- 【LeetCode】762. Prime Number of Set Bits in Binary Representation 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 遍历数字+质数判断 日期 题目地址:https:// ...
- LeetCode1240铺瓷砖
题目 n*m的矩阵,只用正方形铺.求最少正方形个数. n,m<=13 思路 贪心: 加入是最大的正方形,显然行不通,比如n=11,m=13.那么贪心策略是1个11,其余是大小为2的正方形5个,大 ...
- Docker 与 K8S学习笔记(四)—— Dockerfile的编写
在上一篇中我们简单介绍了Docker镜像的获取与使用,其中在镜像制作中提到在实际使用中一定要用Dockerfile方式去创建镜像而不要用docker commit方式,那么我们该如何编写Dockerf ...
- Local Relation Networks for Image Recognition
目录 概 主要内容 Hu H., Zhang Z., Xie Z., Lin S. Local relation networks for image recognition. In Internat ...
- Java Web程序设计笔记 • 【第10章 JSTL标签库】
全部章节 >>>> 本章目录 10.1 JSTL 概述 10.1.1 JSTL 简介 10.1.1 JSTL 使用 10.1.2 实践练习 10.2 核心标签库 10.2. ...
- 自学java,如何快速地找到工作
本人最近一直在帮零基础的java开发者提升能力和找工作,在这个过程中,发现零基础的java程序员,在自学和找工作时,普遍会出现一些问题,同时在实践过程中,也总结出了一些能帮零基础java开发尽快提升能 ...
- ActiveMQ基础教程(三):C#连接使用ActiveMQ消息队列
接上一篇:ActiveMQ基础教程(二):安装与配置(单机与集群) 安装部署好集群环境:192.168.209.133:61616,192.168.209.134:61616,192.168.209. ...
- TKE 用户故事 | 作业帮 Kubernetes 原生调度器优化实践
作者 吕亚霖,2019年加入作业帮,作业帮架构研发负责人,在作业帮期间主导了云原生架构演进.推动实施容器化改造.服务治理.GO微服务框架.DevOps的落地实践. 简介 调度系统的本质是为计算服务/任 ...
- centos一步一步搭建tendermint
一.必要条件 1.安装go 请根据官方文档安装:https://golang.org/doc/install 要特别注意的是: /etc/profile 添加以下内容: export GOPATH=/ ...
- vert.x框架与tomcat的关系
1.前言 大学4年,老师唯一让我们学习的web服务器是tomcat,配置方式是先从官网下载阿帕奇的tomcat文件,然后在开发平台导入,然后再配置web.xml等文件, 是一个可同步可异步请求的服务器 ...