我有一个独立的 Redis 节点作为部署在 OpenShift/K8s 中运行。无论我是否添加带有
redis.conf
文件的 ConfigMap,当我尝试通过 spring.data.redis... 属性连接 Spring Boot 应用程序时,我都会不断收到扭曲的 CROSSSLOT 错误:
CROSSSLOT Keys in request don't hash to the same slot.
org.springframework.data.redis.RedisSystemException: Error in execution
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:52) ~[spring-data-redis-3.2.3.jar:3.2.3]
...
Caused by: io.lettuce.core.RedisCommandExecutionException: CROSSSLOT Keys in request don't hash to the same slot
at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147) ~[lettuce-core-6.3.1.RELEASE.jar:6.3.1.RELEASE/12e6995]
这就是
redis.conf
文件的样子:
requirepass $REDIS_AUTH
cluster-enabled no
tls-cluster no
port 6379
appendonly yes
如果我明确声明我没有集群,为什么会发生这种情况?更好的是:如何让这个错误消失?
我的部署如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-standalone
labels:
app.kubernetes.io/name: redis-standalone
spec:
replicas: 1
selector:
matchLabels:
app: redis-standalone
template:
metadata:
labels:
app: redis-standalone
spec:
automountServiceAccountToken: false
containers:
- name: redis
image: redis-runtime
ports:
- containerPort: 6379
name: client
- containerPort: 6380
name: tls
command:
- /bin/sh
- -c
- redis-server /tmp/conf/redis.conf --requirepass $REDIS_AUTH
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: REDIS_AUTH
valueFrom:
secretKeyRef:
name: redis-auth
key: passphrase
resources:
limits:
cpu: '1'
memory: 2Gi
requests:
cpu: '1'
memory: 2Gi
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 25
timeoutSeconds: 5
periodSeconds: 5
failureThreshold: 5
successThreshold: 1
readinessProbe:
exec:
command:
- /bin/sh
- -c
- |
export REDISCLI_AUTH=$REDIS_AUTH
response=$(redis-cli -h localhost -p 6379 ping)
if [ "$response" != "PONG" ] ; then
echo "Unable to ping the Redis master node"
exit 1
fi
initialDelaySeconds: 15
timeoutSeconds: 5
periodSeconds: 3
volumeMounts:
- name: redis-standlone-config
mountPath: /tmp/conf
readOnly: false
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: { }
- name: redis-standlone-config
configMap:
name: redis-standlone-config
defaultMode: 0775
items:
- key: redis.conf
path: redis.conf
我发现了问题。供将来参考:上面的代码片段是正确的,除了它缺少
persistentVolumeClaim
之外。因此,如果有人需要一个如何将 Redis 独立节点与 K8s 组合在一起的示例,这应该会有所帮助。配置可以进一步调整。
问题是由于我仍然有一个恶意 Redis 节点作为 OCP 内 StatefulSet 的一部分运行而引起的。这干扰了我当前的独立 Redis 节点,并导致了 CROSSSLOT 问题。我删除了这个节点,代码成功地将会话 ID 保存到 Redis 服务器中。