Redis请求路由

Stella981
• 阅读 281

简介

我们通过上几篇的介绍已经初步的掌握了Redis集群的相关内容,但这都是针对Redis服务端来说。我们还没有使用客户端去操作Reids集群。Redis为了追求性能的最大化,对集群环境的客户端通信协议做了非常大的修改,也就是说如果我们要从单节点连接Redis切换到连接集群环境Redis,那么客户端的代码需要做出相应的修改。


下面我们介绍一下Redis中的请求重定向。

请求重定向

既然是重定向我们就应该了解,重定向指的是通过某种方法将原来的请求重新转向其它的地方,那么Redis中的重定向指的到底是什么呢?我们知道Redis中的任何键都存储到槽中,而通过上几篇文章中我们知道在Redis集群环境中,槽被均匀的分布到多个主节点中了,所以在我们执行任何Redis命令时,和单节点有很大的不同,因为集群环境首先要计算键对应的槽,再根据槽找出相应的节点。如果计算之后,当前键所在的槽是当前节点,那么就直接处理该命令,如果计算完后,不是当前节点,则Redis会显示MOVED重定向错误,也就是告诉客户端该键所对应槽的正确节点是多少。这个就叫做Redis的重定向。下面我们演示一下上述所说的内容。


下面我们启动一个新节点6387。因为该节点没有添加到集群中,所以我们执行set命令时,可以直接返回成功。

Redis请求路由

下面我们在集群中执行同样的命令。

Redis请求路由

我们看在集群环境中执行同样的命令时,Redis提示了MOVED错误。原因也就是上述介绍中的那样。下面我们看一下MOVED重定向的执行流程。也就是如下图所示:

Redis请求路由

在Redis中我们可以使用cluster keyslot {key}命令查看key所对应的槽,然后在通过cluster nodes命令查看每个节点负责的槽,这样我们就可以在执行命令的时候,就可以知道在哪个节点上执行了。我还还是已上图的key为例。具体操作如下图所示:

Redis请求路由

我们用cluster keyslot {key}命令查看键所在的槽是12691。然后我们通过cluster nodes命令知道节点6382负责的槽为12288-16383。所以我们在执行命令时,只有在6382节点上执行才能成功,在其它节点上执行Redis都会报MOVED重定向错误。下面我们将上述执行失败的命令在6382节点执行。

Redis请求路由

在Redis中我们使用redis-cli执行命令时,我们可以添加-c参数,该参数会自动重定向,简化我们手动重定向操作。

Redis请求路由


键命令执行主要分两个步骤:计算槽,查找槽所在的节点。下面我们详细介绍一下这两方面的内容。

计算槽

Redis根据键的使用CRC16函数计算键的散列值,然后在用散列值对16383取余,这样使每个键都可以映射到0-16383槽范围内。

槽节点查找

Redis计算得到键所对应的槽后,需要查找槽所在的节点。集群內通过消息交换每个节点都会知道所有节点的槽的信息。根据MOVED重定向机制,客户端可以随机连接集群内的任意Redis获取键的所在节点,这种客户端叫做傀儡客户端,它的优点是代码实现简单,对客户端协议影响比较小,只需要根据重定向信息再次发送请求即可。但这样也有它的弊端,也就是每次执行键命令前都要到Redis上进行重定向才能找到要执行命令的节点。这样就额外的增加了IO开销。正是因为这样的弊端所以Redis提供了另一种技术实现,也叫Smart(智能)客户端,在下一篇中,我们在介绍Smart相关的内容。

本文分享自微信公众号 - 吉林乌拉(jilinwulacom)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
刚刚好 刚刚好
2个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小森森 小森森
2个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
2个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
1个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
1年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
Easter79 Easter79
1年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Easter79 Easter79
1年前
SpringBoot整合Redis乱码原因及解决方案
问题描述:springboot使用springdataredis存储数据时乱码rediskey/value出现\\xAC\\xED\\x00\\x05t\\x00\\x05问题分析:查看RedisTemplate类!(https://oscimg.oschina.net/oscnet/0a85565fa
helloworld_28799839 helloworld_28799839
2个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue
helloworld_34035044 helloworld_34035044
5个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为