redis的学习

Redis 是一个开源的(BSD 许可)、内存中的数据结构存储系统,常用于数据库、缓存和消息队列等场景。

基础知识

**主要特点**:

1. 数据存储在内存中:这使得 Redis 具有极高的读写性能,能够快速响应数据请求。

2. 多种数据结构支持:包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。 - 字符串:可用于存储简单的键值对。 - 哈希:适合存储对象的属性。 - 列表:可作为队列、栈等使用。 - 集合:用于存储不重复的元素。 - 有序集合:每个元素都有一个分数,可用于排序和排名。

3. 丰富的操作命令:提供了各种针对不同数据结构的操作命令,方便进行数据的增删改查。

4. 持久化机制:支持两种持久化方式,即 RDB(快照)和 AOF(只追加文件),以防止数据丢失。

5. 高可用:可以通过主从复制和哨兵机制实现高可用性,保证服务的稳定性。

6. 分布式:通过 Redis Cluster 实现分布式存储,扩展存储容量和性能。

**应用场景**:

1. 缓存:加速数据读取,减轻数据库压力。

2. 会话存储:存储用户会话信息。

3. 排行榜:利用有序集合实现各种排行榜。

4. 消息队列:使用列表等结构实现简单的消息队列。

5. 分布式锁:保证在分布式环境下的并发操作的正确性。

**性能优化**:

1. 合理选择数据结构:根据业务需求选择最合适的数据结构,以提高存储和操作效率。

2. 控制数据大小:避免存储过大的数据,防止内存占用过高。

3. 优化键的设计:简洁且有意义的键名有助于提高性能。

Redis相关面试题

什么是缓存穿透 ? 怎么解决 ?

缓存穿透是指查询一个一定 不存在 的数据,如果从存储层查不到数据则不写
入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致
DB 挂掉。这种情况大概率是遭到了攻击。
解决方案的话,我们通常都会用布隆过滤器来解决它

介绍一下布隆过滤器吗?

布隆过滤器主要是用于检索一个元素是否在一个集合中。我们当时使用的是
redisson 实现的布隆过滤器。
它的底层主要是先去初始化一个比较大数组,里面存放的二进制 0 1 。在一
开始都是 0 ,当一个 key 来了之后经过 3 hash 计算,模于数组长度找到数据
的下标然后把数组中原来的 0 改为 1 ,这样的话,三个数组的位置就能标明一
key 的存在。查找的过程也是一样的。
当然是有缺点的,布隆过滤器有可能会产生一定的误判,我们一般可以设置
这个误判率,大概不会超过 5% ,其实这个误判是必然存在的,要不就得增
加数组的长度,其实已经算是很划分了, 5% 以内的误判率一般的项目也能
接受,不至于高并发下压倒数据库。

什么是缓存击穿 ? 怎么解决 ?

缓存击穿的意思是对于设置了过期时间的 key ,缓存在某个时间点过期的时
候,恰好这时间点对这个 Key 有大量的并发请求过来,这些请求发现缓存过
期一般都会从后端 DB 加载数据并回设到缓存,这个时候大并发的请求可能
会瞬间把 DB 压垮。
解决方案有两种方式:
第一可以使用互斥锁:当缓存失效时,不立即去 load db ,先使用如 Redis
setnx 去设置一个互斥锁,当操作成功返回时再进行 load db 的操作并回设缓
存,否则重试 get 缓存的方法
第二种方案可以设置当前 key 逻辑过期,大概是思路如下:
:在设置 key 的时候,设置一个过期时间字段一块存入缓存中,不给当前
key 设置过期时间
:当查询的时候,从 redis 取出数据后判断时间是否过期
:如果过期则开通另外一个线程进行数据同步,当前线程正常返回数据,
这个数据不是最新
当然两种方案各有利弊:
如果选择数据的强一致性,建议使用分布式锁的方案,性能上可能没那么
高,锁需要等,也有可能产生死锁的问题
如果选择 key 的逻辑删除,则优先考虑的高可用性,性能比较高,但是数据
同步这块做不到强一致。

什么是缓存雪崩 ? 怎么解决 ?

缓存雪崩意思是设置缓存时采用了相同的过期时间,导致缓存在某一时刻同
时失效,请求全部转发到 DB DB 瞬时压力过重雪崩。与缓存击穿的区别:
雪崩是很多 key ,击穿是某一个 key 缓存。
解决方案主要是可以将缓存失效时间分散开,比如可以在原有的失效时间基
础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的重
复率就会降低,就很难引发集体失效的事件。

redis做为缓存,mysql的数据如何与redis进行同步呢?(双写一致

性)

就说我最近做的这个项目,里面有 xxxx 根据自己的简历上 写)的功能,
需要让数据库与 redis 高度保持一致,因为要求时效性比较高,
我们当时采用的读写锁保证的强一致性。
我们采用的是 redisson 实现的读写锁,在读的时候添加共享锁,可以保证读
读不互斥,读写互斥。当我们更新数据的时候,添加排他锁,它是读写,读
读都互斥,这样就能保证在写数据的同时是不会让其他线程读数据的,避免
了脏数据。这里面需要注意的是读方法和写方法上需要使用同一把锁才行。

那这个排他锁是如何保证读写、读读互斥的呢?

其实排他锁底层使用也是 setnx ,保证了同时只能有一个线程操作
锁住的方法

听说过延时双删吗?为什么不用它呢?

延迟双删,如果是写操作,我们先把缓存中的数据删除,然后更新
数据库,最后再延时删除缓存中的数据,其中这个延时多久不太好确定,在
延时的过程中可能会出现脏数据,并不能保证强一致性,所以没有采用它。
当时设置的 allkeys-lru 策略。把最近最常访问的
数据留在缓存中。

Redis分布式锁如何实现 ?

redis 中提供了一个命令 setnx(SET if not exists)
由于 redis 的单线程的,用了命令之后,只能有一个客户端对某一个 key 设置
值,在没有过期或删除 key 的时候是其他客户端是不能设置这个 key

如何控制Redis实现分布式锁有效时长呢?

redis setnx 指令不好控制这个问题,我们当时采用的
redis 的一个框架 redisson 实现的。 redisson 中需要手动加锁,并且可以控制锁的失效时间和等待时间,当锁
住的一个业务还没有执行完成的时候,在 redisson 中引入了一个看门狗机
制,就是说每隔一段时间就检查当前业务是否还持有锁,如果持有就增加加
锁的持有时间,当业务执行完成之后需要使用释放锁就可以了
还有一个好处就是,在高并发下,一个业务有可能会执行很快,先客户 1
有锁的时候,客户 2 来了以后并不会马上拒绝,它会自旋不断尝试获取锁,
如果客户 1 释放之后,客户 2 就可以马上持有锁,性能也得到了提升。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值