数据库
首页 > 数据库> > Redis cpu100%的探索

Redis cpu100%的探索

作者:互联网

最近网站在高流量时段总“挂”,CPU达到100%导致的,原因是redis CPU使用过大。

公司的Terry解决并复现了这个问题。那么今天就借用Terry文档咱们整理下做个分享,这个分享主要想讲述的是在开发或运维中遇见这种不能直接定位的“灾难”,我们要有的分析问题思路。

首先说下环境:redis服务器为单核,nginx负载均衡6台,worker_processes 2,PHP 静态CGI进程 220。

先分析下达到这种情况的场景:

1.长链接导致僵尸进程

2.在链接数过多后,val过大导致慢插入

3.存入磁盘快照过大,频次过高

4.主从存在频繁全量量同步

5.⽹络问题

6.慢查询

我们要了解redis中连接的定义,connect脚本结束后被释放,pconnect进程结束后被释放。

PHP中redis->close() 。

1)当使用connect 当执⾏close(),会向redis发送quit指令,直接断开连接。不执close命令则php脚本运行完后会自动断开连接 。

2)当使⽤pconnect,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行。

3)当使用pconnect,close的作用仅使当前php脚本不能再进行redis请求,但无法真正关闭redis长连接,连接在后续使用同一个fpm进程时仍然会被重用,直至fpm进程生命周期结束或被杀死。

参考链接:https://www.cnblogs.com/huanxiyun/articles/6554670.html

php-fpm的生命周期:进程管理理⼀一共有三种模式,ondemand(按需)、static(静态)、dynamic(动态)-默认。

ondemand:在php-fpm启动的时候,不会给这个pool启动任何一个worker,是按需启动,当有连接过来才会启动。

static:php-fpm启动采用固定数量的worker,在运行期间也不会扩容,虽然也有1秒的定时器,仅限于统计一些状态信息,例例如空闲worker个数,活动worker个数,⽹网络连接队列长度等信息。

dynamic:在php-fpm启动时,会初始启动⼀一些worker,在运行过程中动态调整worker数量,worker的数量受限于pm.max_children配置,同时受限全局配置process.max

我们的redis和PHP-FPM配置是pconnect,startic。

 

这个测试中本是要观察长链接是否跟fpm进程同一个生命周期,刚开始以为自己的理解有问题,后来才发现redis设置了心跳,有这个设置后连接在60秒内没有动作就会被杀死。

 

关闭心跳后测试按照预期,证明了redis的链接跟fpm进程间的关系。

redis-benchmark压力测试工具是一个测试连接非常好用的工具,这里不多做介绍有兴趣请点击连接 http://www.redis.cn/topics/benchmarks.html

redis-benchmark -h 111.111.111.111 -p 6380 -c 9990 -n 1000 -q 9990的并发访问1000次发现在高并发的状态下CPU确实上升了2%但达到100%还差的很远。

所以连接数过多的猜想是不对的。

单纯的连接数过多是达不到我们想要的效果的,那么在这里做一个延伸就是在连接数过多的情况下插入大的val。

在这个测试中CPU在多连接数的基础上再次提升了3%,也不是我们想要的结果。

这里我们看下写入磁盘快照

配置:save 900 1,save 300 10,save 60 10000,rdbcompression yes。这段配置意思是说每15分钟至少有1次key的改变触发1次持久化,每5分钟至少10次key改变触发1次持久化,每60秒10000个key改变触发1次持久化,rdbcomprssion的意思是说是否压缩存储。

看了下持久化日志。

RDB:75MB of memory used by copy-on-write

可以看出我的存储数据为75MB,接下来我把持久化数据存储到268MB,CPU的攀升比之前的幅度大很多但也只达到了35%。可见也不是这个原因。

主从同步我们服务器没有做,网络原因也不过多考虑。

我们看下慢查询。

是否因为val值过大导致慢查询。这个时候我们观察到我们代码中session是存储在redis当中的,会有一些空值存在即:有key但里面没有val。经过测试我们得出在配置session存入redis时只要执行session_start()函数那么redis就会出现一条空值数据。

这时我们观察了下keys发现有460W,经过测试果然是这个问题,在代码中有很多keys()查询,这会导致redis查询没一个key,当在本地复现这个问题时在key达到200W时CPU就已经“挂”掉了。

查下redis的文档发现了一个很有趣的现象,文档中说keys 返回所有匹配的键(说白了就是全表查询)在入门级笔记本中100W个key的查询时间是40毫秒。好吧他没说100W+之后的查询效率,这就告诉你在key达到100W+后keys查询会大大降低查询速度。

标签:探索,fpm,worker,cpu100%,redis,查询,key,Redis,php
来源: https://www.cnblogs.com/q3619940/p/10671979.html