Redis主从结构主节点执行写入后wait命令对性能的影响
这里的Redis主从结构可以是简单的主从,sentinel,redis cluster中的主从等。
wait命令的作用:
此命令将阻塞当前客户端,直到当前Session连接(主节点上)所有的写命令都被传送到指定数据量的slave节点。
如果到达超时(以毫秒为单位),则即使尚未完全传送到达指定数量的salve节点,该命令也会返回(成功传送到的节点的个数)。
该命令将始终返回确认在WAIT命令之前发送的写命令的副本数量,无论是在达到指定数量的副本的情况下,还是在达到超时的情况下。
具体说就是:比如对于1主2从的结构,Wait要求3秒钟之内传送到2个节点,但是达到超时时间3秒钟之后只成功传送到了1个slave节点上,此时wait也不会继续阻塞,而是返回成功传送的节点个数(1)。
有点类似于MySQL的半同步复制,但是效果完全不能跟半同步相比,因为Redis本身没有回滚的功能,这里的wait命令发起之后,即便是超时时间之后没有送到任何一个slave节点,主节点也不会回滚。
wait命令无法保证Redis主从之间的强一致,不过,在主从、sentinel和Redis群集故障转移中,wait能够增强(仅仅是增强,但不是保证)数据的安全性。
既然wait命令在当前连接之后会等待指定数量的从节点确认,其主节点的写入效率必然会收到一定程度的影响,那么这个影响有多大?
这里做一个简单的测试,环境2核4G的宿主机,docker下的集群3主3从的Redis集群,因此不用考虑网络延迟,在执行写入操作之后,使用两个Case,对比使不使用wait命令等待传送到salve的效率,
1,单线程循环写入100000个key值
2,多线程并发,10个线程每个线程写入10000个key,一共写入100000个key
Case1:单线程循环写入100000个key值
结论:不使用wait命令,整体耗时33秒,集群中单个节点的TPS为1000左右;使用wait命令,整体耗时72秒,集群中单个节点的TPS为480左右,整体效率下降了50%多一点
单线程不使用WAIT

单线程使用WAIT(redis_conn.execute_command('wait', 1, 0))

Case2:多线程循环写入100000个key值
结论:不使用wait命令,整体耗时19秒,集群中单个节点的TPS为1700左右;使用wait命令,整体耗时36秒,集群中单个节点的TPS为900左右,整体效率与单线程基本上一致,下降了50%多一点
多线程不使用WAIT,单节点上TPS可达到1700左右

多线程使用WAIT,单节点上TPS可达到850左右

鉴于在多线程模式下,CPU负载接近于瓶颈,因此不能再加更多的线程数,测试数据也仅供参考。

