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 比多线程的 Memcached 效率要高得多 (为什么 Redis 是单线程的但是还可以支撑高并发)?
1) 纯内存操作
2) 核心是基于非阻塞的 IO 多路复用机制
3) 单线程反而避免了多线程的频繁上下文切换问题 (百度)
来源: http://www.bubuko.com/infodetail-3112554.html