Memcached和Redis简介

前言:react

        目前比较流行的缓存技术无疑是Memcached和Redis,两套缓存技术有着诸多的类似之处,但又具有大量的显著差别,做为新生的方案,Redis被视为首选,可是有些场景Memcached发挥的做用是不容忽视的。redis

类似点:算法

         1. Memcached和Redis都属于In-Memory、Key-Value数据存储方案,同属于NoSQL家族,都选择将所有数据存储在内存中。数组

         2. 都是成熟的开源项目,Memcached由Brad Fitzpatrick 2003年开发而成,Redis则由Salvatore Sanfilippo于2009建立。缓存

         3. 简单易用,只需几分钟就能够完成安装工做。服务器

不一样之处:数据结构

         1. Redis支持服务器端的数据操做: Redis相对Memcached拥有更多的数据结构,支持丰富的数据操做。多线程

         2. 内存使用率:Memcached简单的key-value存储,内存利用率更高,而若是Redis采用hash结构来作Key-value存储,因为组合式的压缩,内存利用率更高。并发

         3.性能对比:Redis单核,Memcached可使用多核,因此平均每个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,可是比起Memcached,还有些差距。app

结合以上特性下面从二者的事件模型,内存管理,数据类型、集群管理、持久化详细讲解一下

1、事件模型

      相同之处:都是用epol来作事件循环

      不一样之处:redis是单线程服务器(这里的单线程是指除了主线程之外其余线程没有event loop),redis事件模型只有一个event loop,是最简单的reactor的实现。redis事件模型中有一个亮点,redis里面的fd(详细请百度)就是服务器与客户端链接socket的fd,一般根据fd找到具体的客户端信息,一般的处理方式就是用红黑树将fd与客户端信息保存起来,经过fd查找,效率是lgn,不过redis比较特殊,redis客户端的数量上限能够设置,即同一时刻知道redis打开的fd的上限,且进程的fd在同一时刻是不会重复的,因此redis使用一个数据,将fd做为数组的下标,数组的元素就是客户端的信息,这样经过fd就能订位客户端信息,查找效率是O(1),省去了红黑树的实现。

       Memcached是多线程的,使用Master-Worker的方式,其中主线程负责接收链接,而后将链接分给各个worker线程,在各个worker线程中完成命令的接收,处理和返回结果。

2、内存管理

  1. Memcached使用预先分配,预先分配一大块内存,而后接下来就从内存池中分配,这样能够减小内存的分配次数,提升效率。Memcached的采用Slab Allocation,内存的结构决定了Value值的大小最大只能为1MB。

       Slab Allocation的原理:将分配的内存分割成各类尺寸的块(chunk),并把尺寸相同的块分红组,每一组被称为slab。Memcached的内存分配以Page为单位,Page默认值为1M,能够在启动时经过-I参数来指定。Slab是由多个Page组成的,Page按照指定大小切割成多个chunk。memcached在启动时经过-f选项能够指定 Growth Factor因子。该值控制slab之间的差别,chunk大小的差别。默认值为1.25。其结构图以下:

 

  优缺点:Slab Allocation能够有效的解决内存碎片的问题,可是也会形成内存的浪费

             1.每一个slab的chunk大小是固定的,当item的占用空间实际小于chunk大小时,会出现内存浪费

             2.每一个slab的大小是固定的(由于page是固定的),当slab不能被他所拥有的chunk整除时,会出现内存浪费

             3.按照Growth Factor因子生成指定大小的slab,而某slab id根本未被使用时,会出现内存浪费

   2. Redis使用动态分配,因为C语言没有自带的GC,因此Redis的实现中封装了C的malloc,calloc,realloc和free函数来对本身的内存进行管理,这些实现都在zmalloc.h和zmalloc.c中。在Redis中,并非全部的数据一直存储在内存中。当物理内存用完时,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文件中加载相应数据的读取请求进行并发操做,减小阻塞的时间。

3、数据类型

     Memcached仅支持简单的key-value结构的数据,Redis支持的数据类型要丰富得多。经常使用的由五种:String、Hash、List、Set和Sorted Set。Redis内部使用一个redisObject对象来表示全部的key和value。

四:集群管理

     Memcached自己并不支持分布式,只能在客户端经过一致性hash这样的分布式算法来实现Memcached的分布式存储。 Redis更偏向服务端构建分布式存储,Redis Cluster是一个实现了分布式且容许单点故障的Redis高级版本,去中心化,具备线性可伸缩的功能。节点与节点之间经过二进制协议进行通讯,节点与客户端之间经过ascii协议进行通讯。在数据的放置策略上,Redis Cluster将整个key的数值域分红4096个哈希槽,每一个节点上能够存储一个或多个哈希槽,也就是说当前Redis Cluster支持的最大节点数就是4096。Redis Cluster使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。

五:数据持久化

     Memcached不支持数据持久化。Redis支持两种数据持久化RDB快照和AOF日志。

     Redis Cluster引入了master-slave模式,每个master都对应两个slave节点。

 总体上说,二者的性能都很好,没必要为哪一个性能更高而纠结。不过,redis提供的持久化和数据同步机制,这些都是memcached没有的,因此若是你想要持久化,就只能用redis了。另外,memcached足以应付简单的键值存储,不过你要是想用更高级的数据结构,好比hash,list,set,zset之类的,redis提供了这些类型,用着更方便。 

相关文章
相关标签/搜索