`

Memcached 及 Redis 架构分析和比较

 
阅读更多
Memcached和Redis作为两种Inmemory的key-value数据库,在设计和思想方面有着很多共通的地方,功能和应用方面在很多场合下(作为分布式缓存服务器使用等) 也很相似,在这里把两者放在一起做一下对比的介绍
 
基本架构和思想

首先简单介绍一下两者的架构和设计思路

Memcached

Memcached采用客户端-服务器的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端Library可以用任何语言实现。

从用户的角度来说,服务器维护了一个键-值关系的数据表,服务器之间相互独立,互相之间不共享数据也不做任何通讯操作。客户端需要知道所有的服务器,并自行负责管理数据在各个服务器间的分配。

在服务器端,内部的数据存储,使用基于Slab的内存管理方式,有利于减少内存碎片和频繁分配销毁内存所带来的开销。各个Slab按需动态分配一个page的内存(和4Kpage的概念不同,这里默认page为1M),page内部按照不同slab class的尺寸再划分为内存chunk供服务器存储KV键值对使用




Memcached的基本应用模型如下图所示





Redis

Redis的基本应用模式和上图memcached的基本相似,不难发现网上到处都是关于redis是否可以完全替代memcached使用的问题

Redis内部的数据结构最终也会落实到key-Value对应的形式,不过从暴露给用户的数据结构来看,要比memcached丰富,除了标准的通常意义的键值对,Redis还支持List,Set, Hashes,Sorted Set等数据结构

基本命令

Memcached的命令或者说通讯协议非常简单,Server所支持的命令基本就是对特定key的添加,删除,替换,原子更新,读取等,具体包括 Set, Get, Add, Replace, Append, Inc/Dec 等等

Memcached的通讯协议包括文本格式和二进制格式,用于满足简单网络客户端工具(如telnet)和对性能要求更高的客户端的不同需求

Redis的命令在KV(String类型)上提供与Memcached类似的基本操作,在其它数据结构上也支持基本类似的操作(当然还有这些数据结构所特有的操作,如Set的union,List的pop等)而支持更多的数据结构,在一定程度上也就意味着更加广泛的应用场合

除了多种数据结构的支持,Redis相比Memcached还提供了许多额外的特性,比如Subscribe/publish命令,以支持发布/订阅模式这样的通知机制等等,这些额外的特性同样有助于拓展它的应用场景

Redis的客户端-服务器通讯协议完全采用文本格式(在将来可能的服务器间通讯会采用二进制格式)


事务

redis通过Multi / Watch /Exec等命令可以支持事务的概念,原子性的执行一批命令。在2.6以后的版本中由于添加了对Script脚本的支持,而脚本固有的是以transaction事务的方式执行的,并且更加易于使用,所以不排除将来取消Multi等命令接口的可能性

Memcached的应用模式中,除了increment/decrement这样的原子操作命令,不存在对事务的支持

数据备份,有效性,持久化等

memcached不保证存储的数据的有效性,Slab内部基于LRU也会自动淘汰旧数据,客户端不能假设数据在服务器端的当前状态,这应该说是Memcached的Feature设定,用户不必太多关心或者自己管理数据的淘汰更新工作,当然是否适合你的应用,取决于具体的需求,它也可能成为你需要精确自行控制Cache生命周期的一个障碍

Memcached也不做数据的持久化工作,但是有许多基于memcached协议的项目实现了数据的持久化,例如memcacheDB使用BerkeleyDB进行数据存储,但本质上它已经不是一个Cache Server,而只是一个兼容Memcached的协议key-valueData Store了

Redis可以以master-slave的方式配置服务器,Slave节点对数据进行replica备份,Slave节点也可以充当Read only的节点分担数据读取的工作

Redis内建支持两种持久化方案,snapshot快照和AOF 增量Log方式。快照顾名思义就是隔一段时间将完整的数据Dump下来存储在文件中。AOF增量Log则是记录对数据的修改操作(实际上记录的就是每个对数据产生修改的命令本身),两种方案可以并存,也各有优缺点,具体参见 http://redis.io/topics/persistence

以上Redis的数据备份持久化方案等,如果不需要,为了提高性能,也完全可以Disable


性能

性能方面,两者都有一些自己考虑和实现

Memcached

memcached自身并不主动定期检查和标记哪些数据需要被淘汰,只有当再次读取相关数据时才检查时间戳,或者当内存不够使用需要主动淘汰数据时进一步检查LRU数据


Redis

Redis为了减少大量小数据CMD操作的网络通讯时间开销 RTT (Round Trip Time),支持pipeline和script技术

所谓的pipeline就是支持在一次通讯中,发送多个命令给服务器批量执行,带来的代价是服务器端需要更多的内存来缓存查询结果。
Redis内嵌了LUA解析器,可以执行lua 脚本,脚本可以通过eval等命令直接执行,也可以使用script load等方式上传到服务器端的script cache中重复使用

这两种方式都可以有效地减少网络通讯开销,增加数据吞吐率

对于KV的操作,Memcached和Redis都支持Multiple的Get和Set命令(Memcached的Multiple Set命令貌似只在二进制的协议中支持),这同样有利于性能的提升

实际性能方面,网上有很多测试比较,给出的结果各不相同,这无疑和各种测试的测试用例,测试环境,和测试时具体使用的客户端Library实现有关。但是总体看下来,比较靠谱的结论是在kv类操作上,两者的性能接近,Memcached的结构更加简单,理论上应该会略微快一些。


集群

memcached的服务器端互相完全独立,客户端通常通过对键值应用Hash算法决定数据的分区,为了减少服务器的增减对Hash结果的影响,导致大面积的缓存失效,多数客户端实现了一致性hash算法

Redis计划在服务器端内建对集群的支持,但是目前代码还处于alpha阶段(貌似已经Design了两三年了?)在此之前,同样可以认为每个Redis服务器实例相互之间是完全独立的,需要依靠客户端处理分区算法和可用服务器列表管理的工作。



Redis官方推荐的用于Sharding的客户端程序库是Twitter的开源项目 Twemproxy, Twemproxy同时支持Memcached和Redis的文本通讯协议。

需要注意的是,Redis的许多命令在集群环境下是不能正确运行的,例如set的交集,以及跨节点的事务操作等等,因为目前的Redis集群设计,根本目标也就是服务器之间互相汇报一下存活状态,以及对数据做荣誉备份平衡负载等而已,本质上对数据的跨节点操作并不提供任何额外支持,所以在数据服务的层面上来说,各个服务器依旧是完全独立的。

这些操作如果一定要实现,当然可以通过客户端代码来实现(效率有多高且不说),类似的问题memcached集群当然也会遇上,但是原本memcached就不支持复杂的操作和数据类型,许多运算逻辑原本就是由客户端代码或应用程序自己处理的。


MR类批处理应用

提供指定范围的遍历操作,是支持类似MapReduce这样的批处理应用逻辑的关键之一,但是要在基于hash方式存储的数据结构的基础上提供这样的支持并不容易(或者说要实现高效的范围或遍历操作并不容易)

Redis支持Scan操作用于遍历数据集,这一操作基于其内部数据结构及实现的限制,可以保证在Scan开始时的所有数据都能被获取到,但是不能保证不返回重复的数据,这需要由客户端来检查,或者客户端对此无所谓。Scan操作还支持Match条件用来过滤键值,虽然存在一定的局限性,例如match条件的比较是在获取数据之后再执行的,效率是一个问题,更明显的问题是不能保证每次scan的iterate过程都能返回同样数量的有效数据。

对于范围操作,Redis的Ordered Set支持在插入时指定数据的分数(Score)用于排序,而后支持在指定Score范围内的各种操作,虽然由于不支持基于字符串的或自定义的基准的Range操作,这样的范围操作应用起来有很大的局限性(或者说需要满足特定的应用模式),但是还是比没有好了

Memcached核心协议本身不支持任何范围类的操作,也没有对遍历操作的支持,甚至不存在官方合法的列举所有Key的操作,这当然很大程度上源于其设计思想和精简的架构

不过还是有一些兼容memcached协议的服务器实现了范围类操作,具体格式可以参考 https://code.google.com/p/memcached/wiki/RangeOps 所建议的标准

此外Redis的Hashes数据结构,在一定程度上可以满足获取特定子集数据的应用逻辑需求。

综上来说,如果要实现类似HBase支持的scan操作,不论是Redis还是memcached都无法做到,但是对于Redis来说,能否用于批处理类应用,不能一概而论,取决于具体的数据的格式逻辑和使用方式。通过适当的调整应用程序使用数据的方式,还是有可能在一定程度上实现对MR类批处理,或范围查询类应用逻辑的支持的。而对于键值分布在一个较大的连续空间,数量不确定,同时又无法很好的映射为数值进而使用ordered set来处理的这样一些数据结构,应该还是很难高效的分区遍历的
分享到:
评论

相关推荐

    memcached数据完整迁移到redis

    总结来说,从 memcached 迁移到 redis 是为了利用 redis 更强大的功能和更全面的数据管理能力。在迁移过程中,需要注意数据一致性、性能优化以及对现有应用程序的影响。通过合理的规划和测试,可以顺利完成这个转换...

    redis架构图

    这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是...

    分布式数据库面试专题系列:Memcached+Redis+MongoDB.zip

    面试中,可能会讨论Redis的数据持久化策略(RDB和AOF)、其内存管理及内存上限、以及如何设计高可用的Redis架构。 最后,我们讨论MongoDB,这是一个面向文档的NoSQL数据库,适合处理大量结构松散或半结构化的数据。...

    Redis架构下的MySQL数据库性能提升浅析.pdf

    2. memory cache: 将 Redis 看作是一个把数据存储在内存中的高速缓存,用来在应用和数据库之间提供缓冲,替代 memcached。 3. data structure server: 主要利用了复杂数据结构的高速操作,提供某些特殊业务场景的...

    cpp-美团twemproxy是memcached和redis协议的多进程快速和轻量级代理

    标题中的“cpp-美团twemproxy是memcached和redis协议的多进程快速和轻量级代理”揭示了这个项目的核心特性。首先,它是一个用C++编写的代理服务,这通常意味着它能够提供高效的性能和低级别的内存管理。其次,它是...

    数据平台缓存技术方案Memcached-Redis[汇编].pdf

    数据平台缓存技术方案Memcached-Redis 汇编 Memcached 是高性能的分布式内存缓存服务器,协议简单,通过缓存数据库的查询结果,减少数据库访问次数,提高动态 Web 应用的速度和扩展性。Memcached 支持多种语言,...

    分布式数据库面试专题系列:Memcached+Redis+MongoDB.rar

    本面试专题系列涵盖了三个主流的分布式数据存储系统:Memcached、Redis和MongoDB,它们各自有着独特的特性和应用场景。 首先,Memcached是一个高性能、分布式的内存对象缓存系统。它主要用于减轻数据库的负载,通过...

    数据平台前端缓存技术方案Memcached-Redis.v1.0[汇编].pdf

    数据平台前端缓存技术方案主要涉及两种常用的内存缓存服务:Memcached和Redis。本文将重点解析Memcached的相关知识。 1. **Memcached基础** - **M的概念**:Memcached是一个高性能的分布式内存对象缓存系统,它...

    memcachedredis性能测试.docx

    同时,由于其轻量级和简单的设计,使得它易于集成到现有的应用架构中。 7. **对比Redis** Redis是另一种常见的键值存储系统,相比Memcached,Redis提供了更丰富的数据结构(如列表、集合、有序集合等),支持持久...

    php mysql redis nginx memcached

    memcached和redis目录则可能包含各自服务的二进制文件和配置。 这个组合通常用于搭建一个高性能的Web环境,其中Nginx负责接收HTTP请求,通过FastCGI与PHP交互处理动态内容,MySQL存储数据,Redis和Memcached作为...

    memcache&redis构建缓存服务器.pdf

    在构建缓存服务器的过程中,Memcached和Redis是两个重要的高性能分布式内存缓存系统,它们的使用可以显著提升Web应用的响应速度和扩展性。以下是详细介绍这两个系统的知识内容。 首先,RDBMS(关系型数据库管理系统...

    twemproxy:一个快速、轻量级的 memcached 和 redis 代理-开源

    twemproxy(发音为“two-em-proxy”),又名 nutcracker 是 memcached 和 redis 协议的快速轻量级代理。 它的构建主要是为了减少与后端缓存服务器的连接数。 这与协议流水线和分片一起使您能够水平扩展分布式缓存...

    分布式论文.docx

    对于 Memcached 和 Redis 的应用,我们可以从以下几个方面进行比较分析: 1. 数据类型与操作:Memcached 支持简单的字符串、整数和布尔值类型的数据,支持 get、set、delete 等基本操作。Redis 支持多种数据类型,...

    使用memcached基于hibernate之上的高效数据库缓存架构方案(含源代码)

    本系统非常简洁易用,主程序BaseManager.java不到1000行代码,用“精悍”来形容绝对不为过,1000行代码却包含了数据库对象的缓存、列表和长度的缓存、按字段散列缓存、update延时更新、自动清除列表缓存等功能,用它...

    Java架构面试资料合集Spring面试专题及答案MySQL面试Redis面试资料.zip

    Java架构面试资料合集Spring面试专题及答案MySQL面试Redis面试资料: BAT面试常问80题 Dubbo服务框架面试专题及答案整理文档 java筑基(基础)面试专题系列(一):Tomcat+Mysql+设计模式 java筑基(基础)面试专题...

    互联网分布式缓存技术(redis、memcached、ssdb)

    互联网分布式缓存技术 课程主讲: 互联网应用高级架构师 白贺翔涉及技术: Redis、SSDB、Memcached课程描述: 介绍互联网分布式技术的重要性、背景、应用范围;目前互联网行业使用分布 式缓存进行设计的比例,...

    Redis从初始到集群到哨兵模式

    Memcached和Redis都是流行的缓存解决方案,但是它们的设计理念和实现方式不同。 1. 数据类型:Memcached只支持String类型,而Redis支持多种数据类型。 2. 持久化:Memcached不支持持久化,而Redis提供了RDB和AOF两...

    分布式缓存 Redis + Memcached 经典面试题!.pdf

    【分布式缓存Redis + Memcached】是现代互联网应用中常用的技术组合,用于高效地存储和检索数据,以提高系统的响应速度和并发处理能力。这里我们将深入探讨这两个分布式缓存系统的特点,以及它们在面试中经常遇到的...

Global site tag (gtag.js) - Google Analytics