redis知识点

要模糊查询redis中的key

方法一:使用scan命令(推荐)

scan cursor [MATCH pattern] [COUNT count]
  • cursor - 游标。
  • pattern - 匹配的模式。
  • count - 指定从数据集里返回多少元素,默认值为 10 。

keys pattern里面有3个通配符 分别是 *,?,[]

* : 通配多个任意字符

? : 通配单个字符

[] : 通配数组内的某个字符

redis 127.0.0.1:6379> scan 0   # 使用 0 作为游标,开始新的迭代
1) "17"                        # 第一次迭代时返回的游标
2)  1) "key:12"
    2) "key:8"
    3) "key:4"
    4) "key:14"
    5) "key:16"
    6) "key:17"
    7) "key:15"
    8) "key:10"
    9) "key:3"
   10) "key:7"
   11) "key:1"
redis 127.0.0.1:6379> scan 17  # 使用的是第一次迭代时返回的游标 17 开始新的迭代
1) "0"
2) 1) "key:5"
   2) "key:18"
   3) "key:0"
   4) "key:2"
   5) "key:19"
   6) "key:13"
   7) "key:6"
   8) "key:9"
   9) "key:11"
java代码
do {
            ScanParams scanParams = new ScanParams();        //*表示匹配任意数量的任意字符
            scanParams.match("xxxx*");
            scanParams.count(10);
 
            ScanResult<String> sr = jedis.scan(cursor, scanParams);
            List<String> resultList = sr.getResult();
 
            for (String result : resultList) {
                System.out.println("key: " + result);            //对key的操作,或者先放到一个集合里面,然后再进行后续操作
            }
 
            cursor = sr.getStringCursor();
            System.out.println("cursor: " + cursor);
} while (!cursor.equals("0"));

方法二:keys 指令 (只适合在测试环境中使用,不适合在生产环境中使用,原因是redis是单线程运行的,当redis中的数据量很大时,由于此操作会遍历所有数据,并将结果一次性全部返回,执行时间会比较长,从而导致后续操作等待,直接影响系统的正常运行)

@Autowired
private RedisTemplate redisTemplate;
public void getKey() {
        long start = System.currentTimeMillis();
        redisTemplate.keys("cart*");
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        RedisConnection connection = RedisConnectionUtils.getConnection(redisTemplate.getConnectionFactory());
        Cursor<byte[]> result = connection.scan(new ScanOptions.ScanOptionsBuilder().count(10).match("cart*").build());
        long start1 = System.currentTimeMillis();
        //cursor有id和position这两个属性,id则对应 scan cursor 的cursor的值,poisition则是当前遍历到第几个
        while (result.hasNext()) {//这里可以改用for循环来获取指定数量的key
            String key=new String(result.next());
            //对key的操作,或者先放到一个集合里面,然后再进行后续操作
        }
        long end1 = System.currentTimeMillis();
        System.out.println(end1 - start1);
}

redis两种持久化方式的基本特点

RDB默认五分钟一次生成快照,且fork出一个子进程去做持久化操作;AOF一秒一次去通过一个后台线程fsync操作。

redis持久化两种方式的优缺点

(一)RDB的优点:
1.RDB对redis的性能影响非常小,因为在同步数据的时候他只是fork了一个子进程去做持久化;
2.数据恢复的速度比AOF快。

(二)RDB的缺点:
数据完整性不足

(一)AOF的优点:
1.以追加的方式写数据,减少磁盘寻址开销,写入性能高,文件不易破损;
2.适合做灾难性数据误删除的紧急恢复

(二)AOF的缺点:
一样的数据,AOF文件比RDB要大

redis两种持久化方式如何选择?

都要,在出问题时第一时间用RDB恢复,然后AOF做数据补全,冷备热备一起用。

redis线程模型

redis线程模型基于文件事件处理器,它是单线程的,所以 Redis 才叫做单线程的模型,它采用IO多路复用机制来同时监听多个Socket,根据Socket上的事件类型来选择对应的事件处理器来处理这个事件。

文件事件处理器的结构包含4个部分:多个Socket、IO多路复用程序、文件事件分派器、事件处理器(命令请求处理器、命令回复处理器、连接应答处理器等)。

redis五种数据类型的使用场景

在这里插入图片描述

什么是缓存雪崩?

同一时间缓存大面积失效,那一瞬间Redis跟没有一样,大数量(每秒6000个请求)级别的请求直接打到数据库几乎是灾难性的,你想想如果打挂的是一个用户服务的库,那其他依赖他的库所有的接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏,你怎么重启用户都会把你打挂,等你能重启的时候,用户早就睡觉去了,并且对你的产品失去了信心,什么垃圾产品。

怎么处理缓存雪崩?

处理缓存雪崩简单,在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会在同一时间大面积失效。

setRedis(Key,value,time + Math.random() * 10000);

如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题。或者设置热点数据永远不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就完事了,不要设置过期时间),电商首页的数据也可以用这个操作,保险。

什么是缓存穿透和击穿,他们跟雪崩有什么区别?

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,我们数据库的 id 都是1开始自增上去的,如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。

缓存击穿,这个跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值