一、介绍
因为代驾过程中,需要保存驾驶途中的 GPS 定位,将来计算代驾真实里程的时候,就需要用到这些坐标点。那么这些定位点保存在 MySQL 中可以吗?当然不行,MySQL 单表记录超过两千万就卡的不行。那么保存在 MongoDB 中可以吗?也不行,因为 MongoDB 里面的条件查询真的是超级蹩脚,所以想要用复杂条件检索数据,还是打消用 MongoDB 的念头吧。
除了 GPS 定位数据之外,还要把代驾过程中的聊天对话的文字内容保存起来。这么看来,我们需要一个既能保存海量数据,又能支持复杂条件检索的数据存储平台。HBase就再合适不过了。
HBase是一个分布式、版本化、面向列的开源数据库。构建在 Apache Hadoop 和 Apache ZooKeeper 之上。HBase 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。利用 HBase 技术可在廉价的 PC server 上搭建大规模结构化存储集群。HBase 不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库,HBase 是基于列的,而不是基于行的模式。
HBase特点:准实时查询(百豪秒以内);高可靠性,数据存储于HDFS中且依赖于 ZooKeeper进行 Master 和 RegionServer 的协调管理。
HBase的操作语句很难写。
Phoenix 是给 HBase 添加了一个语法表示层,允许我们用 SQL 语句读写 HBase 中的数据,可以做联机事务处理。拥有低延迟的特性,这就让我们方便多了。Phoenix 会把 SQL 编译成一系列的 HBase 的 scan 操作,然后把 scan 结果生成标准的 JDBC 结果集。处理千万级行的数据也只用毫秒或秒级就搞定。而且 Phoenix 还支持 MyBatis 框架,正好可以和华夏代驾项目整合到一起。
二、部署 HBase 和 Phoenix
1. 倒入镜像文件
首先找到 HBase.tar.gz phoenix.tar.gz 镜像文件,然后把这个文件上传到 CentOS系统中,执行命令,把镜像文件导入 Docker 之中。
docker load < phoenix.tar.gz
2. 创建容器
由于 HBase 需要使用的内存较大,这里我没有规定具体的内存大小,容器会自动使用空闲的内存。容器中数据目录是 /tmp/hbase-root/hbase/data ,把这个目录映射到宿主机的 /root/hbase/data 目录。
docker run -it -d -p 2181:2181 -p 8765:8765 -p 15165:15165 \
-p 16000:16000 -p 16010:16010 -p 16020:16020 \ #映射端口
-v /root/hbase/data:/tmp/hbase-root/hbase/data \ #映射文件
--name phoenix --net mynet --ip 172.18.0.14 \ #分配网络
boostport/hbase-phoenix-all-in-one:2.0-5.0 #镜像名字
3. 开放端口
使用 VirtualBox 软件把 Linux 的 2181、8765、15165、16000、16010、16020端口,映射到 Windows 的相应端口上面。
参考链接:
4. 初始化Phoenix
运行命令,进入到 Phoenix 容器中,然后执行命令设置 HBASE_CONF_DIR 环境变量。
docker exec -it phoenix bash
export HBASE_CONF_DIR=/opt/hbase/conf/
然后就可以使用 Phoenix 自带的命令行客户端通过 SQL 语句操作 HBase数据。
接下来我们要连接 Phoenix 的命令行客户端。虽然 IDEA 也内置了Phoenix 客户端,但是 Bug 挺多的,用着不方便。所以建议大家使用 Phoenix 自带的命令行客户端更好一些。而且我们要执行的 SQL 语句也并不多,命令行客户端已经足够用了。
/opt/phoenix-server/bin/sqlline.py localhost
#调用 Phoenix 自带的命令行客服端
三、创建逻辑库和数据表
1. 创建逻辑库
为了存储数据,我们需要像操作 MySQL 一样,先创建逻辑库,再定义数据表。在 Phoenix 的命令行客户端,我们先来执行创建逻辑库的命令。
CREATE SCHEMA hxds #创建
USE hxds #切入
2. 创建数据表
接下来我们要创建 order_voice_text、order_monitoring 和 order_gps 数据表。其中 order_voice_text 表用于存放司乘对话内容的文字内容;
CREATE TABLE hxds.order_voice_text(
"id" BIGINT NOT NULL PRIMARY KEY, #只能主键加 NOT NULL
"uuid" VARCHAR,
"order_id" BIGINT,
"record_file" VARCHAR,
"text" VARCHAR,
"label" VARCHAR,
"suggestion" VARCHAR,
"keywords" VARCHOR,
"create_time" DATE
);
# ovt 为 order_voice_text 的缩写
#创建自增长的序列
CREATE SEQUENCE hxds.ovt_sequence START WITH 1 INCREMENT BY 1;
#给字段创建索引
CREATE INDEX ovt_index_1 ON hxds.order_voice_text("uuid");
CREATE INDEX ovt_index_2 ON hxds.order_voice_text("order_id");
CREATE INDEX ovt_index_3 ON hxds.order_voice_text("label");
CREATE INDEX ovt_index_4 ON hxds.order_voice_text("suggestion");
CREATE INDEX ovt_index_5 ON hxds.order_voice_text("create_time");
order_monitoring 表存储 AI 分析对话内容的安全评级结果。命令类似于上面。
order_gps 表存储代驾过程中的 GPS 定位。命令类似于上面。
#演示查询语句
SELECT * FROM hxds.order_gps;
SELECT * FROM hxds.order_gps WHERE "id"=9527;
四、编写 hxds-nebula 子系统
先来看一下 hxds-nebula 子系统的 application.yml 文件,里面的 JDBC 驱动和 URL 路径都是为了连接 Phoenix 的。如果你用的是云主机,别忘了 URL 要写云主机的 IP,而且还要在安全组里面把相关端口开放一下。
datasource:
#驱动类
driver-class-name: org.apache.phoenix.queryserver.client.Driver
url: jdbc:phoenix:thin:url=http://127.0.0.1:8765;serialization=PROTOBUF
type: com.alibaba.druid.pool.DruidDataSource
druid:
test-on-borrow: true
test-while-idle: true
max-active: 8
min-idle: 4
1. 定义 POJO 类
既然要用 MyBatis 连接 Phoenix,那么持久层的 POJO 类、DAO 接口和 XML 文件都要配齐了才可以。在 com.example.hxds.nebula.db.pojo 包中,创建3个 POJO 类。如下:
@Data
public class OrderMonitoringEntity {
private Long id;
private Long orderId;
private Byte status;
private Integer records;
private String safety;
private Integer reviews;
private Byte alarm;
private String createTime;
}
2. 定义 DAO 接口
在 com.example.hxds.nebula.db.dao 包中,声明3个 DAO 接口。如下:
public interface OrderGpsDao {
public int insert(OrderVoiceTextEntity entity)
}
3. 定义 XML 文件
在 resources 目录中创建 mapper 文件夹,定义3个 XML 文件。如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.hxds.nebula.db.dao.OrderGpsDao">
<insert id="insert" parameterType="com.example.hxds.nebula.db.pojo.OrderVoiceTextEntity">
UPSERT INTO hxds.order_voice_text("id", "uuid", "order_id", "record_file", "text", "create_time")
VALUES(NEXT VALUE FOR hxds.ovt_sequence, '${uuid}', #{orderId}, '${recordFile}', '${text}', NOW())
</INSERT>
</mapper>
4. 运行子系统
上述内容都配置完成之后,就可以启动 hxds-nebula 子系统了,如果控制台没有报错信息,说明配置都是正确的。