2. 环境搭建与部署:Flink集群部署、Kafka集群搭建、Redis与HBase初始化配置

好,咱们直接进入正题。实时推荐平台要跑起来,底层基础设施得先立住。说白了,这一章就是搭积木——把 Flink、Kafka、Redis、HBase 这几个核心组件装好、配通、能干活。

我个人习惯,先把整体架构理清楚,再动手。你想想看,如果连数据怎么流、存哪里都不知道,配再多参数也是瞎忙活。

实时推荐平台基础架构图 数据源 用户行为日志 Kafka 集群 消息缓冲 & 解耦 Flink 集群 实时计算 & 推荐 Redis 集群 特征缓存 HBase 集群 用户画像存储 数据流说明: 用户行为 → Kafka → Flink 消费并计算 → 实时写入 Redis(特征)和 HBase(画像) 推荐服务从 Redis 读取实时特征,从 HBase 读取用户画像,生成推荐结果返回前端

2.1 Flink 集群部署

Flink 是整个平台的「大脑」。所有实时推荐逻辑都在上面跑。部署方式我推荐用 Standalone 模式,方便调试和运维。生产环境当然可以用 YARN 或 Kubernetes,但咱们课程里先把 Standalone 玩透。

2.1.1 环境准备

  • JDK:1.8 或 11,我建议用 JDK 8,兼容性最好
  • SSH 免密登录:集群节点之间要能互相访问
  • 时钟同步:NTP 必须配,否则 Checkpoint 会出问题

我曾经遇到过因为时钟不同步导致 Flink Checkpoint 频繁超时的情况。排查了整整一天,最后发现是其中一台机器时间慢了 3 分钟。嗯,从那以后我每部署一套集群,第一件事就是检查 NTP。

2.1.2 下载与配置

# 下载 Flink 1.17.0
wget https://dlcdn.apache.org/flink/flink-1.17.0/flink-1.17.0-bin-scala_2.12.tgz
tar -xzf flink-1.17.0-bin-scala_2.12.tgz
mv flink-1.17.0 /opt/flink

核心配置文件是 flink-conf.yaml,我一般这样配:

# flink-conf.yaml 关键配置
jobmanager.rpc.address: node01
jobmanager.memory.process.size: 2048m
taskmanager.memory.process.size: 4096m
taskmanager.numberOfTaskSlots: 4
parallelism.default: 4
state.backend: rocksdb
state.checkpoints.dir: hdfs:///flink-checkpoints
state.savepoints.dir: hdfs:///flink-savepoints

个人经验:RocksDB 作为状态后端,在实时推荐场景下表现很稳。尤其是用户画像这类大状态,比 FsStateBackend 靠谱得多。

2.1.3 启动集群

# 在 node01 上启动
/opt/flink/bin/start-cluster.sh

# 检查进程
jps
# 应该看到:StandaloneSessionClusterEntrypoint
# 和 TaskManagerRunner

启动后访问 http://node01:8081,能看到 Web UI 就算成功了。

2.2 Kafka 集群搭建

Kafka 是实时数据的「高速公路」。用户点击、浏览、购买行为,全得先进 Kafka,Flink 再从里面消费。

2.2.1 集群规划

节点 角色 Broker ID
node01 Controller + Broker 0
node02 Broker 1
node03 Broker 2

三台机器起步,别用单节点。我在项目中见过单节点 Kafka 挂了,整个推荐链路瘫痪的惨案。

2.2.2 安装与配置

# 下载 Kafka 3.4.0
wget https://dlcdn.apache.org/kafka/3.4.0/kafka_2.12-3.4.0.tgz
tar -xzf kafka_2.12-3.4.0.tgz
mv kafka_2.12-3.4.0 /opt/kafka

修改 config/server.properties:

# node01 配置
broker.id=0
listeners=PLAINTEXT://node01:9092
log.dirs=/data/kafka/logs
zookeeper.connect=node01:2181,node02:2181,node03:2181
num.partitions=8
default.replication.factor=2

关键参数说明:

  • num.partitions=8:默认分区数,推荐场景建议 8-16 个分区
  • default.replication.factor=2:副本数 2,保证高可用
  • log.dirs:建议用独立磁盘,别跟系统盘混一起

2.2.3 启动与验证

# 先启动 Zookeeper(Kafka 依赖它)
/opt/kafka/bin/zookeeper-server-start.sh -daemon config/zookeeper.properties

# 再启动 Kafka
/opt/kafka/bin/kafka-server-start.sh -daemon config/server.properties

