0
点赞
收藏
分享

微信扫一扫

开发岗面试汇总

倪雅各 2022-05-01 阅读 68
面试

中间件:

Redis:

高性能k-v数据库,在内存运行,也可以持久化到磁盘,单线程单进程KV数据库。

支持的数据结构和底层实现:

类型用法实现
Stringset key value最大512M
Hash(k-v集合)hmset name key1 val1 key2 val2适合存储对象
List(有序列表,按插入顺序排序)lpush/rpush name value
SET(无序集合)sadd name value
zset(有序集合)zadd name score value每个元素都会关联一个分数,按分数排序

REDIS主从实现原理:

主节点负责写,从节点负责读。

从节点发现主节点信息,建立socket链接,主节点将所有数据发送给从节点,完成初次全量同步,如果master有写命令,进行命令传播,保持主从一致性。

slave断开重连会进行同步,判断master id是否跟自己记录的一样,如果不一样就进行完整同步,如果一样就判断主从偏移量是否一致,如果不一致就进行部分重新同步,如果一样就直接结束。

分块分表:

分区是分割数据到多个redis实例的处理过程,因此每个实例保存key的一个子集。

如果只使用一个redis实例时,其中保存了服务器中全部的缓存数据,这样会有很大风险,如果单台redis服务宕机了将会影响到整个服务。解决的方法就是采用分片/分区的技术,将原来一台服务器维护的整个缓存,现在换为由多台服务器共同维护内存空间。

Redis Cluster 使用分片机制,在内部分为16384各slot插槽,分布在所有的master节点上,每个master节点负责一部分slot,数据操作时通过crc16的hash函数来对key进行取模,将结果路由到预先分配过slot相应节点上。

redis怎么实现高并发:

1、Redis是基于内存的,内存的读写速度非常快;

2、Redis是单线程的,省去很多上下文切换线程的时间;

3、Redis使用多路复用,可以处理并发的连接,非阻塞IO内部实现epoll,采用epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化为事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间。

redis持久化机制:

redis一般把数据缓存在内存里,但是会周期性的把更新的数据写入磁盘

两种持久化策略:

RDB:快照形式,直接把内存dump,Redis需要做持久化时,会fork一个子进程,子进程将数据写到临时RDB表里,写完再替换,实现COW;适合冷备,每5分钟生成一次;

AOF:把对服务器修改的命令都放到文件里;每一个写命令都追加到aof文件里,redis重启时会直接根据AOF指定进行恢复,适合热备,1秒1次fsync。

redis缓存雪崩,缓存穿透,缓存击穿,如何解决雪崩问题:

缓存雪崩:redis宕机或者大量key失效,同时又有大量请求打进来,DB撑不住;

1、设置不同的过期时间,防止同时失效

2、搭建高可用redis集群

3、设置多级缓存

缓存击穿:一个key非常热点,扛大量请求,然后再某一个时间点过期,恰好这个时间点对这个key有大量请求过来,这些请求发现缓存过期时会从后台DB加载数据并回到缓存,把DB压垮。

解法:热点数据永不过期(物理不过期,逻辑不过期;当发现要过期了通过后台异步进程进行缓存重建)或者加上互斥锁。

缓存穿透:用户大量请求在缓存和DB中查不到,导致数据不存在也会大量查DB

解法:DB查不到也写在缓存里,或使用布隆过滤器(类似一个hashset,可以快速查找某个KEY是否在数据库存在)。

Redis过期策略:

1、定期删除:100ms随机抽一些设置了过期时间的删除

2、惰性删除:等查询了再看过期没,过期了就删除

Redis的淘汰策略:

设置过期时间:LRU:最近最少使用,TTL:淘汰剩余时间短的;Random:随机淘汰。

所有K-V:Random随机淘汰。

Redis分布式锁的实现:

假设有5个redis节点,这些节点之间既没有主从,也没有集群关系。客户端用相同的key和随机值在5个节点上请求锁,请求锁的超时时间应小于锁自动释放的时间。当在3个(超过半数)redis上请求到锁的时候,才算是真正获取到了锁。如果没有获取到锁,则把部分已锁的redis释放掉。

如何解决redis分布式锁过期时间到了业务没执行完问题:

思路一:任务执行的时候,开辟一个守护线程,在守护线程中每隔一段时间重新设置过期时间。

思路二:通过Redisson中的看门狗来实现,在Redisson实例被关闭前,不断延长锁的有效期,默认30秒。

Redis重新分配哈希值:

系统自动化当前各主节点中拿出一定数量的哈希槽,转义至新的主节点中,以达到哈希槽平衡。

Redis快的原因:

基于内存操作,数据结构简单,避免上下文切换和竞争关系,多路复用和非阻塞IO:使用多路复用来监听多个socket连接客户端。

高可用:

主从复制+哨兵模式(3个)

哨兵集群:集群监控:监控Master/Slave是否正常工作;消息通知:某个Redis故障,报警给管理员;master node挂了自动转移给slave;配置中心:通知client新的master。

通过Sentine哨兵来监控Redis主服务器的状态。当主挂掉时,在从节点中根据一定策略选出新主,并调整其他从slave到新主。

选主的的策略简单来说有三个:

1、slave的priority设置的越低,优先级越高;

2、同等情况下,slave复制的数据越多优先级越高;

3、相同的条件下runid越小越容易被选中。

在Redis集群中,sentinel也会进行多实例部署,sentinel之间通过Raft协议来保证自身的高可用。

举报

相关推荐

0 条评论