Redis支持复杂的数据结构
Reids 相比Memcached又有更多的数据结构,能支持更丰富的数据操作,如果需要缓存能够支持复杂的结构和操作,Redis 会是不错的选择
Redis 原生支持集群模式
在Redis3.x版本中就可以支持cluster模式,而Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据
性能对比
由于Redis 只是用了单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 memcached性能更高。而在100k以上的数据中心,Memcached 性能要高于redis,虽然Redis最近也在存储大数据的性能上进行了优化,但比起Menmcached稍有逊色
Redis 的线程模型
Redis 内部使用文件事件处理器file event handler,这个文件事件处理器是单线程的,所以 Redis才叫做单线程模型。它是采用 IO 多路复用机制同时监听多个socket将产生事件的socker 压入到内存队列中,事件分派器根据socket 上的时间类型来选择对应的事件处理器进行处理。
文件事件处理的结构包含了4个部分:
- 多个socket
- IO多路复用程序
- 文件事件分派器
- 事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)
多个socket 可能会并发产生不同的操作,每个操作对应的文件事件,但是 IO 多路复用会监听多个 socket,会将产生事件的 socket 放入到队列中排队,事件分派器每次从队列中取出一个socket,根据 socket 的事件类型交给对应的事件处理器进行处理
通信是通过socket来完成的
首先,Redis服务端进程初始化的时候会将 server socket 的AE_READABLE 事件与连接应答器处理器关联
客户端 socket01 向 Redis 进程的 server socket 请求建立连接,此时 server socket 会产生一个 AE_READABLE
事件,IO 多路复用程序监听到 server socket 产生的事件后,将该 socket 压入队列中。文件事件分派器从队列中获取 socket,交给连接应答处理器。连接应答处理器会创建一个能与客户端通信的 socket01,并将该 socket01 的 AE_READABLE
事件与命令请求处理器关联。
假设此时客户端发送了一个 set key value
请求,此时 Redis 中的 socket01 会产生 AE_READABLE
事件,IO 多路复用程序将 socket01 压入队列,此时事件分派器从队列中获取到 socket01 产生的 AE_READABLE
事件,由于前面 socket01 的 AE_READABLE
事件已经与命令请求处理器关联,因此事件分派器将事件交给命令请求处理器来处理。命令请求处理器读取 socket01 的 key value
并在自己内存中完成 key value
的设置。操作完成后,它会将 socket01 的 AE_WRITABLE
事件与命令回复处理器关联。
如果此时客户端准备好接收返回结果了,那么 Redis 中的 socket01 会产生一个 AE_WRITABLE
事件,同样压入队列中,事件分派器找到相关联的命令回复处理器,由命令回复处理器对 socket01 输入本次操作的一个结果,比如 ok
,之后解除 socket01 的 AE_WRITABLE
事件与命令回复处理器的关联
为啥 Redis 单线程模型也能效率这么高?
- 存内存操作
- 核心是基于非堵塞的IO 多了复用机制
- C语言实现,一般来说C语言与操作系统距离更近,执行速度相对于快一些
- 单线程反而避免了多线程的频繁切换上下文的问题,预防多线程过多导致产生竞争问题

