redis的一些常见面试题

1 、在项目中缓存是如何使用的?

 

 

2、为啥在项目里要用缓存呢?

用缓存,主要用途,高性能和高并发

高性能

场景举例:假如有这么一个操作,用户发起请求,操作数据库,查出结果,耗时600ms,然后这个结果,在一段时间内都不会改变,或者说改变了也不用立即向用户反馈,那么这个时候就可以用缓存了,把查出来的结果直接放到缓存里,下次再有人来请求,就直接在缓存里通过key value键值对给到用户,性能提高!

简单的说就是,把一个复杂耗时的操作的结果,后面不怎么需要改变的结果,但是有很多的读取操作,就可以使用缓存,后面读取的时候直接从缓存中读就可以了。

高并发:因为数据库不支持高并发,像mysql最高也就支持到2000,然后我们把数据放到缓存中去,轻轻松松的十几万的并发,是mysql的几十倍。

 

3 、使用缓存有什么缺点?

1)缓存与数据库双写不一致

2)缓存雪崩

3)缓存穿透

4)缓存并发竞争

 

4、redis和memcached有什么区别?

redis:线程模型是单线程NIO异步的工作模型。

  1. 数据结构 :redis拥有更多的数据结构和更多的数据结构,很多复杂的操作跟高效

2.集群redis官方就是支持redis cluster集群模式,而menacahe不支持,需要依赖客户端。

 

 

5、redis都有哪些数据类型?

String

用来抢购,用来限制库存数量做一个计数器,就可以用string类型

分布式锁

string类型的setnx的作用是“当key不存在时,设值并返回1,当key已经存在时,不设值并返回0”,“判断key是否存在”和“设值”两个操作是原子性地执行的,因此可以用string类型作为分布式锁,返回1表示获得锁,返回0表示没有获得锁。

list

是一个有序列表,

可以用来做简单的点对点消息队列,和可以用来做粉丝列表,评论列表,

还可以通过lrange命令,就是从某个元素开始读取多少个元素,可以基于list实现分页查询,这个很棒的一个功能,基于redis实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走

set

无序集合,自动去重

可以用于去重,将需要去重的数据放进去。自动去重,

如果需要对一些数据进行进行快速的全局去重,可以使用jvm的hashSet进行去重,但是如果是在多台机器上的话就需要用redis的set进行去重,

也可以基于set对数据进行交集,并集,差集操作。比如,微博里的粉丝可以做一个交集,就可以查看两个人的共同好友

黑名单/白名单

sorted set

可以去重,有序。

可以用来做排行榜,比如商品的销量排行 收藏排行等

hash

这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在redis里,然后每次读写缓存的时候,可以就操作hash里的某个字段。 比如项目中可以哟来做购物车用户id为key 商品id为field,商品数量为value;

结构:

key=150

value={

“id”: 150,

“name”: “zhangsan”,

“age”: 20

}

 

6、redis的过期策略都有哪些?

设置过期时间定期删除和惰性删除最后走内存淘汰机制

7、内存淘汰机制都有哪些?

1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用

2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最常用的)

3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的key给干掉啊

4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(这个一般不太合适)

5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key

6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除

8、手写一下LRU代码实现?

 

public class LRUCache<K, V> extends LinkedHashMap<K, V> {
   
private final int CACHE_SIZE;

   // 这里就是传递进来最多能缓存多少数据
   public LRUCache(int cacheSize) {
       super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); // 这块就是设置一个hashmap的初始大小,同时最后一个true指的是让linkedhashmap按照访问顺序来进行排序,最近访问的放在头,最老访问的就在尾
       CACHE_SIZE = cacheSize;
  }

   @Override
   protected boolean removeEldestEntry(Map.Entry eldest) {
       return size() > CACHE_SIZE; // 这个意思就是说当map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据
  }

}

 

9、如何保证redis的高并发以及高可用?

redis单机的瓶颈 能够承受的QPS大概就是在1万到几万

使用redis replication 主从实现读写分离支撑10万+的高并发,将架构做成主从架构,一主多从,主负责写,将数据同步到从节点上,从节点负责读,所有的读取请求都走从节点,这个架构支持水平扩容,只需要再在增加从节点就OK

 

