干货技巧|关于Redis的16个使用技巧

1、什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?

回答:持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。Redis 提供了两种持久化方式:RDB(默认) 和AOF。RDB,是Redis DataBase缩写,功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数AOF,f是Append-only file缩写每当执行服务器(定时)任务或者函数时flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作aof写入保存:WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。存储结构:内容是redis通讯协议(RESP )格式的命令文本存储。比较:aof文件比rdb更新频率高,优先使用aof还原数据。aof比rdb更安全也更大rdb性能比aof好如果两个都配了优先加载AOF

2、Redis 单线程为什么还能这么快

命令执行基于内存操作,在内存操作时间是几十纳秒,命令执行是单线程,没有线程切换开销,基于IO多路复用机制提升Redis的I/O利用率高效数据结构

3、Redis到底是单线程还是多线程?

Redis6.0版本之前的单线程指的是 网络I/O和键值对读写是由一个线程完成的。Redis6.0引入的多线程指的是网络请求过程采用了多线程;而键值对读写命令仍然是单线程处理的,Redis依然是并发安全的。即数据操作模块是单线程的,其它持久化、集群数据同步等,是由额外线程执行的。

4、使用过Redis分布式锁么,它是怎么实现的?

先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!

5、什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?

缓存穿透

一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。

如何避免?

对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

缓存雪崩

当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。

如何避免?

在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。

做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期

不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

6、Redis的并发竞争问题如何解决?

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:

客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。

服务器角度,利用setnx实现锁。

对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。

7、Redis 支持哪几种数据类型?

String、List、Set、Sorted Set、hashes。

它还有三种特殊的数据结构类型

Geospatial

Hyperloglog

Bitmap

8、Redis 有哪几种数据淘汰策略?

noeviction:返回错误当内存限制达到,并且客户端尝试执行会让更多内存被使用的命令。allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。

volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。

allkeys-random: 回收随机的键使得新添加的数据有空间存放。

volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

9、Redis 集群为什么至少需要三个主节点

因为新主节点的选举现需要大于半数的集群主节点同意才能选举成功,只有两个的话,其中一个挂了,达不到选举新主节点条件的。

10、Redis集群为什么推荐奇数个节点

在挂掉相同机器的前提下,奇数和奇数+1的偶数,效果是一样的,但是却多浪费了一台机器

例如:3台机器挂两台,和4台机器挂两台同样都不可用。

11、请说一下缓存击穿问题

缓存击穿: 指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。

缓存击穿看着有点像,其实它两区别是,缓存雪奔是指数据库压力过大甚至down机,缓存击穿只是大量并发请求到了DB数据库层面。可以认为击穿是缓存雪奔的一个子集吧。有些文章认为它俩区别,是区别在于击穿针对某一热点key缓存,雪奔则是很多key。

解决方案就有两种:

1.使用互斥锁方案。缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redis的setnx)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。

2. “永不过期”,是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。

12、说说Redis的常用应用场景

缓存、排行榜、计数器应用、共享Session、分布式锁、社交网络、消息队列、位操作

13、什么是热Key问题,如何解决热key问题

什么是热Key呢?在Redis中,我们把访问频率高的key,称为热点key。如果某一热点key的请求到服务器主机时,由于请求量特别大,可能会导致主机资源不足,甚至宕机,从而影响正常的服务。而热点Key是怎么产生的呢?主要原因有两个:

用户消费的数据远大于生产的数据,如秒杀、热点新闻等读多写少的场景。

请求分片集中,超过单Redi服务器的性能,比如固定名称key,Hash落入同一台服务器,瞬间访问量极大,超过机器瓶颈,产生热点Key问题。

14、那么在日常开发中,如何识别到热点key呢?

凭经验判断哪些是热Key;

客户端统计上报;

服务代理层上报

15、如何解决热key问题?

Redis集群扩容:增加分片副本,均衡读流量;

将热key分散到不同的服务器中;

使用二级缓存,即JVM本地缓存,减少Redis的读请求。

16、如何实现一个排行榜功能?

比如,用户每天上传视频,获得点赞的排行榜可以这样设计:

1.用户Jay上传一个视频,获得6个赞,可以酱紫:

zadd user:ranking:2021-03-03 Jay 3

2.过了一段时间,再获得一个赞,可以这样:

zincrby user:ranking:2021-03-03 Jay 1

3.如果某个用户John作弊,需要删除该用户:

发表评论

相关文章