Redis与Memcached | Cult Minds

Redis与Memcached

Redis与Memcached的比较相当多,首先我们比较一下他们的介绍。

Memcached:一款完全开源、高性能的、分布式的内存系统;

Redis:一个开源的、Key-Value型、基于内存运行并支持持久化的NoSQL数据库;

可以发现,Memcached更侧重于高性能内存/缓存系统,而Redis则支持持久化,主打数据库功能,兼可作缓存系统(性能也很高)。

下面有一个更加详细的比较表

对比参数RedisMemcached
类型1. 支持内存
2. 非关系型数据库
1. 支持内存
2. key-value形式
3. 缓存系统
数据存储类型String、List、Set、Hash、Sort Set文本型、二进制型
查询操作1. 批量操作
2. 支持事务
3. 每个类型CRUD不同
CRUD和少量其他命令
附加功能1. 发布/订阅模式
2. 主从分区
3. 序列化支持
4. 脚本支持
多线程服务支持
网络模型单进程IO复用模型多进程非阻塞IO模型
事件库AeEventLibEvent
持久化支持RDB、AOF不支持

网络模型

Memcached是多线程非阻塞IO复用的网络模型,它由负责监听的主线程和子线程worker组成。主线程监听网络连接,每当接受到网络请求,将连接描述字传递给worker线程进行读写IO操作。Memcached的网络层使用libevent封装的事件库。但多线程不可避免地会有缓存一致性和锁等问题,这里面带来了性能损耗。

Redis是单线程IO复用模型,自己封装了一个简单的AeEvent事件处理框架,主要实现了epoll, kqueue和select,对于单纯只有IO操作的业务场景来说,单线程可以将速度优势发挥到最大,但对于一些消耗CPU资源的计算性的操作例如redis提供的排序和聚合等,单线程模型施加会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞的。

我们可以粗略得出结论,在高并发场景的压力下,多线程非阻塞式IO的Memcached表现会更加优异。

内存管理机制

Memcached和Redis都是由C语言开发,他们都是自主实现内存模型。

Memcached的内存模式是Slab Allocation。它有以下几个特点:

  1. Memcached存储数据的最小单位是chunk,这种设计是为了避免内存碎片的问题。chunk的大小可以通过Factor来管理。
  2. Slab和Page用于承装不同尺寸的chunk。

  3. 不同尺寸chunk最终进入一个slab_class进行管理,便于访问。

数据访问流程,用户在slab_class找到合适尺寸的slab,再通过某种方式找到chunk,保证数据进入一个合适大小的chunk中存储,防止内存浪费。

Memcached内存模型

相对于Memecached,Redis的内存管理要相对简单。

Redis内存模型

Redis每一个数据块都是根据数据类型和大小来分配,每一块数据的元数据存入内存块头部。分配内存时,redis调用malloc后返回首地址指针real_ptr。redis将内存块的大小size存入头部,size本身所占据的内存大小是固定为sizeof(typeof(size))。根据这个可以推算存储的数据的内存指针ret_ptr。释放内存时,通过ret_ptr来推算real_ptr再调用free函数释放内存。

结论

Memcacehd预分配内存池,用不同大小的内存单元来管理内存,数据选择合适的内存单元来存储。这样节省了申请/释放内存的开销,减少了内存碎片产生,但依然会带来内存空间浪费。Memcached通过这种方式来最大化内存管理性能,是时间优先策略。

Redis按需申请内存,Redis会把带过期时间的数据单独存放在一起,这些数据是临时数据,临时数据会根据缓存过期策略来进行剔除。非临时数据则永远不会剔除。Redis更好地利用了内存空间,是空间优先策略。

数据一致性

Redis提供了事务,这种事务并非真正的事务实现。而且这种事务性操作容易造成线程阻塞。Memcached会返回操作的结果,不会影响其他数据。

集群

Memcached本身不支持集群,但它可以通过客户端来实现集群操作。它通过客户端上的程序库来封装了对集群服务器访问的接口,使得用户看起来似乎是在操作一个节点。客户端的程序通过hash算法来选择memcached节点,然后去访问对应的节点。

Redis支持集群。各个节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。

总结

  1. 如果业务更加侧重性能的高效性,对持久化要求不高,那么应该优先选择Memcached。

    具体到业务有服务器的实时配置、存储json字符串等等。

  2. 对持久化有高需求,追求多类型数据支持,选择Redis。

    具体到业务有排行榜类应用、社交关系存储、数据排重等等。

0%