当前位置: 首页 > news >正文

Redis: 集群高可用之MOVED转向和ASK转向解决方案

MOVED转向


1 ) 问题描述

  • 在客户端操作Redis集群的时候 MOVED转向 或 MOVED错误是经常遇到的一类问题
  • 我们先连入集群:$ /usr/local/redis/bin/redis-cli -a 123456 -h 192.168.10.101 -p 6371
  • 之前在Redis中存储过一些数据,比如下面的情况,当输入 $ get username, 会有
    (error) MOVED 14315 192.168.10.103:6375
    
    • 它提示 usrename 这个key的槽在 14315,槽在 103:6375节点
    • 这里它已经提示你key在哪里,但就是不给你
    • 这个涉及到 Redis 的一个官方规范

2 )Redis 规范

  • 这个规范是:
    • 一个 Redis 的客户端, 它向集群中的任意节点发送命令请求
    • 请求节点会对命令请求进行分析,如果该命令是集群可以执行的命令
    • 之后,对这个key做crc16的运算,对16384取余,最后得到一个值
    • 它会对这个key所在的槽进行查找,如果槽在当前节点,则可以顺利执行
    • 否则当前节点会给你返回一个 MOVED 错误
    • 这个 MOVED 错误会告诉你槽和对应的节点在哪里

3 )解决方案


3.1 解决方案 1

  • 让你的这个客户端使用集群的方式来连接就行了
  • $ /usr/local/redis/bin/redis-cli -c -a 123456 -h 192.168.10.101 -p 6371
    • 看到这里多了一个 -c
    • 它会帮助我们做 MOVED 转向
  • 这里使用的是 redis-cli, 另外,你的第三方的客户端, 比如一些可视化的客户端
  • 包括项目里的代码,也要以集群 cluster 的方式接入

3.2 解决方案 2

  • 如果你的客户端不支持集群
  • 但是在你连接你每次获取请求的时候,实际上会拿到这个槽和这个节点的信息
  • 把记录下来之后,再次有这个命令的时候,就可以寻找到正确的那个节点去执行命令
  • 最终集群处于一个稳定状态了,所有的客户端都会保存一个完整的哈希槽对应一个节点的映射记录,集群呢就非常高效了
  • 然后有命令过来,客户端就可以直接向正确的这个节点发送命令请求就无需转向等等的这些操作了
  • MOVED 转向是 Redis 官方规范要求,就是客户端必须要处理MOVED的错误
    • 要么就是以集群的方式连接, 交给那种第三方的东西帮你去做
    • 要么就是你自己去处理
  • 因为我们要实现对用户的一种透明
  • 总结下来
    • 就是保持 server 端,尽量简洁
    • 能不在server端做的事情就不在server端做
    • 降低 server端 的压力

ASK转向


1 ) 问题描述

  • 除了上面 MOVED 转向 和 Redis 的规范,还要求客户端必须也要实现对 ASK 转向的处理
  • 在进行节点与插槽管理的时候,比如添加一个主节点
    • 需要把其他节点的槽重新分配给了这个新的主节点
    • 在这个过程中,移动了很多的槽,槽在做迁移
    • 包括在删除主节点的时候,也是先把那些槽转移到可用的节点上
    • 就是先迁移过去,然后再删它
  • 就在上面这个过程中,如果你发了一个命令,你这个命令要处理的那个键
  • 恰好就属于正在被迁移的这个槽,这时候就会产生 ASK 转向
  • 原节点会在自己的数据里面去找你指定的这个键
  • 如果找到了,那就直接执行客户端发送的命令就返回了
  • 没找到,这个键有可能已经被迁移到目标的节点了, 原节点就会向客户端返回一个ASK错误
  • 指引客户端向正在导入槽的目标节点,再次发送之前要执行的命令
  • 在环境稳定的情况下,是不可能产生ask错误的
    • 因为 ASK 错误,是你的集群中有槽在迁移
    • 而且你请求的那个key 正好就是在迁移的那些槽中才会发生这个错误

2 ) 解决方案


