Redis 与其他 key - value 缓存产品有以下三个特点:
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行利用。Redis不仅仅支持大略的key-value类型的数据,同时还供应list,set,zset,hash等数据构造的存储。Redis支持数据的备份,即master-slave模式的数据备份。Memcache时一个内存工具缓存系统,用于加速动态web运用程序,减轻数据库负载。它可以应对任意多个连接,利用非壅塞的网络I/O。

事情机制:
在内存中开辟一块空间,然后建立一个hash表,memcached自管理这些hash表。
一、性能
由于Redis只利用单核,而Memcached可以利用多核,以是均匀每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据时,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
二、内存利用效率利用大略的key-value存储的话,Memcached的内存利用率更高,而如果Redis采取hash构造来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。
三、Redis支持做事器真个数据操作Redis比较Memcached来说,拥有更多的数据构造并支持更丰富的数据操作,常日在Memcached里,你须要将数据拿到客户端来进行类似的修正再set回去,序列化再反序列化,这大大增加了网络IO的次数和数据体积。在Redis中,这些繁芜的操作常日和一样平常的GET/SET一样高效。以是,如果须要缓存能够支持更繁芜的构造和操作,那么Redis会是不错的选择。
与Memcached仅支持大略的key-value构造的数据记录不同,Redis支持的数据类型要丰富得多。最为常用的数据类型紧张由五种:String、Hash、List、Set和Sorted Set。Redis内部利用一个redisObject工具来表示所有的key和value。
四、数据存储及持久化Redis和Memcached都是将数据存放在内存中,都是内存数据库。不过memcached还可用于缓存其他东西,例如图片、视频等等。memcached把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小;redis有部分存在硬盘上,这样能担保数据的持久性,支持数据的持久化(RDB、AOF),而Memcached不支持持久化。同时Redis并不是所有的数据都一贯存储在内存中的,当物理内存用完时,Redis可以将一些良久没用到的value交流到磁盘,但memcached超过内存比例会抹掉前面的数据。
memcached挂掉后,数据不可规复;redis数据丢失后可以通过aof规复,Redis支持数据的备份,即master-slave主从模式的数据备份。
总的来说:
memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。
redis支持持久化操作。redis供应了两种不同的持久化方法来讲数据存储到硬盘里面,一种是快照(snapshotting),它可以将存在于某一时候的所有数据都写入硬盘里面。另一种方法叫只追加文件(append-only file, AOF),它会在实行写命令时,将被实行的写命令复制到硬盘里面。
五、网络IO模型memcached是多线程,非壅塞IO复用的网络模型,分为监听主线程和worker子线程,监听线程监听网络连接,接管要求后,将连接描述字pipe通报给worker线程,进行读写IO,网络层利用libevent封装的事宜库,多线程模型可以发挥多核浸染,但是引入了cache coherency和锁的问题,比如:memcached最常用的stats命令,实际memcached所有操作都要对这个全局变量加锁,进行技能等事情,带来了性能损耗。
redis利用单线程的IO复用模型,自己封装了一个大略的AeEvent事宜处理框架,紧张实现了epoll, kqueue和select,对付单存只有IO操作来说,单线程可以将速率上风发挥到最大,但是redis也供应了一些大略的打算功能,比如排序、聚合等,对付这些操作,单线程模型施加会严重影响整体吞吐量,CPU打算过程中,全体IO调度都是被壅塞的。
六、内存管理机制对付像Redis和Memcached这种基于内存的数据库系统来说,内存管理的效率高低是影响系统性能的关键成分。传统C措辞中的malloc/free函数是最常用的分配和开释内存的方法,但是这种方法存在着很大的毛病:首先,对付开拓职员来说不匹配的malloc和free随意马虎造成内存透露;其次频繁调用会造成大量内存碎片无法回收重新利用,降落内存利用率;末了作为系统调用,其系统开销远远大于一样平常函数调用。以是,为了提高内存的管理效率,高效的内存管理方案都不会直策应用malloc/free调用。Redis和Memcached均利用了自身设计的内存管理机制,但是实现方法存在很大的差异,下面将会对两者的内存管理机制分别进行先容。
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的大小就为112个字节,依此类推。
当Memcached吸收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最得当的Slab Class,然后通过查询Memcached保存着的该Slab Class内空闲Chunk的列表就可以找到一个可用于存储数据的Chunk。当一条数据库过期或者丢弃时,该记录所占用的Chunk就可以回收,重新添加到空闲列表中。从以长进程我们可以看出Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺陷便是会导致空间摧残浪费蹂躏。由于每个Chunk都分配了特定长度的内存空间,以是变长数据无法充分利用这些空间。如图 所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就摧残浪费蹂躏掉了。
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开释内存。
Redis通过定义一个数组来记录所有的内存分配情形,这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当出路序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为zmalloc_allocations。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。zmalloc.c中有一个静态变量used_memory用来记录当前分配的内存总大小。以是,总的来看,Redis采取的是包装的mallc/free,相较于Memcached的内存管理方法来说,要大略很多。
在Redis中,并不是所有的数据都一贯存储在内存中的。这是和Memcached比较一个最大的差异。当物理内存用完时,Redis可以将一些良久没用到的value交流到磁盘。Redis只会缓存所有的key的信息,如果Redis创造内存的利用量超过了某一个阀值,将触发swap的操作,Redis根据“swappability = agelog(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文件中加载相应数据的读取要求进行并发操作,减少壅塞的韶光。
Memcached利用预分配的内存池的办法,利用slab和大小不同的chunk来管理内存,Item根据大小选择得当的chunk存储,内存池的办法可以省去申请/开释内存的开销,并且能减小内存碎片产生,但这种办法也会带来一定程度上的空间摧残浪费蹂躏,并且在内存仍旧有很大空间时,新的数据也可能会被剔除。
Redis利用现场申请内存的办法来存储数据,并且很少利用free-list等办法来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命令参数,会把带过期韶光的数据单独存放在一起,并把它们称为临时数据,非临时数据是永久不会被剔除的,即便物理内存不足,导致swap也不会剔除任何非临时数据(但会考试测验剔除部分临时数据),这点上Redis更适宜作为存储而不是cache。
总的来看,Redis采取的是包装的mallc/free,相较于Memcached的内存管理方法来说,要大略很多。
七、集群、分布式存储Memcached是全内存的数据缓冲系统,Redis虽然支持数据的持久化,但是全内存毕竟才是其高性能的实质。作为基于内存的存储系统来说,机器物理内存的大小便是系统能够容纳的最大数据量。如果须要处理的数据量超过了单台机器的物理内存大小,就须要构建分布式集群来扩展存储能力。
Memcached本身并不支持分布式,因此只能在客户端通过像同等性哈希这样的分布式算法来实现Memcached的分布式存储,当客户端向Memcached集群发送数据之前,首先会通过内置的分布式算法打算出该条数据的目标节点,然后数据会直接发送到该节点上存储。但客户端查询数据时,同样要打算出查询数据所在的节点,然后直接向该节点发送查询要求以获取数据。
相较于Memcached只能采取客户端实现分布式存储,Redis更倾向于在做事器端构建分布式存储,但没有采取同等性哈希。最新版本的Redis已经支持了分布式存储功能。Redis Cluster是一个实现了分布式且许可单点故障的Redis高等版本,它没有中央节点,具有线性可伸缩的功能。为了担保单点故障下的数据可用性,Redis Cluster引入了Master节点和Slave节点。在Redis Cluster中,每个Master节点都会有对应的两个用于冗余的Slave节点。这样在全体集群中,任意两个节点的宕机都不会导致数据的不可用。当Master节点退出后,集群会自动选择一个Slave节点成为新的Master节点。
八、运用处景redis:数据量较小的更性能操作和运算上
memcache:用于在动态系统中减少数据库负载,提升性能;做缓存,提高性能(适宜读多写少,对付数据量比较大,可以采取sharding)
MongoDB:紧张办理海量数据的访问效率问题
关于redis和memcache方面还有啥差异,大家可以不才方留言,一起磋商哦~
后面会分享更多DBA和devops方面的内容,感兴趣的朋友可以关注下!
!