redis 限制内存使用大小

  • 记录一次生产环境问题排查过程:
    • 生产环境部署方式:nginx + uwsgi + flask
    • 问题描述:

      发现生产环境中之前正常运行的服务突然不可用了,查看程序日志发现部分接口访问时报I/O写错误,nginx acess.log显示504,error.log显示 upstream time out.
      同时 netstat -apn | grep 6379 | wc -l 检查发现redis存在大量连接,进一步检查发现其中大多为 SYN_SENT 包,连接大多归属于uwsgi 进程。

  因为程序中有很多接口被调用是会访问redis, 以为是redis连接池导致,对程序中的redis连接池进行优化后重启服务,刚启动时一切正常,http 200, 但几分钟后服务再次挂掉,http 504.

  • 检查系统资源使用情况,发现 kswapd0 进程CPU占用很高,这个进程是当物理内存不足时,会将一部分硬盘当做虚拟内存来使用, 使用swap分区与内存换页操作交换数据,导致CPU占用过高, 再细看发现redis-server内存占用已超过100%:
    在这里插入图片描述

  • 进入redis中查看info memory和各存储数据的key下数据量,果然存在大量未处理完毕的数据。

    到此问题终于是找到了。

  • 设置redis最大占用内存

    # 编辑redis配置文件,加入最大内存使用限制,我根据服务器的情况设置为3G
    maxmemory 3221225472
    
  • 设置redis数据过期策略:

    • redis中有6种过期策略:
    # 根据LRU算法生成的过期时间来删除
    # volatile-lru -> remove the key with an expire set using an LRU algorithm
    # 根据LRU算法删除任何key。
    # allkeys-lru -> remove any key accordingly to the LRU algorithm
    # 根据过期设置来随机删除key。
    # volatile-random -> remove a random key with an expire set
    # 无差别随机删。
    # allkeys-random -> remove a random key, any key
    # 根据最近过期时间来删除(辅以TTL)
    # volatile-ttl -> remove the key with the nearest expire time (minor TTL)
    # 谁也不删,直接在写操作时返回错误。
    # noeviction -> don't expire at all, just return an error on write operations
    
    • 在redis配置文件中设置过期策略为:
      maxmemory-policy allkeys-lru

        一开始是设置为volatile-lru的,但是该策略只是清除设置过期时间的key值,因为很多key并没有设置过期时间。因此修改为maxmemory-policy allkeys-lru,指明非活跃近期很少用的key值清除.
        在使用maxmemory-policy allkeys-lru策略时,内存超限后将不再存储数据,但数据的读取删除操作不会受影响,超限时显示错误
          OOM command not allowed when used memory > 'maxmemory'
      在这里插入图片描述

  • 重启程序,至此服务终于正常运行。

总结:本次的问题归根结底是redis中存储入了大量脏数据,但数据处理并没有及时的清理掉这部分数据,最终导致服务停滞,allkeys-lru策略有可能会将长期未用但实际有用的数据清理掉,所以还是应优化数据处理为主。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值