redis缓存 面试一则

redis 和 memcached 有什么区别?redis的线程模型是什么?为何单线程比多线程memcached效率要高得多(为何redis单线程还能够支撑高并发)?

回答:
redis和memcached区别java

一、redis支持服务器端的数据操做:redis比memcached数据结构多和支持更丰富的数据操做
    二、redis能够支持复杂的结构和操做
    三、redis官方致辞集群模式
复制代码

redis的线程模型(用redis仍是要了解一点线程模型)react

一、文件事件处理器
      redis基于reactor(java的Nio就是一个reactor模型)模式开发了网络事件处理器,这个处理器叫作文件事件处理器,
      file event handler。这个文件事件处理器,是单线程的,redis因此才叫作单线程的模型,
      采用IO多路复用机制同时监听多个socket,根据socket上的时间来选择对应的事件处理器来处理这个事件
      
      若是被监听的socket准备好执行accept、read、write、close
      等操做的时候,相应的文件事件就会产生,这个时候文件处理器就会调用以前关联的时间处理器来处理事件
      
      文件处理器的结构包含4个部分:多个socket,IO多路复用程
      序,文件事件分派器、事件处理器(命令请求处理器、命令回复处理器、链接应答处理器,等等)。
      
      相应的多个socket会产生多个不一样的操做,每一个操做对应不一样的文件事件,可是IO多路复用程序虽然会监听多个socket,但
      是会把socket放到一个队列中,这样依次选择对应的事件处理器来处理
    
    二、文件事件
    
    当socket变得可读时(好比客户端对redis执行write操做,或者close操做),或者有新的能够应答的socket出现,socket就会产生一个AE_READABLE事件。
    
    当socket即可能够读写的时候(客户端对redis执行read操做),socket会产生一个AE_WRITABLE事件
    
    IO多路复用程序能够监听AE_REABLE 和 AE_WRITABLE两种事假,要是一个socket同时产生了两种事件,那么文件分派器优先处理前者(读)其次才是写
    
    三、文件事件处理器
    
    若是是客户端要链接redis,那么会为socket关联链接应答处理器
    
    若是客户端要写数据到redis,为socket关联命令请求处理器
    
    若是要读数据,为socket关联命令回复处理器
    
    四、客户端与redis通讯的一次流程
    
    在redis启动初始化的时候,redis会将链接应答处理器何AE_READABLE事件关联起来,
    接着若是一个客户端跟redis发起链接此时会产生一个AE_READABLE事件,而后由链接应答处理器跟客户端创建链接,建立客户端对应的socket,同时将这个socket的AE_READABLE事件跟命令请求处理器关联起来
    
    当客户端向redis发起请求的时候(无论读仍是写),首先就会在socket产生一个AE_READABLE事件,而后由对应的命令请求处
    理器来处理。这个命令请求处理器就会从socket中读取相关数据,而后进行执行和处理
    
    接着redis这边准备好了给客户端的相应数据后,就会将socket的AE_WRITABLE事件跟命令回复处理器关联起来
    当客户端这边准备好读取相应数据时,就会在socket上产生一个AE_WRITABLE事件,
    会由对应的命令回复处理器来处理,就是讲准备好的相应数据写入socket,供客户端来读取
    
    命令回复处理器写完以后,就会删除这个socket的AE_WRITABLE事件和命令回复处理器的关联关系
复制代码

为何redis单线程模型效率这么高redis

一、纯内存操做
    二、核心是基于非阻塞的IO多路复用机制
    三、不用频繁切换上下文
复制代码

redis都有哪些数据类型?分别在哪些场景下使用合适?

(若是问这个问题应该以为你对技术没有深刻研究过,看看你会不会用)缓存

一、string 最基本的类型,普通set和get,作简单的kv缓存
    二、hash: 相似map的一种结构,前提是简单对象(没有嵌套其余对象)给缓存在redis里,而后每次读写缓存的时候,就能够操做hash里的某个字段
    
    好比 key=abc value={"id":12,"age":12}, 能够直接操做age 修改成 20.
    
    三、list 有序列表,这个能够来个骚操做
    好比,作分页,相似那种下拉分页的东西
    简单的消息队列,粉丝列表
    
    四、set 无序集合,自动去重
    基于set玩交集、并集和差集,好比交集,两我的粉丝列表整一个交集,看看共同好友
    
    五、sortedset
    能够排序的去重,作排行榜
    将每一个用户以及其对应的什么分数写入进去,zadd board score username,接着zrevrange board 0 99,就能够获取排名前100的用户;zrank board username,能够看到用户在排行榜里的排名
    
    zadd board 85 zhangsan
    zadd board 72 wangwu
    zadd board 96 lisi
    zadd board 62 zhaoliu
    
    96 lisi
    85 zhangsan
    72 wangwu
    62 zhaoliu

    zrevrange board 0 3
    
    获取排名前3的用户
    
    96 lisi
    85 zhangsan
    72 wangwu
复制代码

redis过时策略有哪些?内存淘汰机制有哪些?手写一个LRU代码实现?

一、设置过时时间,set key的时候均可以给一个过时时间,假如过时后redis怎么对这个key删除的? 答:按期删除+惰性删除服务器

按期删除就是每一个100ms随机抽取一些设置了过时时间的key,若是过时了就删除,可是会有一个问题,由于随机查找因此有些会漏。网络

可是你再获取这key的时候,却找不到这个时候就是惰性删除,在你获取key的时候,redis会检查一下,这个key若是过时了,就删除不给你返回什么东西。数据结构

可是这样还有一个问题就是,假如删除没有删除,而后你系统也没有查key,就这样一直留在内存里,redis内存就崩了。 这个时候就会走内存淘汰机制多线程

二、内存淘汰 若是redis的内存占用过多的时候,这个时候就会进行内存淘汰并发

redis 10个key,如今已经满了,redis须要删除掉5个key
    
    1个key,最近1分钟被查询了100次
    1个key,最近10分钟被查询了50次
    1个key,最近1个小时倍查询了1次
    
    1)noeviction:当内存不足以容纳新写入数据时,新写入操做会报错,这个通常没人用吧,实在是太恶心了
    2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key(这个是最经常使用的)
    3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key,这个通常没人用吧,为啥要随机,确定是把最近最少使用的key给干掉啊
    4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,移除最近最少使用的key(这个通常不太合适)
    5)volatile-random:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,随机移除某个key
    6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过时时间的键空间中,有更早过时时间的key优先移除复制代码
相关文章
相关标签/搜索