3、安装与部署:从单机到集群的完整实践
部署 Pinot 这件事,说实话比我想象中要灵活得多。早期我还在用笨办法手动搭集群,后来发现官方其实给了好几条路——单机尝鲜、生产集群、容器化,各有各的玩法。这一章我就把三种模式都走一遍,顺便聊聊我踩过的坑。
3.1 单机模式:五分钟跑起来
我个人习惯先用单机模式验证配置。你想想看,如果单机都跑不顺,集群肯定更麻烦。
Pinot 的单机模式其实是个“all-in-one”进程,把 Controller、Broker、Server 都塞在一起。适合开发测试,千万别上生产。
3.1.1 下载与启动
# 下载二进制包(以 1.0.0 为例)
wget https://downloads.apache.org/pinot/apache-pinot-1.0.0/apache-pinot-1.0.0-bin.tar.gz
tar -xzf apache-pinot-1.0.0-bin.tar.gz
cd apache-pinot-1.0.0-bin
# 启动单机模式(自动内嵌 ZK)
./bin/pinot-admin.sh QuickStart -type MULTI_STAGE
启动后访问 http://localhost:9000 就能看到控制台。嗯,这里要注意:MULTI_STAGE 类型会启动一个内嵌的 ZooKeeper,端口 2181。如果你本地已经有 ZK 在跑,记得改端口或者用 -zkAddress 参数指定。
-type STREAM 来测试实时摄入,省得每次都要配 Kafka 连接。不过这只是快速验证,生产环境别这么干。
3.1.2 验证部署
启动后,用 curl 检查各组件状态:
# 检查 Controller
curl http://localhost:9000/health
# 检查 Broker
curl http://localhost:8099/health
# 检查 Server
curl http://localhost:8097/health
如果都返回 OK,说明单机模式跑起来了。我曾经遇到过端口被占用的情况,尤其是 Mac 上 AirPlay 会抢 9000 端口。解决办法很简单:启动时加 -controllerPort 19000 换个端口。
3.2 集群模式:Helix 与 ZooKeeper 的依赖关系
单机模式只是开胃菜。生产环境必须上集群,而集群的核心就是 Apache Helix + ZooKeeper。说白了,Pinot 的集群管理完全建立在 Helix 之上,而 Helix 又依赖 ZK 做分布式协调。
3.2.1 架构总览
先看一张我画的架构图,理清组件关系:
3.2.2 为什么非要 ZK?
你可能会问:Pinot 自己不能管理集群状态吗?答案是:不能,也没必要。Helix 已经提供了成熟的分区管理、故障转移、负载均衡能力,Pinot 直接复用就好。ZK 在这里扮演的角色就是“可靠的配置存储 + 分布式锁”。
我记得有一次生产环境 ZK 集群挂了,Pinot 整个集群就变成了“瞎子”——Controller 不知道哪些 Server 活着,Broker 不知道路由到哪。从那以后,我部署 Pinot 之前一定会先确保 ZK 集群是高可用的。
3.2.3 集群部署步骤
假设你已经有一个 3 节点的 ZK 集群(zk1:2181,zk2:2181,zk3:2181),部署 Pinot 集群的流程如下:
- 启动 Controller(建议 2 台,主备模式)
- 启动 Broker(至少 2 台,做负载均衡)
- 启动 Server(根据数据量决定,建议 3 台起)
- (可选)启动 Minion(用于后台任务,如数据合并)
# 启动 Controller(节点1)
./bin/pinot-admin.sh StartController \
-zkAddress zk1:2181,zk2:2181,zk3:2181/pinot \
-controllerPort 9000
# 启动 Broker(节点2)
./bin/pinot-admin.sh StartBroker \
-zkAddress zk1:2181,zk2:2181,zk3:2181/pinot \
-brokerPort 8099
# 启动 Server(节点3)
./bin/pinot-admin.sh StartServer \
-zkAddress zk1:2181,zk2:2181,zk3:2181/pinot \
-serverPort 8097
/pinot 是命名空间。如果你在同一套 ZK 上跑多个 Pinot 集群(比如测试和生产),一定要用不同的路径,否则会互相干扰。我曾经因为忘了改路径,导致测试集群把生产集群的配置覆盖了……嗯,血的教训。
3.2.4 组件配置对比
| 组件 | 默认端口 | 核心配置项 | 高可用建议 |
|---|---|---|---|
| Controller | 9000 | controller.helix.cluster.name |
至少 2 台,主备切换 |
| Broker | 8099 | pinot.broker.enable.query.limit.override |
至少 2 台,前端加负载均衡 |
| Server | 8097 | pinot.server.instance.dataDir |
3 台起,副本数=2 |
| Minion | 9514 | pinot.minion.port |
按需部署,非必须 |
3.3 Docker 部署:容器化第一步
如果你不想手动装 JDK、配环境变量,Docker 是最快的方式。官方镜像在 apachepinot/pinot 下,标签对应版本号。
3.3.1 单机 Docker 启动
# 拉取镜像
docker pull apachepinot/pinot:1.0.0
# 启动单机模式(内嵌 ZK)
docker run -d --name pinot-quickstart \
-p 9000:9000 -p 8099:8099 -p 8097:8097 \
apachepinot/pinot:1.0.0 \
QuickStart -type MULTI_STAGE
我个人习惯把数据目录挂载出来,方便排查:
docker run -d --name pinot-quickstart \
-v /data/pinot:/tmp/pinot \
-p 9000:9000 -p 8099:8099 -p 8097:8097 \
apachepinot/pinot:1.0.0 \
QuickStart -type MULTI_STAGE
3.3.2 集群 Docker Compose
生产环境用 Docker Compose 编排集群比较省心。下面是一个简化版示例:
version: '3.8'
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.4.0
environment:
ZOOKEEPER_CLIENT_PORT: 2181
controller:
image: apachepinot/pinot:1.0.0
command: StartController -zkAddress zookeeper:2181/pinot
ports:
- "9000:9000"
depends_on:
- zookeeper
broker:
image: apachepinot/pinot:1.0.0
command: StartBroker -zkAddress zookeeper:2181/pinot
ports:
- "8099:8099"
depends_on:
- zookeeper
server:
image: apachepinot/pinot:1.0.0
command: StartServer -zkAddress zookeeper:2181/pinot
ports:
- "8097:8097"
depends_on:
- zookeeper
-serverHost <宿主机IP>,强制指定对外通信地址。
3.4 Kubernetes 部署:生产级实践
K8s 部署是 Pinot 在云原生环境下的标准姿势。官方提供了 Helm Chart,但说实话,默认配置有很多坑。我结合自己的生产经验,给你一套靠谱的方案。
3.4.1 使用 Helm 安装
# 添加 Helm 仓库
helm repo add pinot https://raw.githubusercontent.com/apache/pinot/master/kubernetes/helm
# 安装 Pinot 集群
helm install pinot pinot/pinot \
--set controller.replicaCount=2 \
--set broker.replicaCount=2 \
--set server.replicaCount=3 \
--set zookeeper.replicaCount=3
嗯,这里要注意:Helm Chart 默认会帮你部署 ZK 集群。如果你已经有现成的 ZK(比如用 Strimzi 管理的),可以通过 --set zookeeper.enabled=false 关掉内置 ZK。
3.4.2 关键配置项
| 参数 | 默认值 | 生产建议 | 说明 |
|---|---|---|---|
controller.replicaCount |
1 | 2 | 主备切换,避免单点 |
server.replicaCount |
1 | ≥3 | 保证数据副本数 |
server.persistence.size |
10Gi | 根据数据量评估 | 建议用 SSD 存储类 |
broker.requestMemory |
512Mi | 2Gi+ | 查询量大时需调高 |
3.4.3 我遇到的 K8s 部署坑
说几个我在生产环境踩过的坑:
- Pod 重启后 IP 变化: Pinot 的 Server 实例名默认用 IP,Pod 重启后 IP 变了,Helix 里会残留旧实例。解决办法是设置
pinot.server.instance.id为 Pod 名称(通过 Downward API 注入)。 - 资源限制不当: 有次我把 Server 的 CPU limit 设得太低,导致查询延迟飙升。后来改成
requests=4, limits=8才稳定。 - ZK 性能瓶颈: 默认 ZK 的
maxClientCnxns是 60,如果 Pinot 节点多,很容易达到上限。建议调大到 200+。
3.5 部署模式对比总结
| 模式 | 适用场景 | 复杂度 | 生产可用 | 推荐指数 |
|---|---|---|---|---|
| 单机模式 | 开发测试、功能验证 | ★☆☆☆☆ | 否 | ⭐⭐ |
| 集群模式(手动) | 中小规模生产、定制化部署 | ★★★★☆ | 是 | ⭐⭐⭐ |
| Docker Compose | CI/CD 环境、演示 | ★★☆☆☆ | 谨慎 | ⭐⭐⭐ |
| Kubernetes | 大规模生产、云原生环境 | ★★★★★ | 是 | ⭐⭐⭐⭐⭐ |
我个人最推荐 K8s 部署——虽然学习曲线陡,但一旦配好,扩缩容、故障恢复、资源隔离都省心很多。如果你团队没有 K8s 运维能力,手动集群模式也是稳妥的选择,至少可控性强。