高并发情况下Redis 的可用性测试与分析及部署架构说明

一、Redis AOF模式设置
修改配置文件redis.conf参数:
appendonly yes
# appendfsync always
 appendfsync everysec
# appendfsync no


二、测试方法
创建多线程,其中每一个线程执行一个无限循环向Redis 发送set key-value命令,由于处理器执行一次循环操作的速度非常快,因此这样每一个线程都模拟了一个多并发的情况。

<span style="font-size:18px;">class pushThread extends Thread { 
	private JedisPool jedisPool;
	private Jedis jj;
	private String threadName;
	public pushThread(String threadName) {
    	jedisPool  = new JedisPool(new JedisPoolConfig(),"localhost");
    	jj = jedisPool.getResource();
    	this.threadName = threadName;
	}
	public void run() {
		int n = 1;
    		for(;;) {
    			jj.set("key" + threadName, "" + n);
    			System.out.println(n + " has been set by " + threadName);
     		n++;
    		}
	}
}</span>

<span style="font-size:18px;">public static void main(String[] args) {
for(int i = 0; i < 80; i++) {
new pushThread("" + i).start();
}
}</span>


三、测试说明

1、读取Redis的timeout异常
创建线程数在50以下时程序可以正常执行,当线程数设置为100以上时,某些线程执行出现异常:
java.net.SocketTimeoutException: Read timed out

造成这种异常可能有以下两个原因:
原因一:在连接Redis的Jedis的默认构造方法中,超时一般被默认设置为2000毫秒,也就是2秒。当然这个时间,对于Redis这种从内存中读取数据的数据库来说应该是相当大了,但是为什么还会超时?可能的原因是,当Redis的数据量很大时,可能在Redis server可能会出现超时。因为Redis在运行时,是单线程来处理所有的客户端的连接的。当连接数非常多或者数据量很大时,也要遵循FIFO的调度策略,这就造成等待队列过长,因此可能会出现超时的情况。

解决方法:尝试在调用jedis的构造方法时,将超时时间设置的更大些。
Jedis jedis = new Jedis("127.0.0.1", 8371,100000);//将超时时间设置为100000毫秒


原因二:因为Redis是基于TCP连接的,大量数据反复交互相当于远程读写内存的操作,势必会造成带宽的使用紧张,在带宽吃紧的情况下,Redis客户端即Jedis拿不到连接或拿不到后续数据包。

解决方法:最直接的方法是增加带宽,但针对这种问题,对并发交互数据的频率进行调整,对数据量进行精减才是解决这一问题的最佳方案。

2、AOF模式相关问题与快照模式的优点
创建50个线程,执行1分钟之后,每个线程大约循环了13800次,AOF日志(appendonly.aof)的大小是25.5M。Redis重启时会先加载appendonly.aof文件,加载25M配置文件大约耗时5秒。同时做了多次突然关闭Redis 的试验,日志记录准确没有出现丢失数据的情况。
AOF生成的命令日志,只是操作过程的记录文件,它的主要作用是保证高可用性。因为在高并发的情况下,AOF日志文件appendonly.aof会迅速变得很大(当我将线程数调整为50,1分钟appendonly.aof 的文件大小已达到了25M)。

Redis AOF rewrite(重新生成一份AOF文件)设置:
(1)Redis接收到客户端发送的BGREWRITEAOF指令请求,执行AOF rewrite;
(2)在Redis配置文件redis.conf中,如果用户设置了auto-aof-rewrite-percentage和auto-aof-rewrite-min-size参数,当AOF日志文件大小大于auto-aof-rewrite-min-size,同时AOF文件大小的增长率大于auto-aof-rewrite-percentage时,会自动触发AOF rewrite;

另外需要注意的是根据网上反馈AOF曾经出现过,因为个别命令导致 AOF 文件在重新载入时,无法恢复原样的问题。

快照模式的优点是:日志的内容更加紧凑,可以在加密后保存到其他数据中心或者亚马逊 S3;快照可以最大化 Redis 的性能:父进程在保存快照文件时唯一要做的就是生成一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作;
快照在恢复大数据集时的速度比 AOF 的恢复速度要快。一个原因是快照文件中每一条数据只有一条记录,不会像AOF日志那样可能有一条数据的多次操作记录。所以每条数据只需要写一次就行了。另一个原因是快照文件的存储格式和Redis数据在内存中的编码格式是一致的,不需要再进行数据编码工作,所以在CPU消耗上要小于AOF日志的加载。
四、部署架构说明
结合以上分析,建议采用如下的部署方式:Redis Master上不做持久化保证读写性能,Slave上同时开启RDB(快照)和AOF,保证数据的安全性。当 Redis启动时,程序会优先使用 AOF 文件来恢复数据集,因为AOF文件所保存的数据通常是最完整的。

在服务器运行时对 RDB 文件进行备份。RDB文件一旦被创建,就不会进行任何修改,当服务器要创建一个新的RDB文件时,它先将文件的内容保存在一个临时文件里,当临时文件写入完毕才会替换原来的RDB文件,因此备份RDB文件都是相对安全的。


©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页