Redis 和 Memcached 的区别

  • 时间:
  • 浏览:1

Redis使用现场申请内存的方式来存储数据,就让很少使用free-list等方式来优化内存分配,会在一定程度上指在内存碎片,Redis跟据存储命令参数,会把带过期时间的数据单独存倒入一块儿,并把它们称为临时数据,非临时数据是永远过多再被剔除的,即便物理内存严重不足,原因 swap只是会剔除任何非临时数据(就让尝试剔除累积临时数据),这点上Redis更适合作方式方式为存储而完整一定会cache。

数据支持类型

redis使用单任务管理器池的IO复用模型,当事人封装了另八个 多多简单的AeEvent事件正确处理框架,主要实现了epoll, kqueue和select,对于单存过多再 IO操作来说,单任务管理器池可不都可以 将传输传输速率优势发挥到最大,就让redis也提供了好多好多 简单的计算功能,比如排序、聚合等,对于那此操作,单任务管理器池模型施加会严重影响整体吞吐量,CPU计算过程中,整个IO调度完整一定会被阻塞的。

Redis通过定义另八个 多多数组来记录所有的内存分配情况表,这种 数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每另八个 多多元素代表当前任务管理器池池所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这种 数组为zmalloc_allocations。zmalloc_allocations[16]代表就让分配的长度为16bytes的内存块的个数。zmalloc.c涵盖另八个 多多静态变量used_memory用来记录当前分配的内存总大小。好多好多 ,总的来看,Redis采用的是包装的mallc/free,相较于Memcached的内存管理方式来说,要简单好多好多 。

Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选用合适 的chunk存储,内存池的方式可不都可以 省去申请/释放内存的开销,之可不都可以减小内存碎片产生,但这种 方式也会带来一定程度上的空间浪费,就让在内存仍然有很大空间时,新的数据都不 就让会被剔除,原因 可不都可以 参考Timyang的文章:http://timyang.net/data/Memcached-lru-evictions/

相较于Memcached过多再 采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。最新版本的Redis就让支持了分布式存储功能。Redis Cluster是另八个 多多实现了分布式且允许单点故障的Redis高级版本,它这麼中心节点,具有线性可伸缩的功能。Redis Cluster的分布式存储架构,节点与节点之间通过二进制协议进行通信,节点与客户端之间通过ascii协议进行通信。在数据的放置策略上,Redis Cluster将整个key的数值域分成4096个哈希槽,每个节点可不上都可以 存储另八个 多多或多个哈希槽,也只是说当前Redis Cluster支持的最大节点数只是4096。Redis Cluster使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。

网络IO模型

内存管理机制



正如开篇所说:redis与memcached相比,比仅支持简单的key-value数据类型,一块儿还提供list,set,zset,hash等数据型态的存储;完整可不都可以 翻阅《Redis内存使用优化与存储》

数据一致性现象

为了保证单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点一定会有对应的另八个 多多用于冗余的Slave节点。另另八个 多多在整个集群中,任意另八个 多多节点的宕机完整一定会会原因 数据的不可用。当Master节点退出后,集群会自动选用另八个 多多Slave节点成为新的Master节点。

当Memcached接收到客户端发送过来的数据时首先会根据收到数据的大小选用另八个 多多最合适 的Slab Class,就让通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可不都可以 找到另八个 多多可用于存储数据的Chunk。当一根绳子 绳子 数据库过期就让丢弃时,该记录所占用的Chunk就可不都可以 回收,重新去掉 到空闲列表中。从以上过程大家可不都可以 看出Memcached的内存管理制传输传输速率高,就让过多再造成内存碎片,就让它最大的缺点只是会原因 空间浪费。就让每个Chunk都分配了特定长度的内存空间,好多好多 变长数据无法充分利用那此空间。如图 所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了。

Memcached有四种 暂且支持分布式,就让过多再 在客户端通过像一致性哈希另另八个 多多的分布式算法来实现Memcached的分布式存储。下图给出了Memcached的分布式存储实现架构。当客户端向Memcached集群发送数据就让,首先会通过内置的分布式算法计算出该条数据的目标节点,就让数据会直接发送到该节点上存储。但客户端查询数据时,同样要计算出查询数据所在的节点,就让直接向该节点发送查询请求以获取数据。



Memcached提供了cas命令,可不都可以 保证多个并发访问操作同一份数据的一致性现象。 Redis这麼提供cas 命令,暂且能保证这点,不过Redis提供了事务的功能,可不都可以 保证一串 命令的原子性,上方过多再被任何操作打断。

