剖析扩容redis后碰到的一个异常情况

1.背景

一个服务依赖redis,采用了多线程模式进行并发操作redis(多实例);
使用的是Java的ShardedJedis;一开始,服务的表现是正常的,无异常;

后面对redis进行了增加加机器部署,通过日志发现这个服务的连接数竟然不够用了,大量报错,报错信息是从pool中获取不到连接数;

2.具体的调用结构图

待补充

3.原因分析

出现上面这种情景,算是一种非正常的情况,为什么这么讲呢?因为底层服务都已经扩容了,为什么客户端从正常变得反而还是不够用呢?

对服务进行扩容,特别通过加机器,上面的情况通过加机器,事实上改变了redis的吞吐量(机器数增加,CPU和内存等扩大了,数据分片增加);

另外一个需要注意的是也提升了请求redis处理的响应时间(毕竟增加了很多硬件),而jedis通过客户端进行hash路由节点的时间是不会
随着节点增多而变化,还是O(1);

如此,就可能打破之前的平衡。导致底层的资源足够用,不再是瓶颈(这里就是说不会阻塞多线程或者说不影响多线程的并发特性),而客户端变得需要更多的连接数才能够用;(特别是客户端采用了多线程的情况下,这种情况极易复现);

4.总结

1.任何服务,都要有这样的一个功能在里面:在超过处理能力时,能够保护自己;在依赖其他服务时,能够有节制的控制自己对依赖的服务的调用(可以参考TCP协议中拥塞控制和流量控制的思路);

说白了,一个服务要能够保护自己,也要能够保护它依赖的;如此这般设计一个服务,才是保证稳定性的一个必备条件。

2.扩容不是那么看似简单的事情,打破一个现有的平衡,就需要打造一个新的平衡,而这个新的平衡要从代码的参数(本文中降低并发参数(单个线程处理能力已经提升了和加大ShardedJedis连接池参数))或者其他方面做重新规划,而不是简单加机器就行的。

你可能感兴趣的:(剖析扩容redis后碰到的一个异常情况)