共计 7359 个字符,预计需要花费 19 分钟才能阅读完成。
Memcached 和 Redis 作为两种 Inmemory 的 key-value 数据库,在设计和思想方面有着很多共通的地方,功能和应用方面在很多场合下 (作为分布式缓存服务器使用等) 也很相似,在这里把两者放在一起做一下对比的介绍
基本架构和思想
首先简单介绍一下两者的架构和设计思路
Memcached
Memcached 采用客户端 - 服务器的架构,客户端和服务器端的通讯使用自定义的协议标准,只要满足协议格式要求,客户端 Library 可以用任何语言实现。
从用户的角度来说,服务器维护了一个键 - 值关系的数据表,服务器之间相互独立,互相之间不共享数据也不做任何通讯操作。客户端需要知道所有的服务器,并自行负责管理数据在各个服务器间的分配。
在服务器端,内部的数据存储,使用基于 Slab 的内存管理方式,有利于减少内存碎片和频繁分配销毁内存所带来的开销。各个 Slab 按需动态分配一个 page 的内存(和 4Kpage 的概念不同,这里默认 page 为 1M),page 内部按照不同 slab class 的尺寸再划分为内存 chunk 供服务器存储 KV 键值对使用
Memcached 的基本应用模型如下图所示
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 服务器实例相互之间是完全独立的,需要依靠客户端处理分区算法和可用服务器列表管理的工作。
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 的基本应用模型如下图所示
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