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