开发者

关于Redis bigkeys命令会阻塞问题的解决

目录
  • 前言
  • 一、 顺丰高级开发工程师在线执行了 Redis 危险命令导致某公司损失 400 万
  • 二、测试一下1000万数据的性能
    • 1、编写脚本文件
    • 2、写入Redis1000万数据
    • 3、通过keys * 查看1000万数据
    • 4、通过配置文件禁止keys *的使用
  • 三、使用scan替代keys *
    • 四、拒绝bigkey
      • 1、阿里云Redis开发规范
      • 2、出现bigkey时如何删除?
      • 3、bigkey会造成哪些问题?
      • 4、如何发现bigkey?

    前言

    今天分享一次Redis引发的线上事故,避免再次踩雷,实现快速入门,丰富个人简历,提高面试level,给自己增加一点谈资,秒变面试小达人,BAT不是梦。

    一、 顺丰高级开发工程师在线执行了 Redis 危险命令导致某公司损失 400 万

    关于Redis bigkeys命令会阻塞问题的解决

    一个命令损失数百万,这,需要赔偿吗?

    代码不规范,同事两行泪,撸码需谨慎!

    处于好奇考虑,我来测试一下,这到底是什么问题?

    二、测试一下1000万数据的性能

    1、编写脚本文件

    写入1000万数据。

    for((i=1;i<=10000000;i++)); do echo "set k$i 哪吒编程$i" >> /tmp/test1.txt;done;
    

    通过/tmp/test1.txt查看一下是否写入成功。

    关于Redis bigkeys命令会阻塞问题的解决

    2、写入Redis1000万数据

    cat /tmp/test1.txt | redis-cli -a 111111 --pipe
    

    关于Redis bigkeys命令会阻塞问题的解决

    3、通过kjavascripteys * 查看1000万数据

    关于Redis bigkeys命令会阻塞问题的解决

    4、通过配置文件禁止keys *的使用

    在redis.conf文件中配置security:

      rename- commphpand keys ""
      rename- command flushdb ""
      rename- command flushall ""
    

    三、使用scan替代keys *

    Redis Scan 命令用于迭代数据库中的数据库键。

    SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程。

    SCAN 返回一个包含两个元素的数组, 第一个元素是用于进行下一次迭代的新游标, 而第二个元素则是一个数组, 这个数组中包含了所有被迭代的元素。如果新游标返回 0 表示迭代已结束。

    scan语法:

    SCAN cursor [MATCH pattern] [COUNT count]

    关于Redis bigkeys命令会阻塞问题的解决

    四、拒绝bigkey

    1、阿里云Redis开发规范

    阿里云Redis开发规范中明确规定“拒绝bigkey(防止网卡流量、慢查询)”

    String类型控制在10KB以内,hash、list、set、zset元素个数不要超过5000。

    2、出现bigkey时如何删除?

    1. String类型的用del删除。
    2. 其它类型使用hscan、sscan、zscan方式渐进式删除,同时要避免bigkey过期时间自动删除问题,因为它会造成主线程阻塞。

    Hash 删除: hscan+hdel

    public void delBigHasphph(String host, int port, String password, String bigHashKey) {
        Jedis jedis = new Jedis(host, port);
        if (password != null && !"".equals(password)) {
            jedis.auth(password);
        }
        ScanParams scanParams = new ScanParams().count(100);
        String cursor = "0";
        do {
            ScanResult<Entry<String, String>> scanResult = jedis.hscan(bigHashKey, cursopythonr, scanParams);
            List<Entry<String, String>> entryList = scanResult.getResult();
            if (entryList != null && !entryList.isEmpty()) {
                for (Entry<String, String> entry : entryList) {
                    jandroidedis.hdel(bigHashKey, entry.getKey());
                }
            }
            cursor = scan开发者_MongoDBResult.getStringCursor();
        } while (!"0".equals(cursor));
        
        //删除 bigkey
        jedis.del(bigHashKey);
    }
    

    3、bigkey会造成哪些问题?

    1. 内存不均,集群迁移困难;
    2. 超时删除,阻塞线程;
    3. 网络流量阻塞;

    4、如何发现bigkey?

    (1)通过redis-cli --bigkeys查找。

    关于Redis bigkeys命令会阻塞问题的解决

    (2)计算每个键值的字节数,通过memory usage key查找

    关于Redis bigkeys命令会阻塞问题的解决

    到此这篇关于关于Redis bigkeys命令会阻塞问题的解决的文章就介绍到这了,更多相关Redis bigkeys命令阻塞内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新数据库

    数据库排行榜