VerneMQ集群重启后保留消息丢失,配置持久化仍未解决
我们运行一个包含2个VerneMQ代理的集群,依次启动单个代理时一切正常,但同时启动两个代理后,所有保留消息丢失。
为解决该问题,我们尝试为VerneMQ配置持久化卷,已确认PVC已与VerneMQ绑定且存储卷已创建,但重启两个Pod后,保留消息仍未同步,导致数据丢失。
存储类配置
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: azure-storage provisioner: kubernetes.io/azure-disk parameters: storageaccounttype: Standard_LRS kind: managed
VerneMQ的PVC模板配置
{{- if .Values.persistentVolume.enabled }} volumeClaimTemplates: - metadata: name: data annotations: {{- range $key, $value := .Values.persistentVolume.annotations }} {{ $key }}: {{ $value }} {{- end }} spec: accessModes: {{- range .Values.persistentVolume.accessModes }} - {{ . | quote }} {{- end }} resources: requests: storage: {{ .Values.persistentVolume.size }} {{- if .Values.persistentVolume.storageClass }} {{- if (eq "-" .Values.persistentVolume.storageClass) }} storageClassName: "" {{- else }} storageClassName: "{{ .Values.persistentVolume.storageClass }}" {{- end }} {{- end }} {{- else }} - name: data {{- end }}
PVC状态
执行命令 kubectl get pvc 返回结果:
data-vernemq-0 Bound xxx 5Gi RWO default 19h data-vernemq-1 Bound xxx 5Gi RWO default 18h
存储类信息
执行命令 kubectl get storageclass 返回结果:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE azure-storage kubernetes.io/azure-disk Delete Immediate false 19h
问题排查与配置遗漏点
VerneMQ持久化机制认知偏差
VerneMQ默认的保留消息存储是节点本地级别的,即便给每个节点挂载独立PVC,节点间也不会自动同步保留消息。当前配置只是给每个Pod分配了独立持久化卷,但没有解决集群内数据共享的核心问题。PVC存储类绑定错误
从PVC状态可见,两个PVC使用的是default存储类,而非你定义的azure-storage。需检查Values.persistentVolume.storageClass是否正确设置为azure-storage,否则PVC会自动绑定到默认存储类,可能不符合预期。缺少集群级共享存储配置
要实现保留消息跨节点同步,VerneMQ需要配置共享存储后端(如Redis、PostgreSQL),或者使用支持ReadWriteMany(RWX)模式的共享卷(如Azure Files)让所有节点访问同一份存储。当前每个节点用独立的ReadWriteOnce(RWO)卷,无法实现数据共享,重启后各节点本地数据自然无法同步。集群启动顺序导致的一致性问题
同时启动两个节点时,VerneMQ集群可能未完成握手就开始处理消息,导致保留消息未被正确写入或同步。依次启动时节点先完成集群加入,数据能正常写入,但独立卷依然无法解决跨节点同步的根本问题。
修复建议
- 配置共享存储后端:修改
vernemq.conf启用共享保留消息存储,示例如下:
也可使用PostgreSQL作为共享存储,确保所有节点读写同一份保留消息数据。retention_backend = redis redis.host = <你的Redis服务名称> - 改用RWX模式共享卷:将存储类改为支持RWX的类型(如Azure Files),修改PVC的
accessModes为ReadWriteMany,让所有VerneMQ节点挂载同一份存储卷,实现本地存储共享。 - 修正存储类绑定:确认
Values.persistentVolume.storageClass设置为azure-storage,确保PVC使用你定义的存储类。 - 调整集群启动策略:先启动一个节点,等待其完成集群初始化后再启动第二个节点,避免集群启动期间的数据不一致。
内容的提问来源于stack exchange,提问作者Logan