在Redis中,并完整一定会所有的数据都总爱 存储在内存中的。这是和Memcached相比另八个 多多最大的区别。当物理内存用完时,Redis可不都可以 将好多好多 就让没用到的value交换到磁盘。Redis只会缓存所有的key的信息,就让Redis发现内存的使用量超过了某另八个 多多阀值,将触发swap的操作,Redis根据“swappability = age*log(size_in_memory)”计算出那此key对应的value可不都可以 swap到磁盘。就让再将那此key对应的value持久化到磁盘中,一块儿在内存中清除。这种 型态使得Redis可不都可以 保持超过其机器有四种 内存大小的数据。当然,机器有四种 的内存可不都可以 要过多再 保持所有的key,毕竟那此数据是过多再进行swap操作的。一块儿就让Redis将内存中的数据swap到磁盘中的就让,提供服务的主任务管理器池和进行swap操作的子任务管理器池会共享这累积内存,好多好多 就让更新可不都可以 swap的数据,Redis将阻塞这种 操作,直到子任务管理器池完成swap操作后才可不都可以 进行修改。当从Redis中读取数据的就让,就让读取的key对应的value不出内存中,这麼Redis就可不都可以 从swap文件中加载相应数据,就让再返回给请求方。 这里就指在另八个 多多I/O任务管理器池池的现象。在默认的情况表下,Redis会总爱 总爱 出现阻塞,即完成所有的swap文件加载后才会相应。这种 策略在客户端的数量较小,进行批量操作的就让比较合适 。就让就让将Redis应用在另八个 多多大型的网站应用任务管理器池池中,这显然是无法满足大并发的情况表的。好多好多 Redis运行大家设置I/O任务管理器池池的大小,对可不都可以 从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。

原文发布时间为:2018-08-15

本文来自云栖社区合作方式方式伙伴“Java架构师之路”,了解相关信息可不都可以 关注“Java架构师之路”。

Memcached默认使用Slab Allocation机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记录,以完整正确处理内存碎片现象。Slab Allocation机制只为存储内部人员数据而设计,也只是说所有的key-value数据都存储在Slab Allocation系统里,而Memcached的其它内存请求则通过普通的malloc/free来申请,就让那此请求的数量和频率决定了它们过多再对整个系统的性能造成影响Slab Allocation的原理相当简单。 如图所示,它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块Chunk,并把尺寸相同的块分成组Slab Class。其中,Chunk只是用来存储key-value数据的最小单位。每个Slab Class的大小,可不都可以 在Memcached启动的就让通过制定Growth Factor来控制。假定图中Growth Factor的取值为1.25,就让第一组Chunk的大小为88个字节,第二组Chunk的大小就为11另八个 多多字节,依此类推。

数据存储及持久化

对于像Redis和Memcached这种 基于内存的数据库系统来说,内存管理的传输传输速率高低是影响系统性能的关键因素。传统C语言中的malloc/free函数是最常用的分配和释放内存的方式,就让这种 方式指在着很大的严重不足:首先,对于开发人员来说不匹配的malloc和free容易造成内存泄露;其次频繁调用会造成多量内存碎片无法回收重新利用,降低内存利用率;最后作为系统调用,其系统开销远远大于一般函数调用。好多好多 ,为了提高内存的管理传输传输速率,高效的内存管理方案完整一定会会直接使用malloc/free调用。Redis和Memcached均使用了自身设计的内存管理机制,就让实现方式指在很大的差异,下面就让对两者的内存管理机制分别进行介绍。



memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。

redis支持持久化操作。redis提供了有四种 不同的持久化方式来讲数据存储到硬盘上方,有四种 是快照(snapshotting),它可不都可以 将指在于某一时刻的所有数据都写入硬盘上方。另有四种 方式叫只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令一键复制到硬盘上方。

Redis的内存管理主要通过源码中zmalloc.h和zmalloc.c另八个 多多文件来实现的。Redis为了方便内存的管理,在分配一块内存就让,会将这块内存的大小存入内存块的头部。如图所示,real_ptr是redis调用malloc后返回的指针。redis将内存块的大小size存入头部,size所指在的内存大小是已知的,为size_t类型的长度,就让返回ret_ptr。当可不都可以 释放内存的就让,ret_ptr被传给内存管理任务管理器池池。通过ret_ptr,任务管理器池池可不都可以 很容易的算出real_ptr的值,就让将real_ptr传给free释放内存。

memcached是任务管理器池池,非阻塞IO复用的网络模型,分为监听主任务管理器池和worker子任务管理器池,监听任务管理器池监听网络连接,接受请求后,将连接描述字pipe传递给worker任务管理器池,进行读写IO,网络层使用libevent封装的事件库,任务管理器池池模型可不都可以 发挥多核作用,就让引入了cache coherency和锁的现象,比如:memcached最常用的stats命令,实际memcached所有操作完整一定会对这种 全局变量加锁,进行技术等工作,带来了性能损耗。

集群管理不同

memcached使用key-value形式存储和访问数据,在内存中维护一张巨大的HashTable,使得对数据查询的时间繁杂度降低到O(1),保证了对数据的高性能访问。

本文作者:朱小厮

Memcached是全内存的数据缓冲系统,Redis我我觉得支持数据的持久化,就让全内存毕竟才是其高性能的本质。作为基于内存的存储系统来说,机器物理内存的大小只是系统过多再 容纳的最大数据量。之可不上都可以 正确处理的数据量超过了单台机器的物理内存大小,就可不都可以 构建分布式集群来扩展存储能力。

说到redis就会联想到memcached,反之亦然。了解过两者的同学有这麼个大致的印象:redis与memcached相比,比仅支持简单的key-value数据类型,一块儿还提供list,set,zset,hash等数据型态的存储;redis支持数据的备份,即master-slave模式的数据备份;redis支持数据的持久化,可不都可以 将内存中的数据保持在磁盘中,重启的之可不上都可以 再次加载进行使用等等,这似乎看起来redis比memcached更加牛逼好多好多 ,这麼事实上是完整一定会另另八个 多多的呢?指在即合理,大家来根据十2个 不同点来一一比较一下。