Redis vs Couchbase,究竟哪个更胜一筹?

Posted 架构头条

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis vs Couchbase,究竟哪个更胜一筹?相关的知识,希望对你有一定的参考价值。

Redis 和 Couchbase 都是基于内存的数据存储系统。在它们各自的官方描述中,Couchbase 是高性能,高伸缩性和高可用的分布式缓存系统;Redis 是一个开源的内存数据结构存储系统。
Redis 作者的比较  

Redis 的作者 Salvatore Sanfilippo 曾经对这两种基于内存的数据存储系统进行过比较:

   Redis 支持服务器端的数据操作

Redis 相比 Couchbase 来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在 Couchbase 里,你需要将数据拿到客户端来进行类似的修改再 set 回去(你需要先先通过 get 方法从服务器读取数据文档,并将文档反序列化为 json 对象,之后修改 json 对象对应属性,再通过 set 方法将数据写入服务器,序列化后进行存储)。这大大增加了网络 IO 的次数和传输中的数据体积。在 Redis 中,这些复杂的操作通常和一般的 GET/SET 一样高效。

   内存使用效率对比

使用简单的 key-value 存储的话,Couchbase 的内存利用率更高,而 Redis 采用 hash 结构来做 key-value 存储,由于其组合式的压缩,其内存利用率会高于 Couchbase。所以,如果需要缓存能够支持更复杂的数据结构和更频繁数据的部分更新操作,那么 Redis 会是不错的选择。(下文会在关于数据存储模型来证明这一点)

   性能对比

由于 Redis 只使用单核,而 Couchbase 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Couchbase 性能更高。而在 100k 以上的数据中,Couchbase 性能要高于 Redis,虽然 Redis 最近也在存储大数据的性能上进行优化,但是比起 Couchbase,还是稍有逊色。

其实不论是在大块数据还是大数据量的处理上,Couchbase 都要优于 Redis,很多平台都是采用 Couchbase 来管理数千万热数据。所以,如果缓存大多数情况下仅仅需要提供数据新增和查询操作,那 Couchbase 基于文档类型的存储结构能够始终如一地为提供亚毫秒的查询体验,对于预定义的数据类型你还可以通过创建索引进一步优化性能,这种情况下,Couchbase 无疑是你更好的选择。(原话中比较的是 Memcached,Couchbase 作为 Memcached 的加强版,继承了其技术实现)

Redis 的优势  
   1 丰富的数据结构

Redis 支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs 等数据类型。而 Couchbase 仅仅支持 json 格式。如果有粉丝列表,排行榜,消息队列等功能需求,选择 Redis 能给你带来很大的便利,因为它丰富的数据结构能够简化开发和交互步骤。

为了证明 Redis 的优势,我们简单举个实例对比,来描述下 Hash 的应用场景。

数据存储于 Couchbase

包含以下信息:用户 ID 为查找的 key,存储的 value 用户对象包含姓名,年龄,生日等信息,如果用普通的 key/value 结构来存储,在 Couchbase 中有以下 2 种存储方式。

▪ 第一种方式将用户 ID 作为查找 key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化 / 反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入 CAS 等复杂问题。

Redis vs Couchbase,究竟哪个更胜一筹?

▪ 第二种方法是用户信息对象有多少成员就存成多少个 key-value 对,用户 ID+ 对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户 ID 为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。

Redis vs Couchbase,究竟哪个更胜一筹?

▲数据存储于 Redis 中

Redis vs Couchbase,究竟哪个更胜一筹?

