1、在项目中redis的使用场景有哪些?
- 缓存数据
- 消息队列
- 计数器(比如统计点击率、点赞率,秒杀因为Redis具有原子性,可以避免并发问题)
- 电商网站信息
- 热点数据(比如新闻网站实时热点、微博热搜等,需要频繁刷新的)
2、redis的持久化策略都有哪些?
持久化策略分别是:RDB和AOF
- RDB:当redis中的写操作达到指定的次数同时距离上一次持久化达到指定的时间就会将redis内存中的数据生成数据快照保存到RDB文件中
- AOF:redis默认的aof是未开启的,可以通过redis的配置文件中的‘APPendonly yes’进行开启,AOF存储的是指令,而且会对指令进行整理。AOF是对数据进行的是增量更新,而RDB是生成数据快照
3、redis支持的数据类型有哪些?
- String(字符串): string 是 redis 最基本的类型,一个 key 对应一个 value.
- hash(哈希):Redis hash 是一个键值(key=>value)对集合。 Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。 使用场景:存储、读取、修改用户属性
- List(列表):Redis List是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
- Set(集合):Redis Set是string类型的无序集合。
- zset(sorted set:有序集合):Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
使用场景:
1.带有权重的元素,比如一个游戏的用户得分排行榜
2.比较复杂的数据结构,一般用到的场景不算太多
4、如何保证redis的高可用?
- redis持久化,同时开启rdb和aof。以此保证数据的安全性,还是会存在数据丢失的风险的
- redis主从配置,可以通过配置哨兵以实现主备配置,保证可用性
- redis支持集群,通过集群配置可以保证redis的高并发
5、如何解决redis集群的脑裂问题?
脑裂发生原因:如果此时master服务器所在区域网络通信出现异常,导致和两台slave机器无法正常通信,但是和客户端的连接是正常的。那么sentinel就会从两台slave机器中选举其中一个作为新的master来处理客户端请求。
脑裂最直接的影响:就是客户端不知道应该往哪个主节点写入数据,结果就是不同的客户端会往不同的主节点上写入数据。严重的话,脑裂会进一步导致数据丢失。也就是说,等到哨兵让原主库和新主库做全量同步后,原主库在切换期间保存的数据就丢失了。
如何解决脑裂问题:
通过Redis 中配置项min-slaves-to-write(最小从服务器数) 和 min-slaves-max-lag(从连接的最大延迟时间)解决这个问题。
min-slaves-to-write 是指主库最少得有 N 个健康的从库存活才能执行写命令。
这个配置虽然不能保证 N 个从库都一定能接收到主库的写操作,但是能避免当没有足够健康的从库时,主库无法正常写入,以此来避免数据的丢失 ,如果设置为 0 则表示关闭该功能。
min-slaves-max-lag :是指从库和主库进行数据复制时的 ACK 消息延迟的最大时间;
可以确保从库在指定的时间内,如果 ACK 时间没在规定时间内,则拒绝写入。
这两个配置项组合后的要求是,主库连接的从库中至少有 N 个从库,和主库进行数据复制时的 ACK 消息延迟不能超过 T 秒,否则,主库就不会再接收客户端的请求了。这样处理之后,即使原主库是假故障,它在假故障期间也无法响应哨兵发出的心跳测试,也不能和从库进行同步,自然也就无法和从库进行 ACK 确认了。
6、redis中的数据可以设置过期时间,当数据过期之后有些key并没有及时的清除,请问如何处理?
关于这个问题的解决之前,我们必须要了解的是,为什么会产生redis中设置了过期时间但是数据并没有及时清除这个问题是如何产生的,然后再根据具体的产生原因分别进行选择性处理。原因大致有以下几点:
- 对于过期数据数据的处理redis提供了两种方式,分别是惰性删除和定期删除。
惰性删除:也称被动删除,但数据过期之后,并不会马上删除。而是等到you请求访问的时候,对数据进行检查,如果过期,再删除。
优点:不需要单独的额外的扫描线程,减少了CPU资源的消耗
缺点:大量的过期数据滞留在内存中,只有主动触发才会检查删除,否则会一直占用内存资源
定期删除:每隔一段时间,默认是100ms,Redis会随机挑选一定数量的key,检查是否过期,并将过期的数据删除 为什么会产生过期数据继续能拉取到呢?这就要从客户端主库写入数据说起,当往主库中写入数据后,设置过期时间,数据会以异步的方式同步给从库,如果此时读取主库,数据已经过期,主库的惰性删除会发挥作用,主动触触发操作,客户端不会拿到已经过期的数据,由于Redis采取的一主多从,如果此时数据从‘从库’拿取数据,就会拿到过期数据,原因则是由于redis版本的原因,在Redis4.2之前的版本,读从库并不会判断数据是否过期,所以有可能返回过期数据
解决措施 升级Redis版本,至少要Redis3.2以上的版本,读从库,如果数据已经过期,则会过滤并返回空值;但是值得注意的是:升级Redis之后,同步过来的数据,虽然已经过期,但是本着谁生产谁维护,从库不会主动删除同步过来的数据,需要依赖于主节点同步过来的key删除命令 另个原因则是和Redis对过期时间的设置有关系,我们一般采取的是EXPIRE和PEXPIRE,表示从执行命令那个时刻开始,往后延长了ttl时间。严重依赖于开始时间从什么时候算起的。(EXPIRE:单位是秒 ; PEXPIRE:单位是毫秒)。当客户端将数据写入主库,主库再向从库中同步数据,这期间的时间间隔会影响数据的过期的时间。
解决措施 可以采取Redis的另外两个命令,EXPIREAT和PEXPIREAT,相对简单,表示过期时间为一个具体的时间点。避免了对开始时间从什么时候算起的依赖
EXPIREAT:单位是秒
PEXPIREAT:单位是毫秒