# 创建测试 Topic
/opt/kafka/bin/kafka-topics.sh --create \
  --topic user-click-log \
  --bootstrap-server node01:9092 \
  --partitions 8 \
  --replication-factor 2

用 kafka-console-producer 和 kafka-console-consumer 发几条消息试试,能收能发就对了。

2.3 Redis 初始化配置

Redis 在推荐平台里干两件事:缓存用户实时特征、存储推荐结果。要求就是快,延迟必须毫秒级。

2.3.1 安装 Redis Cluster

# 下载 Redis 7.0
wget https://download.redis.io/releases/redis-7.0.12.tar.gz
tar -xzf redis-7.0.12.tar.gz
cd redis-7.0.12
make && make install

我习惯用 Redis Cluster 模式,6 个节点起步(3主3从):

# redis.conf 关键配置
port 6379
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
requirepass yourpassword

避坑指南:cluster-node-timeout 别设太短。我曾经设了 2000ms,网络抖动一下集群就脑裂了。5000ms 是个比较稳妥的值。

2.3.2 启动集群

# 在每个节点上启动 Redis
redis-server /etc/redis/redis.conf

# 在任意节点执行集群创建命令
redis-cli --cluster create \
  node01:6379 node02:6379 node03:6379 \
  node04:6379 node05:6379 node06:6379 \
  --cluster-replicas 1 \
  -a yourpassword

2.3.3 验证集群

redis-cli -c -h node01 -p 6379 -a yourpassword
cluster info
cluster nodes

看到 cluster_state:ok,说明集群正常。

2.4 HBase 初始化配置

HBase 存的是用户画像——长期积累的偏好数据。这东西不像 Redis 那么快,但能存海量数据,而且支持按 RowKey 快速查询。

2.4.1 依赖检查

HBase 依赖 HDFS 和 Zookeeper。确保这两个服务已经跑起来了。

# 检查 HDFS
hdfs dfsadmin -report

# 检查 Zookeeper
zkServer.sh status

2.4.2 安装 HBase

# 下载 HBase 2.5.3
wget https://dlcdn.apache.org/hbase/2.5.3/hbase-2.5.3-bin.tar.gz
tar -xzf hbase-2.5.3-bin.tar.gz
mv hbase-2.5.3 /opt/hbase

修改 conf/hbase-site.xml:

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://mycluster/hbase</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>node01,node02,node03</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>
</configuration>

2.4.3 创建推荐平台需要的表

# 启动 HBase Shell
hbase shell

# 创建用户画像表
create 'user_profile', 'basic', 'preference', 'behavior'

# 创建物品特征表
create 'item_feature', 'content', 'statistics'

# 创建推荐结果表
create 'recommend_result', 'rec_list', 'exp_info'
表名 列族 用途
user_profile basic, preference, behavior 存储用户基础信息、偏好标签、行为统计
item_feature content, statistics 物品内容特征、点击/购买统计
recommend_result rec_list, exp_info 推荐结果列表、实验分组信息

注意:HBase 的 RowKey 设计很关键。用户画像表我建议用 user_id 反转后作为 RowKey,避免热点问题。比如用户 ID 是 10086,反转成 68001,这样数据分布更均匀。

2.5 连通性验证

所有组件装完后,得跑个端到端的测试。我一般这么干:

  1. 往 Kafka 的 user-click-log Topic 里发一条测试消息
  2. 写一个简单的 Flink 作业,消费这条消息
  3. Flink 处理完后,分别写入 Redis 和 HBase
  4. 从 Redis 和 HBase 里查一下,数据对不对
// 简单的 Flink 端到端测试代码片段
DataStream<String> source = env.addSource(
  new FlinkKafkaConsumer<>("user-click-log", 
    new SimpleStringSchema(), 
    kafkaProps));

source.map(new MapFunction<String, String>() {
  @Override
  public String map(String value) {
    // 写入 Redis
    jedisCluster.set("test:key", value);
    // 写入 HBase
    hTable.put(new Put(Bytes.toBytes("test_row"))
      .addColumn("basic".getBytes(), "data".getBytes(), value.getBytes()));
    return value;
  }
}).print();

能跑通,说明环境搭建成功了。嗯,这一步别偷懒,我见过太多人搭完环境就以为万事大吉,结果上线第一天就发现 Kafka 连不上 HBase。

总结一下:

  • Flink 负责算,Kafka 负责传,Redis 负责快,HBase 负责存
  • 每个组件都有各自的坑,时钟同步、网络抖动、RowKey 设计,都是血泪教训
  • 环境搭完一定要做连通性验证,别等到上线再发现问题