MySQL + Canal + Redis的验证中遇到如下问题,如何解决呢?

Redis单实例场景已连通 :
使用 python 的 redis 库可以正常连接 redis 单实例, mysql + canal + redis 全流程已连通,可以实现操作 mysql (比如向 mysql 插入数据), canal 感知 mysql 变化,并获取到变化的数据,然后同步写入 redis 。但是 python 中的 redis 库不支持连接 redis 集群,只支持单实例。

Redis集群场景连通当前遇到的问题是: python 连接 k8s 部署的 redis 集群失败,原因是访问集群 IP 失败 ,详情如下:
gitbub 社区提供连接 redis 集群的 python 库为 redis-py-cluster ,所以我在验证的时候也使用了这个库。
redis-py-cluster 库连接 redis 集群的原理简单描述为,先通过 IP+ 端口的方式配置 redis 集群中的所有实例,创建连接池。连接池创建成功后,就可以执行 redis 命令,向 redis 中操作数据。
操作的时候需要选择在哪个 master 上执行,因为是物理主机 + 端口,所以在执行命令操作的时候逻辑和 redis 单实例一样,访问没有问题。
目前从网上看到的案例均是连接通过物理机部署的 redis 集群,没有看到容器相关的例子。
K8s 部署的 redis 集群,在使用 redis-py-cluster 连接的时候通过 NodePort 的方式将 redis 的 6360 端口暴露出来,然后再连接,这一步可以连接成功。但是当执行 redis 命令的时候,由于 redis 集群的分片机制,redis-py-cluster 需要选择在哪个 master 上执行,这个时候会去获取 master 的 IP 和端口,这个 IP 为集群 IP ,对外是不通的,所以连接失败。
下图为 debug 信息,可以看到在准备执行 set( “ foo ” , “ bar ” ) 命令的时候,选择了集群 IP 为 10.244.199.167 的 master ,并尝试连接,最终连接超时。

目前针对这个问题,想到有三个解决方案,但是都还没有验证可行性。哪种方案能解决问题?
1. 在主机的hosts文件中使用集群IP+端口的方式映射主机管理IP,这样当redis-py-cluster选择集群IP的时候,将对应的集群ip端口映射为可以对外访问的管理IP,来实现对redis集群的访问。
2. 在redis的集群中,再添加一个对外可以访问的IP,这种方式如果可行,可能需在redis-py-cluster选择集群ip的时候,指定配置的可对外访问的IP,需要修改redis-py-cluster的源码。
3. Redis集群部署不使用无头service,而使用普通service,对每个实例都配置一个NodePort将端口暴露出来,然后直接修改redis-py-cluster的源码,将选择集群IP的逻辑修改,选择到master后,使用物理IP加NodePort端口替换,这个需要一定的开发工作量。

参与6

2同行回答

顾黄亮顾黄亮课题专家组技术总监畅销书作者
建议使用第一种方式一般来说,像固定IP访问要格外注意。对于redis而言,集群的容错性非常依赖nodes文件,所以要在容器启动文件中设置正确的pod IP显示全部

建议使用第一种方式
一般来说,像固定IP访问要格外注意。
对于redis而言,集群的容错性非常依赖nodes文件,所以要在容器启动文件中设置正确的pod IP

收起
银行 · 2023-12-31
浏览300
ljosefljosef系统架构师某股份制银行
推进使用第一种方案1、NodePort原理是代理,容易导致redis集群的状态检查出现问题,且涉及到服务的发布以及端口的维护,过于复杂2、hosts文件的配置方式简单,可以通过脚本实现自动化,对于redis部署和客户端请求都没有影响。...显示全部

推进使用第一种方案
1、NodePort原理是代理,容易导致redis集群的状态检查出现问题,且涉及到服务的发布以及端口的维护,过于复杂
2、hosts文件的配置方式简单,可以通过脚本实现自动化,对于redis部署和客户端请求都没有影响。

收起
银行 · 2024-01-04
浏览258

ChatGPT 回答

针对这个问题,我建议您尝试第一种解决方案:在主机的hosts文件中使用集群IP+端口的方式映射主机管理IP。这种方式相对简单,不需要修改redis-py-cluster的源码,也不需要对redis集群做过多的修改。具体操作步骤如下:

  1. 在K8s集群中找到redis集群的Pod所在的节点,使用ssh连接到该节点。
  2. 执行以下命令,获取redis集群的管理IP和端口:

    kubectl get svc <redis-cluster-service-name> -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}'

    其中,&lt;redis-cluster-service-name>为redis集群的Service名称。

  3. 在该节点的hosts文件中添加以下内容:

    <redis-cluster-management-ip> <redis-cluster-ip>

    其中,&lt;redis-cluster-management-ip>为redis集群的管理IP,&lt;redis-cluster-ip>为redis集群的IP。

  4. 在python代码中使用&lt;redis-cluster-management-ip>和端口连接redis集群即可。

这种方式的缺点是需要在每个节点上都进行hosts文件的修改,如果节点比较多,维护起来可能会比较麻烦。但是相对来说比较简单,可以先尝试一下。

相关问题

相关资料

相关文章

问题状态

  • 发布时间:2023-12-29
  • 关注会员:3 人
  • 问题浏览:1099
  • 最近回答:2024-01-04
  • X社区推广