1、面试题java
redis和memcached有什么区别?redis的线程模型是什么?为何单线程的redis比多线程的memcached效率要高得多(为何redis是单线程的可是还能够支撑高并发)?react
2、面试官内心分析面试
这个是问redis的时候,最基本的问题吧,redis最基本的一个内部原理和特色,就是redis其实是个单线程工做模型,你要是这个都不知道,那后面玩儿redis的时候,出了问题岂不是什么都不知道?redis
还有可能面试官会问问你redis和memcached的区别,不过说实话,最近这两年,我做为面试官都不太喜欢这么问了,memched是早些年各大互联网公司经常使用的缓存方案,可是如今近几年基本都是redis,没什么公司用memcached了缓存
3、额外的友情提示服务器
同窗,你要是如今还不知道redis和memcached是啥?那你赶忙百度一下redis入门和memcahced入门,简单启动一下,而后试一下几个简单操做,先感觉一下。接着回来继续听课,我以为1小时之内你就搞定了。网络
另一个友情提示,要听明白redis的线程模型,你须要了解socket网络相关的基本知识,若是不懂。。。那我以为你java没学好吧。初学者都该学习java的socket网络通讯相关知识的。。。数据结构
4、面试题剖析多线程
(1)redis和memcached有啥区别并发
这个事儿吧,你能够比较出N多个区别来,可是我仍是采起redis做者给出的几个比较吧
1)Redis支持服务器端的数据操做:Redis相比Memcached来讲,拥有更多的数据结构和并支持更丰富的数据操做,一般在Memcached里,你须要将数据拿到客户端来进行相似的修改再set回去。这大大增长了网络IO的次数和数据体积。在Redis中,这些复杂的操做一般和通常的GET/SET同样高效。因此,若是须要缓存可以支持更复杂的结构和操做,那么Redis会是不错的选择。
2)内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高,而若是Redis采用hash结构来作key-value存储,因为其组合式的压缩,其内存利用率会高于Memcached。
3)性能对比:因为Redis只使用单核,而Memcached可使用多核,因此平均每个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,可是比起Memcached,仍是稍有逊色。
4)集群模式:memcached没有原生的集群模式,须要依靠客户端来实现往集群中分片写入数据;可是redis目前是原生支持cluster模式的,redis官方就是支持redis cluster集群模式的,比memcached来讲要更好
(2)redis的线程模型
1)文件事件处理器
redis基于reactor模式开发了网络事件处理器,这个处理器叫作文件事件处理器,file event handler。这个文件事件处理器,是单线程的,redis才叫作单线程的模型,采用IO多路复用机制同时监听多个socket,根据socket上的事件来选择对应的事件处理器来处理这个事件。
若是被监听的socket准备好执行accept、read、write、close等操做的时候,跟操做对应的文件事件就会产生,这个时候文件事件处理器就会调用以前关联好的事件处理器来处理这个事件。
文件事件处理器是单线程模式运行的,可是经过IO多路复用机制监听多个socket,能够实现高性能的网络通讯模型,又能够跟内部其余单线程的模块进行对接,保证了redis内部的线程模型的简单性。
文件事件处理器的结构包含4个部分:多个socket,IO多路复用程序,文件事件分派器,事件处理器(命令请求处理器、命令回复处理器、链接应答处理器,等等)。
多个socket可能并发的产生不一样的操做,每一个操做对应不一样的文件事件,可是IO多路复用程序会监听多个socket,可是会将socket放入一个队列中排队,每次从队列中取出一个socket给事件分派器,事件分派器把socket给对应的事件处理器。
而后一个socket的事件处理完以后,IO多路复用程序才会将队列中的下一个socket给事件分派器。文件事件分派器会根据每一个socket当前产生的事件,来选择对应的事件处理器来处理。
2)文件事件
当socket变得可读时(好比客户端对redis执行write操做,或者close操做),或者有新的能够应答的sccket出现时(客户端对redis执行connect操做),socket就会产生一个AE_READABLE事件。
当socket变得可写的时候(客户端对redis执行read操做),socket会产生一个AE_WRITABLE事件。
IO多路复用程序能够同时监听AE_REABLE和AE_WRITABLE两种事件,要是一个socket同时产生了AE_READABLE和AE_WRITABLE两种事件,那么文件事件分派器优先处理AE_REABLE事件,而后才是AE_WRITABLE事件。
3)文件事件处理器
若是是客户端要链接redis,那么会为socket关联链接应答处理器
若是是客户端要写数据到redis,那么会为socket关联命令请求处理器
若是是客户端要从redis读数据,那么会为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事件和命令回复处理器的关联关系。
(3)为啥redis单线程模型也能效率这么高?
1)纯内存操做
2)核心是基于非阻塞的IO多路复用机制
3)单线程反而避免了多线程的频繁上下文切换问题(百度)