Redis | Memcached | |
网络IO模型 | 单线程的IO复用的网络模型 | 多线程的非阻塞IO复用的网络模型 |
数据支持类型 |
key-value数据类型 还支持list,set,zset,hash等数据结构的存储 |
key-value形式存储和访问数据 查询的时间复杂度降低到O(1) |
内存管理机制 |
基于zmalloc.h和zmalloc.c两个文件对mallc/free包装来实现管理内存 使用现场申请内存的方式 |
基于Slab Allocation机制管理内存 使用预分配的内存池的方式 |
数据存储及持久化 |
支持存储 除以in-memory的形式存储 另外两种:快照(snapshotting),只追加文件(append-only file, AOF) |
不支持存储只以in-memory的形式存储 |
数据一致性 | 提供了事务的功能,保证命令的原子性,中间不会被任何操作打断 |
提供了cas命令,保证多个并发访问操作同一份数据的一致性 |
集群管理 | 服务器端构建分布式存储 |
只能采用客户端实现分布式存储 |
性能 |
单核 数据量<100k 高数据量>100k 低 |
多核 数据量<100k 低 数据量>100k 高 |
内存使用效率 |
采用key-value 存储结构 利用率低 采用hash结构来做key-value存储(组合式的压缩方式) 利用率高 |
采用key-value 存储结构 利用率高 |
Redis和Memcached这种基于内存的 数据库 系统来说,内存管理的效率高低是影响系统性能的关键因素。
Redis和Memcached最大存储量是根据机器 内存大小 而定。
Redis 是一种键值数据库,处于关系数据库和键值数据库之间。
Redis采用的是包装的mallc/free方式来实现内存管理
Slab Allocation机制的原理:它首先申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk就是用来存储key-value数据的最小单位。每个Slab Class的大小,可以在Memcached启动的时候通过制定Growth Factor来控制。假定图中Growth Factor的取值为1.25,如果第一组Chunk的大小为88个字节,第二组Chunk的大小就为112个字节,依此类推。
Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除。
Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache。
redis提供的两种不同的持久化方法来存储数据到硬盘里面:
①快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里面。
②只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令复制到硬盘里面。
备注:malloc/free是C++/C语言的标准库函数