美文网首页
redis阻塞问题

redis阻塞问题

作者: 迟凝丶捏米么 | 来源:发表于2019-11-27 17:19 被阅读0次

    以下是学习笔记

    • 出现cpu过高的原因有:
      1、连接数过多,通过info clients查看
      2、慢查询,因为redis是单线程,如果有慢查询的话,会阻塞住之后的操作,通过redis日志查 待补充
      3、value值过大?比如value几十兆,当然这种情况比较少,其实也可以看做是慢查询的一种
      4、aof重写/rdb fork发生?瞬间会堵一下Redis服务器
    # 修改慢查询时间与队列长度
    
    # 方式一
    修改配置文件
    # The following time is expressed in microseconds, so 1000000 is equivalent
    # to one second. Note that a negative number disables the slow log, while
    # a value of zero forces the logging of every command.
    # 这里默认是10ms 10毫秒
    slowlog-log-slower-than 10000
    
    # There is no limit to this length. Just be aware that it will consume memory.
    # You can reclaim memory used by the slow log with SLOWLOG RESET.
    # 慢日志队列长度
    slowlog-max-len 128
    
    # 方式二
    config set slowlog-log-slower-than 20000
    config set slowlog-max-len 1000
    config rewrite
    
    # 查看命令
    # 显示队列长度
    127.0.0.1:6379> SLOWLOG LEN
    128
    
    # 默认显示队列尾部的10个
    127.0.0.1:6379> SLOWLOG GET
    
    # 默认显示队列尾部的最后一个
    127.0.0.1:6379> slowlog get 1
    71057             // slowlog唯一编号id
    1574822285        // 查询的时间戳
    10184             // 查询的耗时(微秒),如表示本条命令查询耗时47微秒
    KEYS              // 查询命令,完整命令为 KEYS history_1_*,slowlog最多保存前面的31个key和128字符
    history_1_*
    
    • 对应解决方案:
      1、连接数过多解决:
      1.1 关闭僵尸连接
      采用redi-cli登录,采用client kill ip:port(redis远程连接的ip和端口)。
      需要采用脚本批量删除多个连接
      1.2 修改redis timeout参数
      采用redis-cli登录,采用config set timeout xx 设置redis的keepalive时间
      1.3 修改redis进程的文件数限制
      echo -n "Max open files 3000:3000" > /proc/PID/limits
      1.4 修改系统参数的最大文件数限制
      /etc/security/limits.conf
      2、对慢查询进行持久化,比如定时存放到mysql之类。(redis的慢查询只是一个list,超过list设置的最大值,会清除掉之前的数据,也就是看不到历史)
      3、限制key的长度和value的大小

    • 使用redis的注意事项:
      1、Master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化。
      2、如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
      3、为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网内。
      4、尽量避免在压力较大的主库上增加从库
      5、为了Master的稳定性,主从复制不要用图状结构,用单向链表结构更稳定,即主从关系为:Master<--Slave1<--Slave2<--Slave3.......,这样的结构也方便解决单点故障问题,实现Slave对Master的替换,也即,如果Master挂了,可以立马启用Slave1做Master,其他不变
      6、使用Redis负载监控工具:redis-monitor,它是一个Web可视化的 redis 监控程序

    针对keys*的解决方案

    方案一:初步方案采用scan,一个基于游标的迭代器,进行处理

    // jedis.jar的版本为3.1.0
    ScanParams scanParams = new ScanParams();
    scanParams.match(patternKey);
    scanParams.count(1000);
    ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
    

    Redis的SCAN操作由于其整体的数据设计,无法提供特别准的scan操作,仅仅是一个“can't guarantee,just do my best”的实现:

    • 提供键空间的遍历操作,支持游标,复杂度O(1), 整体遍历一遍只需要O(N);
      提供结果模式匹配;
    • 支持一次返回的数据条数设置,但仅仅是个hints,有时候返回的会多;
    • 弱状态,所有状态只需要客户端需要维护一个游标;
    • 无法提供完整的快照遍历,也就是中间如果有数据修改,可能有些涉及改动的数据遍历不到;
    • 每次返回的数据条数不一定,极度依赖内部实现;
    • 返回的数据可能有重复,应用层必须能够处理重入逻辑;上面的示例代码中, redisTemplate.execute方法是个Set,相当于已经对于返回的key去重
    • count是每次扫描的key个数,并不是结果集个数。count要根据扫描数据量大小而定,Scan虽然无锁,但是也不能保证在超过百万数据量级别搜索效率;count不能太小,网络交互会变多,count要尽可能的大。在搜索结果集1万以内,建议直接设置为与所搜集大小相同。

    方案二:主从集群,进行分离 待补充……

    方案三:在放入之前想策略 待补充……

    Redis 如何高效安全删除大 Hash Key

    Redis 如何高效安全删除大 Hash Key

    Redis删除大的集合键的耗时, 测试估算,可参考;和硬件环境、Redis版本和负载等因素有关

    Key类型 Item数量 耗时
    Hash ~100万 ~1000ms
    List ~100万 ~1000ms
    Set ~100万 ~1000ms
    Sorted Set ~100万 ~1000ms

    参看资料
    redis cpu占用过高排查
    SCAN 命令的基本用法

    相关文章

      网友评论

          本文标题:redis阻塞问题

          本文链接:https://www.haomeiwen.com/subject/xonuwctx.html