redis 和 memcached 有什么区别?redis的线程模型是什么?为什么单线程比多线程memcached效率要高得多(为什么redis单线程还可以支撑高并发)?
回答:
redis和memcached区别
1、redis支持服务器端的数据操作:redis比memcached数据结构多和支持更丰富的数据操作
2、redis可以支持复杂的结构和操作
3、redis官方致辞集群模式
redis的线程模型(用redis还是要了解一点线程模型)
1、文件事件处理器
redis基于reactor(java的Nio就是一个reactor模型)模式开发了网络事件处理器,这个处理器叫做文件事件处理器,
file event handler。这个文件事件处理器,是单线程的,redis所以才叫做单线程的模型,
采用IO多路复用机制同时监听多个socket,根据socket上的时间来选择对应的事件处理器来处理这个事件
如果被监听的socket准备好执行accept、read、write、close
等操作的时候,相应的文件事件就会产生,这个时候文件处理器就会调用之前关联的时间处理器来处理事件
文件处理器的结构包含4个部分:多个socket,IO多路复用程
序,文件事件分派器、事件处理器(命令请求处理器、命令回复处理器、连接应答处理器,等等)。
相应的多个socket会产生多个不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序虽然会监听多个socket,但
是会把socket放到一个队列中,这样依次选择对应的事件处理器来处理
2、文件事件
当socket变得可读时(比如客户端对redis执行write操作,或者close操作),或者有新的可以应答的socket出现,socket就会产生一个AE_READABLE事件。
当socket便可可以读写的时候(客户端对redis执行read操作),socket会产生一个AE_WRITABLE事件
IO多路复用程序可以监听AE_REABLE 和 AE_WRITABLE两种事假,要是一个socket同时产生了两种事件,那么文件分派器优先处理前者(读)其次才是写
3、文件事件处理器
如果是客户端要连接redis,那么会为socket关联连接应答处理器
如果客户端要写数据到redis,为socket关联命令请求处理器
如果要读数据,为socket关联命令回复处理器
4、客户端与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单线程模型效率这么高
1、纯内存操作
2、核心是基于非阻塞的IO多路复用机制
3、不用频繁切换上下文
redis都有哪些数据类型?分别在哪些场景下使用合适?
(如果问这个问题应该觉得你对技术没有深入研究过,看看你会不会用)
1、string 最基本的类型,普通set和get,做简单的kv缓存
2、hash: 类似map的一种结构,前提是简单对象(没有嵌套其他对象)给缓存在redis里,然后每次读写缓存的时候,就可以操作hash里的某个字段
比如 key=abc value={"id":12,"age":12}, 可以直接操作age 修改为 20.
3、list 有序列表,这个可以来个骚操作
比如,做分页,类似那种下拉分页的东西
简单的消息队列,粉丝列表
4、set 无序集合,自动去重
基于set玩交集、并集和差集,比如交集,两个人粉丝列表整一个交集,看看共同好友
5、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代码实现?
1、设置过期时间,set key的时候都可以给一个过期时间,假如过期后redis怎么对这个key删除的? 答:定期删除+惰性删除
定期删除就是每个100ms随机抽取一些设置了过期时间的key,如果过期了就删除,但是会有一个问题,因为随机查找所以有些会漏。
但是你再获取这key的时候,却找不到这个时候就是惰性删除,在你获取key的时候,redis会检查一下,这个key如果过期了,就删除不给你返回什么东西。
但是这样还有一个问题就是,假如删除没有删除,然后你系统也没有查key,就这样一直留在内存里,redis内存就崩了。 这个时候就会走内存淘汰机制
2、内存淘汰 如果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优先移除