2.1 解决方案1

  • 让你的客户端都使用集群的方式连接,它内部会帮你去做

2.2 解决方案2

  • 以正常的方式去登录,登录之后呢,它这个里边有一个 ASKING 的一个命令
  • 这个 ASKING 的命令是干嘛的呢?
    • 就是打开发送该命令客户端的一个Redis ASK 标识
    • 假设,现在有一些槽正在迁移,我请求的key就在迁移的那些槽中
    • 这个时候 Redis 会给我返回一个error,ask 告诉怎么做
    • 这时候,再敲一下 ASKING 看到这个OK之后
    • 再去获取,就能拿到了这个 key
  • 它的原理就是 ASKING 命令打开 Redis ASKING 的一个标识
  • 当你拿完以后,这个 ASKING 的标识也会被移除,它是一次性的
    • 也就是说你的这个槽在迁移的过程中,如果想要多次获取它
    • 每次获取都得通过 ASKING 获取

ASK 错误和 MOVED 错误的区别

1 ) 关于 MOVED 转向

  • MOVED 错误,它代表的这个槽的负责权已经从一个节点转到另一个节点了
  • 而且就是当节点需要让一个客户端长期的针对某个槽的命令请求发送至另一个节点
  • 节点就会向客户端返回 MOVED 转向
  • 使用了集群的方式登录客户端,这个问题就解决了

2 )关于 ASK 转向

  • ASK 转向只是两个节点在迁移过程中,就是槽迁移过程中使用的一种临时措施
  • 就是当节点需要让客户端仅仅只是在下一次命令请求转向另一个节点
  • 节点向客户户会返回 ASK 的一个转向, 要先发送一个 ASKING 的命令,才能够去请求
  • 否则的话会执行失败

3 )简单理解

  • MOVED 转向相当于告诉你这个槽在哪,你要自己去获取, 解决办法是以集群的方式连入,或者说自己去维护槽对应节点信息, 在每次命令之前自己去做处理判断,让他向正确的节点发送请求

  • ASK 转向是槽迁移的过程中产生的一种错误,它会给你返回 ASK error

  • 解决办法,也是你的客户端以集群的方式接入,它会自己帮你去处理

  • 否则的话,先发送一个 ASKING,然后再去获取,就能正常拿到

相关文章:

  • TS 中类型的继承
  • 数据结构-4.5.KMP算法(旧版上)-朴素模式匹配算法的优化
  • 图像增强论文精读笔记-Low-Light Image Enhancement via a Deep Hybrid Network
  • 初学Java基础Day14---初识面向对象,private关键字和封装及构造方法习题
  • SQLite SQL调优指南及高级SQL技巧
  • 19 基于51单片机的倒计时音乐播放系统设计
  • 举例说明 .Net Core 单元测试中 xUnit 的 [Theory] 属性的用法
  • 【iOS】计算器仿写
  • 数据链路层
  • MongoDB-aggregate流式计算:带条件的关联查询使用案例分析
  • MKV转MP4丨FFmpeg的简单命令使用——视频格式转换
  • 小蒋聊技术——DevOps 是什么“玩意”?
  • 爬虫——爬虫理论+request模块
  • SpringBoot Jar 包加密防止反编译
  • Django学习笔记一:MVT的示例
  • 用java编写飞机大战
  • OpenAPI3常用注解
  • pygame--超级马里奥(万字详细版)
  • 【Android 源码分析】Activity生命周期之onDestroy
  • 游戏中的对象池技术探索(一)
  • 巴基斯坦全国航班仍持续延误或取消
  • 历史地理学者成一农重回母校北京大学,担任历史系教授
  • 美国“贸易战”前线的本土受害者:安静的洛杉矶港和准备关门的小公司
  • 邯郸一酒店办婚宴发生火灾,新郎母亲:饭没吃成酒店还要收费
  • 上报集团社长李芸:发挥媒体优势,让中非民心在数字时代更深层互联互通
  • 央行最新报告:积极落地5月推出的一揽子金融政策,促进经济供需平衡、物价合理回升