Key 仍然是用户 ID, value 是一个 Map,这个 Map 的 key 是成员的属性名,value 是属性值,这样对数据的修改和存取都可以直接通过其内部 Map 的 Key(Redis 里称内部 Map 的 key 为 field), 也就是通过 key(用户 ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。这也就是 Redis 作者高内存利用率的论据。

因此,如果有大量大有复杂结构的数据需要缓存,redis 是更好的选择,它不仅能简化你的存储设计,还能帮你避免更新操作时繁琐的序列号和反序列化。像 twitter 的关注列表,粉丝列表等就是选用了 redis 的 list,Agora Games 的排行榜就是选用了 redis 的有序集合。

   2 counter-- 计数器

Redis 和 Couchbase 都提供了 counter 这一特殊数据类型,很多平台都是以 counter 为基础实现的流控和计数功能。但 counter 不同于其他数据,它对实时性的要求非常高,因此十分考验缓存系统的主键失效策略。这里简单提一下,大多数缓存系统都提供了积极失效和消极失效两种策略保证失效数据清理。

▪ 积极策略采用定时定比例抽样清理策略

▪ 消极策略则属于请求触发式的,这里我们主要对消极策略展开叙述。

Redis 2.6 之后的版本采用毫秒为单位存储过期时间,每次数据访问操作都需要进行过期检验,由此保证毫秒级别的过期精度。而 couchbase 的过期精度是秒级别的,也就是说如果你选择了 couchbase 且没有在 counter 上做特殊处理,你的流控将变得极不准确,更危险的是这个问题是由底层机制引发的,你几乎不可能通过业务代码来修复 bug。比如你限制一个客户每秒只能访问 500 次,但实际情况是客户平均下来每秒只能访问不到 300 次,这就是计数器延迟失效引发的问题。

因此,如果选择 Couchbase,要实现准确的流控和计数可能要手动为每一个计数器的 key 添加时间戳,并通过取余操作限制 counter 的峰值数量,当然如果你难以保证所有服务器时钟同步,你可以指定服务器的时间,这也算是 Couchbase 方案的灵活性吧。

总而言之,如果你有高精度的流控和计数类需求,又不想对原生的 counter 二次封装,请选择 redis。

   3 事务

相比 Couchbase,Redis 提供了事务的功能,可以保证一串命令的原子性,中间不会被任何操作打断,主要命令包括主要命令包括 MULTI、EXEC、WATCH 命令。如果对事务有所要求,redis 是个更好的选择。

   4 开源社区的繁荣

Redis 在国内大热,爱好者们不仅翻译了官网,更为其量身定做了很多优化方案,各种中文技术文档也是一应俱全。相比而言,Couchbase 的商业版和社区版差别巨大,更趋近于闭源,网上中文资料少得可怜,所有技术文档都需要翻阅英文官网。

因此,如果你的开发团队缺少很好的英文阅读能力,redis 是更好的选择。

   5 丰富的使用场景

Redis 可以适配丰富的场景,有以下五种为最为常见:

  • 会话缓存(Session Cache):这是最常用的一种使用 Redis 的情景。

  • 全页缓存(FPC):除基本的会话 token 之外,Redis 还提供很简便的 FPC 平台。以 Magento 为例,Magento 提供一个插件来使用 Redis 作为全页缓存后端。

  • 队列:Reids 在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得 Redis 能作为一个很好的消息队列平台来使用。Redis 作为队列使用的操作,就类似于本地程序语言(如 Python)对 list 的 push/pop 操作。例如,Celery 有一个后台就是使用 Redis 作为 broker。

  • 排行榜 / 计数器:Redis 在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis 只是正好提供了这两种数据结构。

    所以,我们要从排序集合中获取到排名最靠前的 10 个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可。当然,这是假定是根据用户的分数做递增的排序。如果想返回用户及用户的分数,你需要这样执行:ZRANGE user_scores 0 10 WITHSCORESAgora Games 就是一个很好的例子,用 Ruby 实现的,它的排行榜就是使用 Redis 来存储数据的。

  • 发布 / 订阅:发布 / 订阅的使用场景确实非常多。不仅在社交网络连接中使用,还可作为基于发布 / 订阅的脚本触发器,甚至用 Redis 的发布 / 订阅功能来建立聊天系统。

Couchbase 的优势  
   1 web 界面

Couchbase 提供了良好的管理界面,集配置,管理,监控和告警于一身。Couchbase 的 web 界面提供了版本提醒,ssl 证书配置,用户管理,邮件告警等一系列丰富的功能,大大简化了运维的工作;也 web 界面可以直观的观测 OPS,磁盘写入队列,内存数据量,Compaction 和 Ejection 实时状况,为开发和测试提供了直观的数据参考。对性能测试至关重要。而 redis 就仅有第三方提供的一些简单客户端产品,用于观测数据存储情况,配置优化相关的工作也需要在配置文件中操作。

如果考虑到后期性能测试以及运维的可操作性,couchbase 是更好的选择。

   2 三高

这里的三高指的是高性能,高可用性和高伸缩性。

Redis 从一开始就是单点解决方案,直到 Redis3.0 后才出来官方的集群方案,而且仍存在一些架构上的问题,其高可用性目前还没有在线上被证明,第三方的集群方案像豌豆荚的 Codi 又缺少官方的后续支持。

相比而言,Couchbase 从一开始就内建集群系统,即使是节点重启,数据未完全载入内存,也能照常提供服务,这得益于每份数据的 metedata,其中包含近期的操作信息,Couchbase 借此来区分热数据,只要热数据加载到最低水位即可立即提供服务。

如果出现节点失效,集群可在指定的时间里自动发现并启动 failover,这里不同 Redis 的哨兵系统,Couchbase 采用激活失效节点备份将请求分摊给幸存节点的方案,恢复时间更快;如果节点新增,Couchbase 会将内存数据复制,一份用于提供服务,一份用于重分配并时刻保证数据一致性,即集群扩容不会导致任何业务中断。此外,couchbase 的异步持久化和备份同步(通过维护一个持久化队列)也要优于 redis 的 RDB 快照和 AOF 日志方案。因此,从三高的角度来看,高可用性和高伸缩性上 Couchbase 显然是更加可靠的。

Couchbase 的集群方案相比 Redis,对用户屏蔽了更多细节,集群更具弹性,且经过多年的生产线上验证。因此,如果高可用和弹性是重要考虑因素,那 Couchbase 无疑是更稳妥的方案。

两款产品直观的优势如上,大家可以根据本文结合实际业务场景进行选择。有兴趣的同学推荐阅读《Seven Databases in Seven Weeks》。

Redis vs Couchbase 内存管理分析  

对于像 Redis 和 Couchbase 基于内存的数据库系统来说,内存管理的效率高低是影响系统性能的关键因素。

   Couchbase 内存管理分析

Couchbase 默认使用 Slab Allocation 机制管理内存,其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的 key-value 数据记录,以完全解决内存碎片问题。(其实是把外部碎片转化为了内部碎片)Slab Allocation 机制只为存储外部数据而设计,也就是说所有的 key-value 数据都存储在 Slab Allocation 系统里,而 Couchbase 的其它内存请求则通过普通的 malloc/free 来申请,因为这些请求的数量和频率决定了它们不会对整个系统的性能造成影响。

Slab Allocation 的原理相当简单。 如图所示,它首先从操作系统申请一大块内存,并将其分割成各种尺寸的块 Chunk,并把尺寸相同的块分成组 Slab Class。其中,Chunk 就是用来存储 key-value 数据的最小单位。每个 Slab Class 的大小,可以在 Couchbase 启动的时候通过制定 Growth Factor 来控制。假定图中 Growth Factor 的取值为 1.25,如果第一组 Chunk 的大小为 88 个字节,第二组 Chunk 的大小就为 110 个字节,依此类推。

Redis vs Couchbase,究竟哪个更胜一筹?

当 Couchbase 接收到客户端发送过来的数据时首先会根据收到数据的大小选择一个最合适的 Slab Class,然后通过查询 Couchbase 保存着的该 Slab Class 内空闲 Chunk 的列表就可以找到一个可用于存储数据的 Chunk。当一条数据库过期或者丢弃时,该记录所占用的 Chunk 就可以回收,重新添加到空闲列表中。

从以上过程我们可以看出 Couchbase 的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费。因为每个 Chunk 都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如图 所示,将 100 个字节的数据缓存到 128 个字节的 Chunk 中,剩余的 28 个字节就浪费掉了(这就是内部碎片,但相比外部碎片是可控的,也是可再利用的)。

Redis vs Couchbase,究竟哪个更胜一筹?

   Redis 内存管理分析

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 vs Couchbase,究竟哪个更胜一筹?

Redis 通过定义一个数组来记录所有的内存分配情况,这个数组的长度为 ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为 zmalloc_allocations。zmalloc_allocations[16] 代表已经分配的长度为 16bytes 的内存块的个数。zmalloc.c 中有一个静态变量 used_memory 用来记录当前分配的内存总大小。所以,总的来看,Redis 采用的是包装的 mallc/free,相较于 Couchbase 的内存管理方法来说,要简单很多。

总的来说,Couchbase 的内存管理机制以每次分配冗余空间为代价,避免了内存碎片。如果程序需要频繁短时效的百字节以上的内存空间,比如动态令牌,Couchbase 显然是更好的选择;如果仅仅使用长效的计数器或几个字节的标识字段,那么使用 Couchbase 反而造成内存浪费,Redis 却是更好的选择。

集群管理  
   1  Couchbase 集群管理

Couchbase 本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现 Couchbase 的分布式存储,Couchbase 会通过在集群内部和客户端直接共享 vbucket 和节点映射关系,客户端每次操作前需要对数据的 key 进行计算,以确定数据落入的 vbucket 编号,再根据映射表确定数据所在节点,然后直接与指定节点通信,不需要 Redis 的节点重定位方案,对于集群变更对外也只需要更新 vbucket 和节点映射关系即可。下图是 Couchbase 的分布式存储实现架构。

Redis vs Couchbase,究竟哪个更胜一筹?

现在我们模拟一下 Couchbase 的失效备援方案,假设当前客户端的 vbucket 和节点映射关系如下:

Redis vs Couchbase,究竟哪个更胜一筹?

那么当 D 节点失效后,集群只需要激活 ABC 上 D 节点的数据副本,然后更新 vbucket 和节点映射关系如下:

Redis vs Couchbase,究竟哪个更胜一筹?

   2 Redis 集群管理

相较于 Couchbase 只能采用客户端实现分布式存储,Redis 更偏向于在服务器端构建分布式存储。最新版本的 Redis 已经支持了分布式存储功能。Redis Cluster 是一个实现了分布式且允许单点故障的 Redis 高级版本,它没有中心节点,具有线性可伸缩的功能。

下图是 Redis Cluster 的分布式存储架构:

Redis vs Couchbase,究竟哪个更胜一筹?

其中节点与节点之间通过二进制协议进行通信,节点与客户端之间通过 ascii 协议进行通信。在数据的放置策略上,Redis Cluster 将整个 key 的数值域分成 4096 个哈希槽,每个节点上可以存储一个或多个哈希槽,也就是说当前 Redis Cluster 支持的最大节点数就是 4096。Redis Cluster 使用的分布式算法也很简单:crc16( key ) % HASH_SLOTS_NUMBER。

为了保证单点故障下的数据可用性,Redis Cluster 引入了 Master 节点和 Slave 节点。在 Redis Cluster 中,每个 Master 节点都会有对应的两个用于冗余的 Slave 节点。这样在整个集群中,任意两个节点的宕机都不会导致数据的不可用。当 Master 节点退出后,集群会自动选择一个 Slave 节点成为新的 Master 节点。

Redis vs Couchbase,究竟哪个更胜一筹?

总而言之,Couchbase 把数据分布计算分摊给客户端执行,节省了缓存服务器的 CPU,并且客户端直接和数据所在节点通信节省了带宽并缩短了响应时间。且相比 Redis 至少需要 6 个实例才能组成集群的限制,Couchbase 的集群方案更加灵活(但 Redis 可以一机多个实例,Couchbase 单机只能部署一个)。

因此,如果机器资源充足,Couchbase 可以提供更好的服务体验(由于客户端分摊计算成本,这里的机器不需要过多 CPU),如果只有机器资源紧张,redis 是部署上的轻量级方案,但前面提到的,当访问量爆发时,可能会考验缓存服务器的 CPU。

该怎么选择?  

在我看来,Conchbase 和 Redis 本就是定位不同的两款产品。Redis 的亮点在于业务契合度高,Couchbase 的亮点在于高可用。如果不是二选一的场景,它们是可以相辅相成的,Redis 的定位是一个带有丰富数据结构的内存数据库,充分利用其数据结构可以简化许多业务场景下的开发,如利用队列实现消息队列,利用有序集合实现排行榜;而 Couchbase 的定位是一个专业的分布式缓存系统,将一些业务关键信息,如鉴权信息和会话信息存储其中,能最大限度保证业务的安全性和高可用性。

Redis&Conchbase 的缓存系统选型:

Redis vs Couchbase,究竟哪个更胜一筹?

Redis vs Couchbase,究竟哪个更胜一筹?

本文转自”恒生技术之眼”博客,作者杨挺,原文《Couchbase vs Redis,究竟哪个更胜一筹?》链接为 http://rdc.hundsun.com/portal/article/736.html

InfoQ 已获得转载授权。


以上是关于Redis vs Couchbase,究竟哪个更胜一筹?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS vs. jQuery,看看谁更胜一筹

Spring Data vs Couchbase SDK [关闭]

计算机视觉VS自然语言处理,你选哪个?

CLion 和 VS 哪个是更智能的c++ IDE?

ClickHouse vs Elasticsearch谁更胜一筹?

ClickHouse vs Elasticsearch谁更胜一筹?