10、redis replication的核心机制

(1)redis采用异步方式复制数据到slave节点,不过redis 2.8开始,slave node会周期性地确认自己每次复制的数据量 (2)一个master node是可以配置多个slave node的 (3)slave node也可以连接其他的slave node (4)slave node做复制的时候,是不会block master node的正常工作的 (5)slave node在做复制的时候,也不会block对自己的查询操作,它会用旧的数据集来提供服务; 但是复制完成的时候,需要删除旧数据集,加载新数据集,这个时候就会暂停对外服务了 (6)slave node主要用来进行横向扩容,做读写分离,扩容的slave node可以提高读的吞吐量slave,高可用性,有很大的关系

11、master持久化对于主从架构的安全保障的意义

如果采用了主从架构,那么建议必须开启master node的持久化!

不建议用slave node作为master node的数据热备,因为那样的话,如果你关掉master的持久化,可能在master宕机重启的时候数据是空的,然后可能一经过复制,salve node数据也丢了

master -> RDB和AOF都关闭了 -> 全部在内存中

master宕机,重启,是没有本地数据可以恢复的,然后就会直接认为自己的数据是空的

master就会将空的数据集同步到slave上去,所有slave的数据全部清空

100%的数据丢失

master节点,必须要使用持久化机制

第二个,master的各种备份方案,要不要做,万一说本地的所有文件丢失了; 从备份中挑选一份rdb去恢复master; 这样才能确保master启动的时候,是有数据的

即使采用了后续讲解的高可用机制,slave node可以自动接管master node,但是也可能sentinal还没有检测到master failure,master node就自动重启了,还是可能导致上面的所有slave node数据清空故障

 

 

 

12、主从架构的核心原理

当启动一个slave node的时候,它会发送一个PSYNC命令给master node

如果这时slave node重新连接master node,那么master node仅仅会复制给slave部分缺少的数据; 否则如果是slave node第一次连接master node,那么会触发一次full resynchronization

开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slave,slave会先写入本地磁盘,然后再从本地磁盘加载到内存中。然后master会将内存中缓存的写命令发送给slave,slave也会同步这些数据。

slave node如果跟master node有网络故障,断开了连接,会自动重连。master如果发现有多个slave node都来重新连接,仅仅会启动一个rdb save操作,用一份数据服务所有slave node。

2、主从复制的断点续传

从redis 2.8开始,就支持主从复制的断点续传,如果主从复制过程中,网络连接断掉了,那么可以接着上次复制的地方,继续复制下去,而不是从头开始复制一份

master node会在内存中常见一个backlog,master和slave都会保存一个replica offset还有一个master id,offset就是保存在backlog中的。如果master和slave网络连接断掉了,slave会让master从上次的replica offset开始继续复制

但是如果没有找到对应的offset,那么就会执行一次resynchronization

3、无磁盘化复制

master在内存中直接创建rdb,然后发送给slave,不会在自己本地落地磁盘了

repl-diskless-sync repl-diskless-sync-delay,等待一定时长再开始复制,因为要等更多slave重新连接过来

4、过期key处理

slave不会过期key,只会等待master过期key。如果master过期了一个key,或者通过LRU淘汰了一个key,那么会模拟一条del命令发送给slave。

 

 

13、redis主从架构下如何实现高可用?

主备切换。或者叫故障转移,需要我们在主从架构中加入entinal node(哨兵)负责监控master node 和slave node的进程是否正常工作。 一旦检查到master挂掉之后,就会发送消息通知到管理员,同时将其中一个salve升级为master 提供写和同步的功能,因为salve上的数据和master上的数据是一样的。最后通知client客户端新的master地址

哨兵作为维护主从架构的高可用,其自身是一个分布式的,并且至少需要3个哨兵实例来保证自己的健壮性

其次:哨兵+redis主从架构,是不会保证数据不丢失,只能保证redis集群的高可用性。

猜你喜欢

转载自www.cnblogs.com/kt-ting/p/12375575.html