前言
在 Kubernetes 環境中運行 Redis Cluster 時,雖然可以透過 Service Name 在叢集內部互相存取,但實務上仍會碰到不少麻煩事:像是從叢集外部無法直接連線、切換資料庫時偶爾會出現異常、或是只能用特定的客戶端工具才能操作。為了解決這些痛點,我決定在 Redis Cluster 前方部署 Predixy 這款高效能代理,讓整個叢集對外看起來就像一台單機 Redis 一樣簡單好用。
為什麼需要在 Redis Cluster 前面放一層 Predixy 代理?
整體架構大致是這樣的:最底層是 Redis Cluster 本身,中間加上 Predixy 代理層,最上面還可以再疊一個 Nginx 做負載平衡。對於應用端來說,它只需要連到 Predixy 提供的單一端點即可,完全不用關心後面有幾個 Redis 節點。

Redis 在 Kubernetes 上的叢集架構概覽
導入 Predixy 代理的好處
| 問題場景 | 加入 Predixy 後的效果 |
|---|---|
| Redis Pod 重啟導致 IP 變動 | 客戶端無感知,Predixy 自動追蹤新 IP |
| Pod 重新排程後 Node IP 改變 | 透過 Service 端點統一入口,終端無需調整 |
| Redis 直接承受大量連線 | Predixy 做連線池管理,降低 Redis 負載 |
| 叢集擴縮容 | 自動偵測拓撲變化,客戶端零停機 |
| 資料安全風險 | 透過 Auth 機制統一管控存取權限 |
常見 Redis 代理方案比較
| 代理方案 | 支援 Redis Cluster | 穩定性 | 備註 |
|---|---|---|---|
| Codis | 否(自有分片) | 成熟 | 需額外 Dashboard,架構較重 |
| Twemproxy | 否 | 成熟 | 不支援 Redis Cluster 協定 |
| redis-cluster-proxy | 是 | 實驗性 | Redis 官方 6.0 推出,尚無穩定版 |
| Predixy | 是 | 穩定 | 高效能、多執行緒、功能完整 |
因為我們希望繼續沿用 Redis Cluster 的原生管理機制,所以 Codis 和 Twemproxy 直接排除。redis-cluster-proxy 目前還不夠成熟,最終選擇了 Predixy 作為我們的代理方案。
K8s 儲存觀念:PV、PVC 與 StorageClass
| 概念 | 說明 |
|---|---|
| PersistentVolume(PV) | 由管理員配置的叢集層級儲存資源,生命週期獨立於 Pod,支援 NFS、iSCSI、雲端儲存等 |
| PersistentVolumeClaim(PVC) | 使用者對儲存的請求,類似 Pod 消耗 CPU/Memory,PVC 消耗 PV 資源 |
| StorageClass | 動態供給(Dynamic Provisioning)的關鍵,定義 PV 模板,使用者只需提交 PVC,系統自動建立並綁定 PV |
實戰:編譯 Predixy 並部署到 Kubernetes
步驟一:下載 Predixy 原始碼並編譯建置映像檔
首先取得 Predixy 原始碼並編譯:
mkdir -p /k8s/predixy
cd /k8s/predixy
wget https://codeload.github.com/joyieldInc/predixy/zip/refs/heads/master
unzip master
mv predixy-master predixy-1.0.5
cd predixy-1.0.5
make
接著準備 Dockerfile:
FROM centos:7
RUN yum install -y epel-release net-tools
RUN yum install -y redis
RUN yum install -y libstdc++-static gcc gcc-c++ make
RUN mkdir /opt/predixy-1.0.5
RUN mkdir /etc/predixy
COPY ./predixy-1.0.5/src/predixy /usr/local/bin/
COPY ./predixy-1.0.5/conf/* /etc/predixy/
ENTRYPOINT ["/usr/local/bin/predixy","/etc/predixy/predixy.conf"]
建置映像檔:
docker build . -t predixy:v1.0.5 -f predixy-dockerfile.yaml

Kubernetes 環境中的 Redis Cluster 部署示意
步驟二:建立 ConfigMap 設定檔
Predixy 的設定透過 Kubernetes ConfigMap 來管理,這邊列出關鍵設定片段:
apiVersion: v1
kind: ConfigMap
metadata:
name: predixy-config
namespace: redis-cluster
data:
predixy.conf: |
Name Predixy-DefaultNS
Bind 0.0.0.0:7617
WorkerThreads 4
ClientTimeout 0
Log /data/predixy.log
LogRotate 1d
Authority {
Auth "********" {
Mode admin
}
}
ClusterServerPool {
Password ********
MasterReadPriority 60
StaticSlaveReadPriority 50
DynamicSlaveReadPriority 60
RefreshInterval 1
ServerTimeout 1
ServerFailureLimit 10
ServerRetryTimeout 1
KeepAlive 120
Servers {
+ redis-cluster.redis-cluster.svc.cluster.local:6379
}
}
套用設定:
kubectl apply -f predixy-configmap.yaml
步驟三:建立 PVC 持久化儲存
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: predixy-pvc-nfs
namespace: redis-cluster
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: nfs-storage
kubectl apply -f predixy-pvc-nfs.yaml
使用 NFS StorageClass 時,建立 PVC 會自動產生對應的 PV 並完成綁定。
步驟四:部署 Predixy Deployment + HPA + Service
Predixy 本身是無狀態服務,使用 Deployment 部署即可。完整的 YAML 包含三個資源:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: predixy
namespace: redis-cluster
spec:
replicas: 2
selector:
matchLabels:
app: predixy
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: predixy
spec:
containers:
- command:
- predixy
- /etc/predixy/predixy.conf
image: registry.cn-hangzhou.aliyuncs.com/senfel/predixy:v1.0.5
name: predixy
resources:
requests:
cpu: 100m
memory: 30Mi
limits:
cpu: 100m
memory: 30Mi
volumeMounts:
- mountPath: /etc/predixy/
name: predixy-config-dir
readOnly: true
- mountPath: /data/
name: predixy-data-dir
volumes:
- configMap:
name: predixy-config
name: predixy-config-dir
- name: predixy-data-dir
persistentVolumeClaim:
claimName: predixy-pvc-nfs
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: predixy
namespace: redis-cluster
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: predixy
minReplicas: 1
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: AverageValue
averageValue: 80Mi
---
apiVersion: v1
kind: Service
metadata:
name: predixy
namespace: redis-cluster
spec:
externalTrafficPolicy: Cluster
ports:
- name: predixy-port
nodePort: 30617
port: 7617
protocol: TCP
targetPort: 7617
type: NodePort
selector:
app: predixy
kubectl apply -f predixy-deployment.yaml
部署完成後確認 Pod 狀態:
kubectl get pod -n redis-cluster | grep predixy
# predixy-ff95dcbc5-k9zjs 1/1 Running 0 15m
# predixy-ff95dcbc5-nllx8 1/1 Running 0 15m
驗證代理效果
從 K8s 叢集外部直接用 redis-cli 連線測試:
redis-cli -h 10.10.22.91 -p 30617
10.10.22.91:30617> auth ********
OK
10.10.22.91:30617> set name tony
OK
10.10.22.91:30617> get name
"tony"
10.10.22.91:30617> set age 30
OK
10.10.22.91:30617> get age
"30"
可以看到,從外部連線就跟操作單機 Redis 完全一樣,不需要指定任何 cluster 參數,Predixy 在背後幫我們搞定了所有路由和負載平衡。
小結
在 Kubernetes 上部署 Redis Cluster 代理 Predixy 其實並不複雜,核心流程就是:編譯 Predixy 原始碼 → 建置 Docker 映像檔 → 透過 ConfigMap 管理設定 → 用 Deployment 部署並搭配 HPA 自動擴縮。最終效果相當不錯:不僅能從叢集外部輕鬆存取 Redis,而且自動負載平衡到任意節點,讓 Redis Cluster 的日常管理變得簡單許多。如果你也有類似的需求,非常推薦試試看這套方案。

發佈留言