阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Memcached 及 Redis 架构分析和比较

147次阅读
没有评论

共计 7359 个字符,预计需要花费 19 分钟才能阅读完成。

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

基本架构和思想

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

Memcached

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

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

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

Memcached 及 Redis 架构分析和比较

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

Memcached 及 Redis 架构分析和比较

Memcached 安装及启动脚本 http://www.linuxidc.com/Linux/2013-07/87641.htm

PHP 中使用 Memcached 的性能问题 http://www.linuxidc.com/Linux/2013-06/85883.htm

Ubuntu 下安装 Memcached 及命令解释 http://www.linuxidc.com/Linux/2013-06/85832.htm

Memcached 的安装和应用 http://www.linuxidc.com/Linux/2013-08/89165.htm

使用 Nginx+Memcached 的小图片存储方案 http://www.linuxidc.com/Linux/2013-11/92390.htm

Memcached 使用入门 http://www.linuxidc.com/Linux/2011-12/49516p2.htm

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

更多详情见请继续阅读下一页的精彩内容 :http://www.linuxidc.com/Linux/2014-10/107975p2.htm

性能

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

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 服务器实例相互之间是完全独立的,需要依靠客户端处理分区算法和可用服务器列表管理的工作。

Memcached 及 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 来处理的这样一些数据结构,应该还是很难高效的分区遍历的

Ubuntu 14.04 下 Redis 安装及简单测试 http://www.linuxidc.com/Linux/2014-05/101544.htm

Redis 集群明细文档 http://www.linuxidc.com/Linux/2013-09/90118.htm

Ubuntu 12.10 下安装 Redis(图文详解)+ Jedis 连接 Redis http://www.linuxidc.com/Linux/2013-06/85816.htm

Redis 系列 - 安装部署维护篇 http://www.linuxidc.com/Linux/2012-12/75627.htm

CentOS 6.3 安装 Redis http://www.linuxidc.com/Linux/2012-12/75314.htm

Redis 安装部署学习笔记 http://www.linuxidc.com/Linux/2014-07/104306.htm

Redis 配置文件 redis.conf 详解 http://www.linuxidc.com/Linux/2013-11/92524.htm

Redis 的详细介绍 :请点这里
Redis 的下载地址 :请点这里

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

基本架构和思想

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

Memcached

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

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

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

Memcached 及 Redis 架构分析和比较

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

Memcached 及 Redis 架构分析和比较

Memcached 安装及启动脚本 http://www.linuxidc.com/Linux/2013-07/87641.htm

PHP 中使用 Memcached 的性能问题 http://www.linuxidc.com/Linux/2013-06/85883.htm

Ubuntu 下安装 Memcached 及命令解释 http://www.linuxidc.com/Linux/2013-06/85832.htm

Memcached 的安装和应用 http://www.linuxidc.com/Linux/2013-08/89165.htm

使用 Nginx+Memcached 的小图片存储方案 http://www.linuxidc.com/Linux/2013-11/92390.htm

Memcached 使用入门 http://www.linuxidc.com/Linux/2011-12/49516p2.htm

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

更多详情见请继续阅读下一页的精彩内容 :http://www.linuxidc.com/Linux/2014-10/107975p2.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-20发表,共计7359字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中