要模糊查询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在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个完好无损的桶上凿开了一个洞。