关于redis批量获取数据pipeline

关于redis批量获取数据pipeline,第1张

Redis是建立在TCP协议上的CS架构,客户端client对redis server采取请求响应的方式交互每次交互会有网络延迟,大约30ms

假设有这样一个场景,redis中存储上千个key值,获取每个key对应field的value,那么要向redis请求上千次 hget(key, field),获取响应也是对应的次数如果能一次性将所有请求提交给server端,执行完成后批量获取响应,只需向redis请求1次,性能获大幅提升

没有用pipeline之前,基本上获取所有数据需要90多s,现在只需03s,性能提升清晰可见

实现以下场景:定时任务每隔1s执行任务函数,但是任务函数执行完成的时间比1s要长,此时启动定时任务要加上两个参数,否则会报错

可允许的实例个数,如果没有设置,则默认为1,表示id相同的任务实例数

像上面的例子中,会报skipped: maximum number of running instances reached (1)的错误,意思APScheduler试图重新执行作业,但前一个仍在运行。

这个参数可以理解为任务的超时容错配置,给executor 一个超时时间,这个时间范围内要是该跑的还没跑完,就别再跑了

像上面的例子中,会报Run time of job …… next run at: ……)” was missed by的错误

查看:

方法1:在redis-cli命令行使用:info clients可以查看当前的redis连接数

127001:6379> info clients

connected_clients:621

client_longest_output_list:0

client_biggest_input_buf:0

blocked_clients:0

127001:6379>

方法2:config get maxclients 可以查询redis允许的最大连接数

127001:6379> CONFIG GET maxclients

##1) "maxclients"

##2) "10000"

127001:6379>

设置:

2config set maxclients num 可以设置redis允许的最大连接数

127001:6379> CONFIG set maxclients 10

OK

127001:6379>

3启动redisservice服务时加参数--maxclients 100000来设置最大连接数限制

redis-server --maxclients 100000 -f /etc/redisconf

获取客户端信息命令

CLIENT LIST 获取客户端列表

CLIENT SETNAME 设置当前连接点redis的名称

CLIENT GETNAME 查看当前连接的名称

CLIENT KILL ip:port 杀死指定连接

CLIENT LIST

##id=3 addr=127001:36588 fd=5 name= age=7 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

CLIENT SETNAME js

##OK

CLIENT LIST

##id=3 addr=127001:36588 fd=5 name=js age=37 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client

CLIENT GETNAME

##"js"

CLIENT KILL id 3

##(integer) 0

释放超时链接配置

查看超时配置

config get timeout

设置超时配置

config set timeout 600

每个redis实例在启动时候,都会随机生成一个长度为40的唯一字符串来标识当前运行的redis节点,查看此id可通过命令info server查看。

当主从复制在初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来,当断线重连时,从节点会将这个runid发送给主节点。主节点根据runid判断能否进行部分复制:

如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会更具offset偏移量之后的数据判断是否执行部分复制,如果offset偏移量之后的数据仍然都在复制积压缓冲区里,则执行部分复制,否则执行全量复制;

如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的redis节点并不是当前的主节点,只能进行全量复制;

下图为redis28之后的提供的psync命令执行过程:

图文说明:

如果从服务器以前没有复制过任何主服务器,或者之前执行过SLAVEOF no one命令,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC -1命令,主动请求主服务器进行完整重同步(因为这时不可能执行部分重同步);

相反地,如果从服务器已经复制过某个主服务器,那么从服务器在开始一次新的复制时将向主服务器发送PSYNC <runid> <offset>命令:其中runid是上一次复制的主服务器的运行ID,而offset则是从服务器当前的复制偏移量,接收到这个命令的主服务器会通过这两个参数来判断应该对从服务器执行哪种同步 *** 作,如何判断已经在介绍runid时进行详细说明。

根据情况,接收到PSYNC命令的主服务器会向从服务器返回以下三种回复的其中一种:

如果主服务器返回+FULLRESYNC <runid> <offset>回复,那么表示主服务器将与从服务器执行完整重同步 *** 作:其中runid是这个主服务器的运行ID,从服务器会将这个ID保存起来,在下一次发送PSYNC命令时使用;而offset则是主服务器当前的复制偏移量,从服务器会将这个值作为自己的初始化偏移量;

如果主服务器返回+CONTINUE回复,那么表示主服务器将与从服务器执行部分同步 *** 作,从服务器只要等着主服务器将自己缺少的那部分数据发送过来就可以了;

