redis 和 memcached 有什么区别?redis 的线程模型是什么?为何 redis 单线程却能支撑高并发?面试
这个是问 redis 的时候,最基本的问题吧,redis 最基本的一个内部原理和特色,就是 redis 其实是个单线程工做模型,你要是这个都不知道,那后面玩儿 redis 的时候,出了问题岂不是什么都不知道?redis
还有可能面试官会问问你 redis 和 memcached 的区别,可是 memcached 是早些年各大互联网公司经常使用的缓存方案,可是如今近几年基本都是 redis,没什么公司用 memcached 了。缓存
redis 和 memcached 有啥区别?数据结构
redis 支持复杂的数据结构多线程
redis 相比 memcached 来讲,拥有更多的数据结构,能支持更丰富的数据操做。若是须要缓存可以支持更复杂的结构和操做, redis 会是不错的选择。并发
redis 原生支持集群模式socket
在 redis3.x 版本中,便能支持 cluster 模式,而 memcached 没有原生的集群模式,须要依靠客户端来实现往集群中分片写入数据。memcached
性能对比高并发
因为 redis 只使用单核,而 memcached 可使用多核,因此平均每个核上 redis 在存储小数据时比 memcached 性能更高。而在 100k 以上的数据中,memcached 性能要高于 redis,虽然 redis 最近也在存储大数据的性能上进行优化,可是比起 memcached,仍是稍有逊色。性能
redis 的线程模型
redis 内部使用文件事件处理器 file event handler,这个文件事件处理器是单线程的,因此 redis 才叫作单线程的模型。它采用 IO 多路复用机制同时监听多个 socket,根据 socket 上的事件来选择对应的事件处理器进行处理。
文件事件处理器的结构包含 4 个部分:
多个 socket 可能会并发产生不一样的操做,每一个操做对应不一样的文件事件,可是 IO 多路复用程序会监听多个 socket,会将 socket 产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理。
来看客户端与 redis 的一次通讯过程(图片若不清晰,请右击在新标签中打开图片):
客户端 socket01 向 redis 的 server socket 请求创建链接,此时 server socket 会产生一个 AE_READABLE 事件,IO 多路复用程序监听到 server socket 产生的事件后,将该事件压入队列中。文件事件分派器从队列中获取该事件,交给链接应答处理器。链接应答处理器会建立一个能与客户端通讯的 socket01,并将该 socket01 的 AE_READABLE 事件与命令请求处理器关联。
假设此时客户端发送了一个 set key value 请求,此时 redis 中的 socket01 会产生 AE_READABLE 事件,IO 多路复用程序将事件压入队列,此时事件分派器从队列中获取到该事件,因为前面 socket01 的 AE_READABLE 事件已经与命令请求处理器关联,所以事件分派器将事件交给命令请求处理器来处理。命令请求处理器读取 socket01 的 key value 并在本身内存中完成 key value 的设置。操做完成后,它会将 socket01 的 AE_WRITABLE 事件与命令回复处理器关联。
若是此时客户端准备好接收返回结果了,那么 redis 中的 socket01 会产生一个 AE_WRITABLE 事件,一样压入队列中,事件分派器找到相关联的命令回复处理器,由命令回复处理器对 socket01 输入本次操做的一个结果,好比 ok,以后解除 socket01 的 AE_WRITABLE 事件与命令回复处理器的关联。
这样便完成了一次通讯。
为啥 redis 单线程模型也能效率这么高?