假日出行大数据分析平台
一、实验概述
1.1 实验目的
本次实验旨在搭建大数据处理平台,通过模拟生成假日出行数据,构建数据仓库(Hive)进行分层处理,并使用 AJ-Report 进行数据可视化展示,最终实现假日出行数据的分析与报表展示。
1.2 实验环境
| 组件 | 版本 | 说明 |
|---|---|---|
| 操作系统 | Ubuntu 22.04 | 虚拟机 |
| Hadoop | 3.1.3 | HDFS + YARN |
| Zookeeper | 3.5.7 | 集群协调 |
| Kafka | 3.0.0 | 消息队列 |
| Hive | 3.1.2 | 数据仓库(Hive-on-Spark) |
| MySQL | 8.4 | 关系型数据库 |
| DataX | - | 数据同步工具 |
| Maxwell | 1.29.2 | 实时 Binlog 采集 |
| Flume | 1.11.0 | 日志采集 |
| AJ-Report | 1.4.1 | 可视化报表 |
| JDK | 1.8 | Java 运行环境 |
1.3 网络配置
- 主机名:hadoop102
- IP 地址:192.168.56.101
- 伪分布式环境
二、基础环境搭建
2.1 Hadoop 配置
core-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/module/hadoop-3.1.3/data</value>
</property>
</configuration>
hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
</configuration>
yarn-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hadoop102</value>
</property>
<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
</configuration>
2.2 Kafka 配置(server.properties)
# broker 编号
broker.id=0
# 端口
listeners=PLAINTEXT://0.0.0.0:9092
# 日志目录
log.dirs=/opt/module/kafka-3.0.0/data
# Zookeeper 连接
zookeeper.connect=127.0.0.1:2181
# 分区数
num.partitions=3
# 副本数
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1
advertised.listeners=PLAINTEXT://192.168.56.101:9092
2.3 Hive 配置(hive-site.xml)
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://127.0.0.1:3306/hive?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>123456</value>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
</property>
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>
</configuration>
2.4 AJ-Report 配置(包括 bootstrap.yml,JAR)
spring:
profiles:
active: prod
datasource:
url: jdbc:mysql://127.0.0.1:3306/aj_report?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 123456
type: com.zaxxer.hikari.HikariDataSource
2.5 服务启动验证
成功启动的服务:
- Hadoop HDFS(NameNode、DataNode、SecondaryNameNode)
- Hadoop YARN(ResourceManager、NodeManager)
- Zookeeper(QuorumPeerMain)
- Kafka
- Hive Metastore
- MySQL
- AJ-Report(端口 9095)
(截图)
三、模拟数据生成
3.1 数据表结构
users(用户表)
CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int NOT NULL,
`mobile` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
aoi(景区表)
CREATE TABLE `aoi` (
`id` int NOT NULL,
`name` varchar(100) NOT NULL,
`city` varchar(50) NOT NULL,
`type` varchar(10) NOT NULL,
`lng` varchar(20) NOT NULL,
`lat` varchar(20) NOT NULL,
`lng_wgs` varchar(20) NOT NULL,
`lat_wgs` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
3.2 模拟数据生成脚本
用户数据生成(insertUser.py)
import mysql.connector
import random
import faker
conn = mysql.connector.connect(
host="localhost",
user="root",
password="123456",
database="travel"
)
cursor = conn.cursor()
# 创建用户表
create_table_sql = """
create table if not exists users(
id int auto_increment primary key,
name varchar(50) not null,
age int not null,
mobile varchar(50) not null
)
"""
cursor.execute(create_table_sql)
# 生成1000条虚拟用户数据
fake = faker.Faker()
users_data = [(fake.name(), random.randint(18, 80), fake.phone_number()) for _ in range(1000)]
insert_sql = "insert into users (name,age,mobile) values (%s,%s,%s)"
cursor.executemany(insert_sql, users_data)
conn.commit()
cursor.close()
conn.close()
3.3 数据生成结果展示

四、数仓构建
4.1 数仓分层架构
ODS 层(原始数据层)
├── ods_users_full -- 用户表
├── ods_aoi_full -- 景区表
├── ods_user_travels_inc -- 用户出行增量表
└── ods_user_activities_inc -- 用户活动增量表
DWD 层(明细数据层)
├── dwd_users -- 用户维度表(维度退化)
├── dwd_user_travels -- 出行事实表
└── dwd_user_activities -- 活动事实表
DIM 层(维度层)
├── dim_area -- 区域维度表
└── dim_date_2023 -- 日期维度表
DWS 层(服务数据层)
└── dws_aoi_city -- 按城市聚合景区指标
ADS 层(应用数据层)
└── ads_aoi_stat -- 各城市景区统计
4.2 数据同步
DataX 全量同步
- users 表同步:MySQL → HDFS(/travel/db/users_full)
- aoi 表同步:MySQL → HDFS(/travel/db/aoi_full)
DataX 配置(users.json):
{
"job": {
"content": [{
"reader": {
"name": "mysqlreader",
"parameter": {
"column": ["id", "name", "age", "mobile"],
"connection": [{
"jdbcUrl": ["jdbc:mysql://hadoop102:3306/travel?useUnicode=true&allowPublicKeyRetrieval=true&characterEncoding=utf-8"],
"table": ["users"]
}],
"password": "123456",
"username": "root"
}
},
"writer": {
"name": "hdfswriter",
"parameter": {
"column": [
{"name": "id", "type": "bigint"},
{"name": "name", "type": "string"},
{"name": "age", "type": "string"},
{"name": "mobile", "type": "string"}
],
"compress": "gzip",
"defaultFS": "hdfs://hadoop102:8020",
"fieldDelimiter": "\t",
"fileType": "text",
"path": "/travel/db/users_full",
"writeMode": "truncate"
}
}
}]
}
}
Maxwell 实时增量采集
- 配置 Maxwell 监听 MySQL binlog
- 将增量数据发送到 Kafka topic incdb0710
- 捕获 user_travels 和 user_activities 表的变更
Maxwell 配置(config.properties):
producer=kafka
kafka.bootstrap.servers=hadoop102:9092,hadoop103:9092,hadoop104:9092
kafka_topic=incdb0710
host=hadoop102
user=maxwell
password=123456
producer_partition_by=primary_key
client_id=maxwell_first
kafka.compression.type=snappy
kafka.retries=0
kafka.acks=1
Flume 日志采集
- 从 Kafka 消费数据写入 HDFS
- 自定义拦截器(TimestampAndTableNameInterceptor)提取表名和时间戳
Flume 配置(travel.conf):
# source
a1.sources.r1.type = org.apache.flume.source.kafka.KafkaSource
a1.sources.r1.kafka.bootstrap.servers = 192.168.10.102:9092
a1.sources.r1.kafka.topics = incdb9
a1.sources.r1.kafka.consumer.group.id = flume9
# channel
a1.channels.c1.type = file
a1.channels.c1.checkpointDir = /opt/module/flume/checkpoint/travel
a1.channels.c1.dataDirs = /opt/module/flume/data/travel/
# interceptor
a1.sources.r1.interceptors.i1.type = cn.wolfcode.flume.interceptor.TimestampAndTableNameInterceptor$MyBuilder
# sink
a1.sinks.k1.type = hdfs
a1.sinks.k1.hdfs.path = /travel/db/%{tableName}_inc/%Y-%m-%d
a1.sinks.k1.hdfs.fileType = CompressedStream
a1.sinks.k1.hdfs.codeC = gzip
4.3 数仓各层表清单
ODS 层
ods_users_full -- 用户全量数据
ods_aoi_full -- 景区全量数据
ods_user_travels_inc -- 用户出行增量数据
ods_user_activities_inc -- 用户活动增量数据
DWD 层
dwd_users -- 用户维度表
dwd_user_travels -- 出行事实表
dwd_user_activities -- 活动事实表
DWS 层
dws_aoi_city -- 按城市聚合景区指标
ADS 层
ads_aoi_stat -- 各城市景区统计(最终结果)
4.4 ADS 层数据导出
使用 DataX 将 ADS 层数据从 HDFS 导出到 MySQL,供 AJ-Report 使用:
{
"job": {
"content": [{
"reader": {
"name": "hdfsreader",
"parameter": {
"path": "/travel/ads/aoi_stat/*",
"defaultFS": "hdfs://hadoop102:8020",
"fileType": "text",
"column": [{"index": 0, "type": "string"}, {"index": 1, "type": "long"}],
"fieldDelimiter": "\t"
}
},
"writer": {
"name": "mysqlwriter",
"parameter": {
"writeMode": "replace",
"username": "root",
"password": "123456",
"connection": [{
"jdbcUrl": "jdbc:mysql://127.0.0.1:3306/travel?useSSL=false&allowPublicKeyRetrieval=true",
"table": ["ads_aoi_stat"]
}],
"column": ["city", "aoi_count"]
}
}
}]
}
}
4.5 ADS 层最终数据
SELECT * FROM ads_aoi_stat ORDER BY aoi_count DESC;
| 城市 | 景区数量(个) |
|---|---|
| 山东 | 1227 |
| 浙江 | 798 |
| 四川 | 725 |
| 江苏 | 615 |
| 安徽 | 605 |
| 广西 | 557 |
| 河南 | 495 |
| 陕西 | 460 |
| 新疆 | 440 |
| 江西 | 421 |
| 河北 | 420 |
| 湖北 | 409 |
| 贵州 | 409 |
| 黑龙江 | 395 |
| 内蒙古 | 380 |
| 福建 | 375 |
| 云南 | 344 |
| 辽宁 | 323 |
| 甘肃 | 323 |
| 湖南 | 289 |
| 北京 | 245 |
| 吉林 | 231 |
| 重庆 | 224 |
| 山西 | 218 |
| 上海 | 111 |
| 西藏 | 116 |
| 青海 | 115 |
| 天津 | 97 |
| 宁夏 | 96 |
| 广州 | 66 |
| 海南 | 64 |
| 惠州 | 36 |
| 韶关 | 31 |
| 佛山 | 28 |
| 清远 | 26 |
| 东莞 | 25 |
| 中山 | 19 |
| 江门 | 18 |
| 深圳 | 16 |
| 湛江 | 16 |
| 河源 | 15 |
| 肇庆 | 15 |
| 茂名 | 14 |
| 云浮 | 12 |
| 阳江 | 12 |
| 梅州 | 32 |
| 潮州 | 8 |
| 珠海 | 8 |
| 汕尾 | 9 |
| 汕头 | 10 |
| 揭阳 | 10 |
| 3A | 10 |
| 4A | 6 |
| 31.2769932964777 | 1 |
| A | 1 |
五、报表开发
5.1 AJ-Report 部署
- 访问地址:http://192.168.56.101:9095/(本地)
- 默认账号:admin / 123456
- 数据源:MySQL(jdbc:mysql://127.0.0.1:3306/travel)

5.2 大屏报表设计
大屏包含以下 5 个图表组件:
1. 柱状图 — 各城市景区数量 TOP15
SELECT city, aoi_count FROM ads_aoi_stat ORDER BY aoi_count DESC LIMIT 15;
- X 轴:city(城市)
- Y 轴:aoi_count(景区数量,求和)
- 说明:展示景区数量排名前 15 的城市


2. 中国地图 — 全国景区分布热力图
SELECT city, aoi_count FROM ads_aoi_stat WHERE city IN ('北京','天津','上海','重庆','河北','山西','辽宁','吉林','黑龙江','江苏','浙江','安徽','福建','江西','山东','河南','湖北','湖南','广东','海南','四川','贵州','云南','陕西','甘肃','青海','台湾','内蒙古','广西','西藏','宁夏','新疆') ORDER BY aoi_count DESC;
- 维度:city(城市)
- 指标:aoi_count(景区数量,求和)
- 说明:在地图上直观展示各省市景区分布密度


3. 饼图 — 景区数量占比 TOP10
SELECT city, aoi_count FROM ads_aoi_stat ORDER BY aoi_count DESC LIMIT 10;
- 维度:city(城市)
- 指标:aoi_count(景区数量,求和)
- 说明:展示 TOP10 城市景区数量的占比分布


4. 漏斗图 — 各城市景区数量漏斗
SELECT city, aoi_count FROM ads_aoi_stat ORDER BY aoi_count DESC LIMIT 10;
- 维度:city(城市)
- 指标:aoi_count(景区数量,求和)
- 说明:以漏斗图形式展示 TOP10 城市景区数量递进关系


5. 词云图 — 城市景区数量词云
SELECT city AS name, aoi_count AS value FROM ads_aoi_stat ORDER BY aoi_count DESC;
- 名称字段:name(城市名)
- 值字段:value(景区数量)
- 说明:以词云形式展示各城市景区数量分布


5.3 大屏报表完整预览截图

5.4 数据分析结论
- 山东省景区数量最多(1227 个),远超其他省份,是旅游资源最丰富的地区
- 浙江(798 个)、四川(725 个)、江苏(615 个)位列第二梯队,均为旅游大省
- 东部沿海省份(山东、浙江、江苏、福建)景区数量普遍高于中西部地区
- 西部省份中,四川(725 个)、陕西(460 个)、新疆(440 个)表现突出
- 一线城市中,北京(245 个)景区数量最多,其次是重庆(224 个)、上海(111 个)
六、实验总结
6.1 遇到的问题及解决方案
- YARN 启动失败:yarn-site.xml 多根节点问题 → 合并为单一
<configuration>根节点 - DataX 同步缺失 fileType 参数 → 添加
"fileType": "text"配置 - AJ-Report 连接 MySQL 失败:配置文件中的远程 IP 未修改 → 修改 JAR 包内 bootstrap.yml 为 127.0.0.1
- Kafka 连接失败:缺少 advertised.listeners 配置 → 添加
advertised.listeners=PLAINTEXT://192.168.56.101:9092
6.2 关键技术点
- 使用 Hive 数仓分层(ODS→DWD→DIM→DWS→ADS)实现数据逐层清洗和聚合
- DataX 实现 MySQL 到 HDFS 的全量数据同步
- Maxwell + Kafka + Flume 实现 MySQL 增量数据的实时捕获和 HDFS 存储
- 自定义 Flume 拦截器解析表名和时间戳
- AJ-Report 制作多图表大屏实现数据可视化
6.3 心得体会
本次实验让我完整经历了大数据分析的全流程。环境搭建的排过程加深了我对分布式组件配置原理的理解;数仓分层设计(ODS→DWD→DWS→ADS)使我认识到数据逐层解耦和复用的重要性,显著提升了查询效率和维护性。利用 Maxwell + Kafka + Flume 实现实时增量同步,让我直观感受到“实时数仓”的技术魅力,也体会到数据一致性保障的难度。最后,通过 AJ-Report 将统计数据可视化呈现,让我看到数据驱动决策的实际价值。这次实践不仅锻炼了动手能力,更构建了我对大数据工程体系的整体认知,为后续深入学习奠定了扎实基础。
浙公网安备 33010602011771号