如果主服务器返回-ERR回复,那么表示主服务器的版本低于Redis 28,它识别不了PSYNC命令,从服务器将向主服务器发送SYNC命令,并与主服务器执行完整同步 *** 作。

 由此可见psync也有不足之处,当从库重启以后runid发生变化,也就意味者从库还是会进行全量复制,而在实际的生产中进行从库的维护很多时候会进行重启,而正是有由于全量同步需要主库执行快照,以及数据传输会带不小的影响。因此在40版本,psync命令做了改进,以下说明。

redis40新版本除了增加混合持久化,还优化了psync(以下称psync2)并实现即使redis实例重启的情况下也能实现部分同步,下面主要介绍psync2实现过程。psync2在psync1基础上新增两个复制id(可使用info replication 查看如下图):

master_replid: 复制id1(后文简称:replid1),一个长度为41个字节(40个随机串+’0’)的字符串,每个redis实例都有,和runid没有直接关联,但和runid生成规则相同。当实例变为从实例后,自己的replid1会被主实例的replid1覆盖。

master_replid2:复制id2(后文简称:replid2),默认初始化为全0,用于存储上次主实例的replid1。

在40之前的版本,redis复制信息完全丢失,所以每个实例重启后只能进行全量复制,到了40版本,主要解决了两种情况下不能进行增量复制的问题:

第一步:存储复制信息

redis在关闭时,通过shutdown save,都会调用rdbSaveInfoAuxFields函数,把当前实例的repl-id和repl-offset保存到RDB文件中,当前的RDB存储的数据内容和复制信息是一致性的可通过redis-check-rdb命令查看。如下图所示:

第二步:重启后加载RDB文件中的复制信息

redis加载RDB文件,会专门处理文件中辅助字段(AUX fields)信息,把其中repl_id和repl_offset加载到实例中,分别赋给master_replid和master_repl_offset两个变量值,特别注意当从库开启了AOF持久化,redis加载顺序发生变化优先加载AOF文件,但是由于aof文件中没有复制信息,所以导致重启后从实例依旧使用全量复制!

第三步:向主库上报复制信息,判断是否进行部分同步

从实例向主库上报master_replid和master_repl_offset+1;从实例同时满足以下两条件,就可以部分重新同步,否则执行全量同步:

从实例上报master_replid串,与主实例的master_replid1或replid2有一个相等,用于判断主从未发生改变;

从实例上报的master_repl_offset+1字节,还存在于主实例的复制积压缓冲区中,用于判断从库丢失部分是否在复制缓冲区中;

psync2除了解决redis重启使用部分同步外,还为解决在主库故障时候从库切换为主库时候使用部分同步机制。redis从库默认开启复制积压缓冲区功能,以便从库故障切换变化master后,其他落后该从库可以从缓冲区中获取缺少的命令。该过程的实现通过两组replid、offset替换原来的master runid和offset变量实现:

第一组:master_replid和master_repl_offset:如果redis是主实例,则表示为自己的replid和复制偏移量; 如果redis是从实例,则表示为自己主实例的replid1和同步主实例的复制偏移量。

第二组:master_replid2和second_repl_offset:无论主从,都表示自己上次主实例repid1和复制偏移量;用于兄弟实例或级联复制,主库故障切换psync。

判断是否使用部分复制条件:如果从库提供的master_replid与master的replid不同,且与master的replid2不同,或同步速度快于master; 就必须进行全量复制,否则执行部分复制。

实验如下:

启动三个实例17220170155:6379(主) ,17220170155:6380(从) ,17220170155:6381(从)

在6379上执行info replication, 如下:

在6380上执行info replication, 如下:

在6381上执行info replication, 如下:

由上图可知, 此时6381和6380的master_replid都存的是6379的master_replid

然后执行shutdown关闭6379实例, 在6380上执行slaveof no one, 6381上执行slaveof 17220170155 6380;

此时通过info replication命令查看6380和6381的信息如下:

由上图可知6379的master_replid都被存到了master_replid2上, 表示为上一次主实例的master_replid,

这时再去查看6381的日志, 如下图:

可以看出6381切换master到6380成功, 并且增量复制也是成功的

这就完成了故障切换下增量复制功能

redis是类似key_value形式的快速缓存服务。类型较丰富,可以保存对象、列表等,支持的 *** 作也很丰富,属于内存数据库,且可以把内存中的数据及时或定时的写入到磁盘。可设置过期自动删除,速度快,易于使用。

以上就是关于关于redis批量获取数据pipeline全部的内容,包括:关于redis批量获取数据pipeline、Redis连接数与最大连接数、redis-4.0.x中如何解决redis重启runid变化引起的全量复制等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9741065.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存