总结:
wait能够在主节点写入命令之后,通过阻塞的方式等待数据传送到从节点,wait能够增强(但不保证)数据的安全性。
其代价或者说性能损耗也是不小的,通过以上测试可以看出,即便是不考虑网络传输延迟的情况下,其性能损耗也超出了50%。
#!/usr/bin/env python
# coding:utf-8
import sys
import time
import datetime
from rediscluster import StrictRedisCluster
import threading
from time import ctime,sleep def redis_cluster_write():
redis_nodes = [ {'host':'172.18.0.11','port':8888},
{'host':'172.18.0.12','port':8888},
{'host':'172.18.0.13','port':8888},
{'host':'172.18.0.14','port':8888},
{'host':'172.18.0.15','port':8888},
{'host':'172.18.0.16','port':8888}]
try:
redis_conn = StrictRedisCluster(startup_nodes=redis_nodes,password='******')
except Exception:
raise Exception
redis_conn.config_set('cluster-require-full-coverage', 'yes')
counter = 0
for i in range(0,100000):
counter = counter+1
redis_conn.set('key_'+str(i),'value_'+str(i))
#redis_conn.execute_command('wait', 1, 0)
if counter == 1000:
print('insert 1000 keys '+str(str(datetime.datetime.now())))
counter = 0 def redis_concurrence_test(thread_id):
redis_nodes = [ {'host':'172.18.0.11','port':8888},
{'host':'172.18.0.12','port':8888},
{'host':'172.18.0.13','port':8888},
{'host':'172.18.0.14','port':8888},
{'host':'172.18.0.15','port':8888},
{'host':'172.18.0.16','port':8888}]
try:
redis_conn = StrictRedisCluster(startup_nodes=redis_nodes, password='******')
except Exception:
raise Exception
redis_conn.config_set('cluster-require-full-coverage', 'yes')
counter = 0
for i in range(0, 10000):
counter = counter + 1
redis_conn.set('key_' + str(thread_id)+'_'+str(counter), 'value_' + str(i))
#redis_conn.execute_command('wait', 1, 0)
if counter == 1000:
print(str(thread_id)+':insert 1000 keys ' + str(str(datetime.datetime.now())))
counter = 0 if __name__ == '__main__':
#redis_cluster_write()
threads = []
for i in range(10):
t = threading.Thread(target=redis_concurrence_test, args=(i,))
threads.append(t)
begin_time = ctime()
for t in threads:
t.setDaemon(True)
t.start()
for t in threads:
t.join()
https://redis.io/commands/wait
Redis主从结构主节点执行写入后wait命令对性能的影响的更多相关文章
- docker学习(四) - docker构建redis主从结构
此文章假设你已经安装了docker,如果没有安装请查询本博客docker安装章节 容器网络 docker network ls 查看默认的网络 Docker安装后,默认会创建下面三种网络类型 在启动 ...
- redis主从、集群、哨兵
redis的主从.集群.哨兵 参考: https://blog.csdn.net/robertohuang/article/details/70741575 https://blog.csdn.net ...
- redis 主从、哨兵、集群
出处: redis主从复制和哨兵 Redis集群方式共有三种:主从模式,哨兵模式,cluster(集群)模式 一.Redis主从复制 主从复制:主节点负责写数据,从节点负责读数据,主节点定期把数据同步 ...
- redis主从集群搭建及容灾部署(哨兵sentinel)
Redis也用了一段时间了,记录一下相关集群搭建及配置详解,方便后续使用查阅. 提纲 Redis安装 整体架构 Redis主从结构搭建 Redis容灾部署(哨兵sentinel) Redis常见问题 ...
- docker安装redis主从以及哨兵
docker安装redis主从以及哨兵 本文使用docker在四台机器上部署一主二从三哨兵的Redis主从结构. 服务器配置 192.168.102.128 主节点 centos7.5 192.168 ...
- Centos7上搭建redis主从
1. 节点(服务器)数量说明 按照redis官方建议:salve和master的数量按照2n+1台服务器(1台master节点,2n台slave节点) 有兴趣的可以了解下redis的master选举机 ...
- shell脚本介绍、shell脚本结构和执行、date命令用法、shell脚本中的变量
7月11日任务 20.1 shell脚本介绍20.2 shell脚本结构和执行20.3 date命令用法20.4 shell脚本中的变量 20.1 shell脚本介绍 1.shell脚本语言是linu ...
- Redis内存使用达到maxmemory设定值后玩家数据无法写入解决 Redis数据“丢失”问题
Redis数据“丢失”问题 - CSDN博客 https://blog.csdn.net/real_myth/article/details/52582739 Redis内存使用达到maxmemory ...
- Redis的主从同步手动执行故障切换
1.准备三个redis配置文件,通过端口的区分,启动三个redis数据库实例,然后配置主从复制. # a6371.conf port 6371 daemonize yes pidfile /data/ ...
随机推荐
- Zabbix添加SNMP自定义监控项OID出现“No Such Instance currently exists at this OID”
原因:zabbix 是用snmpget来获取指定的OID数据,snmpwalk是遍历某个OID下的数据. 所以一定要用snmpget来验证某个OID是否正确. snmptranslate 获取的OID ...
- oracle问题之SYSTEM表空间不足 (二)
杂症二.SYSTEM表空间不足报错 一.杂症: PLSQL登录,报错: ORA-00604: 递归 SQL 层 出现错误 ORA-01653: 表.无法通过(在表空间中)扩展 ORA-02002: ...
- vim 实用快捷键
删除当前行:dd 删除上一行:dj 删除下一行:dk 拷贝当前行:yy 交换当前行和其下一行 交换当前字符和其后的一个字符 剪切当前字符:x 剪切当前光标开始向后三个字符:3x 撤销最近一次修改:u ...
- 《快乐编程大本营》java语言训练班 1课:第一个java程序:你好,范冰冰;
1Java介绍 2安装java环境JDK 3安装web环境tomcat 4安装开发工具Idea2017 5编写第一个程序 ‘你好,范冰冰!’ 地址: http://code6g.com 1.Java介 ...
- webpack入门系列2
前面介绍了使用webpack做最基础的打包,接下来讲讲webpack的进阶. 1.使用 webpack 构建本地服务器: 想不想让你的浏览器监听你的代码的修改,并自动刷新显示修改后的结果,其实Webp ...
- 死磕java(4)
数组 public void int4() { int[] int2 = {1,2,3,4}; System.out.print(int2[2]); } 输出:3 另一种数组的初始化 public ...
- Codeforces_731_B
http://codeforces.com/problemset/problem/731/B 模拟模拟. #include<iostream> #include<cstring> ...
- Codeforces_723_B
http://codeforces.com/problemset/problem/723/B 求括号内单词数和括号外最大单词长度,注意细心,尤其是ok和sum的置0. #include<iost ...
- LNK2019
原因:inline函数被外部文件的函数调用时,必须将inline函数定义在头文件中,不能定义在cpp文件中.
- 新的征程TestOps
TestOps 概念是什么时候提出来的没有去考察,知道TestOps测试运维是在DevOps这个概念下抽象的结果. DevOps,现在几乎每家公司都在谈DevOps,都已经实施,在实施,或者在准备实施 ...