Memcached 与 Redis
让我们比较一下 Memcached 和 Redis。
简介
本课将讨论一些广泛采用的分布式缓存的实际实现。我们的重点将放在两个著名的开源工具上:Memcached 和 Redis。它们是高度可扩展、高性能和强大的缓存工具。这两种技术都遵循客户端-服务器模型并实现亚毫秒级延迟。让我们讨论它们中的每一个,然后比较它们的用处。
内存缓存
Memcached于 2003 年推出。它是一种键值存储分布式缓存,旨在非常快速地存储对象。Memcached 以键值对的形式存储数据。键和值都是字符串。这意味着任何已存储的数据都必须序列化。所以,Memcached 不支持也不能操作不同的数据结构。
Memcached 有一个客户端和服务器组件,每个组件都是运行系统所必需的。该系统的设计方式是一半逻辑包含在服务器中,而另一半在客户端中。但是,每个服务器都遵循无共享架构。在这种架构中,服务器之间相互不知情,服务器之间没有同步、数据共享和通信。
由于断开连接的设计,Memcached 能够实现几乎确定性的查询速度(欧(1个))( O ( 1 ))使用高端系统每秒提供数百万个密钥。因此,Memcached 提供了高吞吐量和低延迟。
从典型 Memcached 集群的设计可以明显看出,Memcached 可以很好地水平扩展。客户端进程通常由服务主机维护,服务主机也与权威存储(后端数据库)进行交互。
Facebook 和 Memcached
Facebook 中的数据访问模式需要频繁读取和更新,因为视图是动态呈现给用户的,而不是提前生成的。因为 Memcached 很简单,所以很容易选择解决方案,因为 Memcached 是 2003 年开始开发的,而 Facebook 是 2004 年开发的。事实上,在某些情况下,Facebook 和 Memcached 团队合作寻找解决方案。
雷迪斯(笔者: 其实就是 redis 直接ctrl+F 搜索 全文替换为 redis即可)呢?
Redis 是 2009 年开发的。因此,当时 Facebook 不可能使用 Redis。
Memcached 的一些简单命令包括:
get <key_1> <key_2> <key_3> ...
set <key> <value> ...
delete <key>[<time>] ...
在 Facebook,Memcached 位于 MySQL 数据库和 Web 层之间,该层使用分布在 800 多台服务器上的大约 28 TB 的 RAM(截至 2013 年)。通过近似最近最少使用 (LRU) 逐出策略,Facebook 能够实现 95% 的缓存命中率。
下图显示了 Facebook 缓存架构的高级设计。正如我们所看到的,在 Web 层发出的总共 5000 万个请求中,只有 250 万个请求到达了持久层。
雷迪斯
Redis是一种数据结构存储,可用作缓存、数据库和消息代理。它以额外的复杂性为代价提供了丰富的特性。它具有以下特点:
- 数据结构存储:Redis 了解它存储的不同数据结构。我们不必从中检索数据结构,操作它们,然后将它们存储回去。我们可以进行内部更改,从而节省时间和精力。
- 数据库:它可以将所有内存中的 blob 保存在辅助存储上。
- 消息代理:异步通信是分布式系统中的一项重要要求。Redis 每秒可以将数百万条消息从系统中的一个组件翻译到另一个组件。
Redis 提供了内置的复制机制、自动故障转移和不同级别的持久性。除此之外,Redis 理解 Memcached 协议,因此,使用 Memcached 的解决方案可以转化为 Redis。Redis 的一个特别好的方面是它将数据访问与集群管理分开。它解耦数据并控制平面。这会提高可靠性和性能。最后,由于使用异步复制,Redis 不提供强一致性。
Redis集群
Redis 具有提供高可用性的内置集群支持。这称为 Redis 哨兵。一个集群有一个或多个使用多线程代理查询的 Redis 数据库。Redis 集群执行自动分片,其中每个分片都有主节点和辅助节点。但是,数据库或节点中的分片数量是可配置的,以满足应用程序的期望和要求。
每个 Redis 集群都由集群管理器维护,其工作是检测故障并执行自动故障转移。管理层由监控和配置软件组件组成。
Redis 中的流水线
由于 Redis 使用客户端-服务器模型,每个请求都会阻塞客户端,直到服务器收到结果。希望发送后续请求的 Redis 客户端必须等待服务器响应第一个请求。因此,整体延迟会更高。
Redis 使用流水线来加速这个过程。流水线是在不等待服务器响应的情况下组合来自客户端的多个请求的过程。因此,它减少了多个请求的RTT跨度数。
注释:往返时间 (RTT) 是以毫秒 (ms) 为单位的网络请求从起点到达目的地并再次返回起点所需的持续时间。 RTT 是确定本地网络或更大 Internet 上连接健康状况的重要指标,网络管理员通常使用它来诊断网络连接的速度和可靠性。
流水线化过程通过 RTT 减少了延迟,减少了进行套接字级 I/O 的时间。此外,通过操作系统中的系统调用进行模式切换是一项昂贵的操作,通过流水线操作可以显着减少这种操作。从客户端流水线化命令对服务器如何处理这些请求没有影响。
例如,客户端通过管道传输的两个请求到达服务器,而服务器无法处理第二个请求。服务器为第一个提供结果并为第二个返回错误。客户端独立地将类似的命令批处理在一起以实现最大吞吐量。
相关信息
如果客户端和服务器都在同一台机器上,流水线将延迟至少提高了五倍。该请求在环回地址 ( ) 上发送127.0.0.1
。在将请求发送到远程机器的系统中,流水线的真正威力得到了突显。
Memcached 与 Redis
尽管 Memcached 和 Redis 都属于 NoSQL 家族,但它们有一些微妙的区别:
简单性: Memcached 很简单,但是它将管理集群的大部分工作留给了集群的开发人员。然而,这意味着使用 Memcached 可以更好地控制。另一方面,Redis 自动执行大部分可扩展性和数据划分任务。
持久性: Redis 通过仅附加文件 (AOF) 和 Redis 数据库 (RDB) 快照等属性提供持久性。Memcached 中没有持久性支持。但是这个限制可以通过使用第三方工具来解决。
数据类型:Memcached 存储对象,而 Redis 支持字符串、排序集、哈希映射、位图和超级日志。但是,最大键或值大小是可配置的。
内存使用:这两种工具都允许我们为缓存设置最大内存大小。Memcached 使用 slab 分配方法来减少碎片。但是,当我们更新现有条目的大小时或存储许多小对象时,可能会浪费内存。尽管如此,还是有一些配置解决方法可以解决此类问题。
多线程: Redis 使用一个内核作为单个进程运行,而 Memcached 可以通过多线程技术有效地使用多核系统。我们可以争辩说,Redis 被设计为单线程进程,降低了多线程系统的复杂性。尽管如此,可以并发执行多个 Redis 进程。与此同时,Redis 多年来通过调整其性能得到了改进。因此,Redis 可以高效地存储小数据项。Memcached 可能是文件大小超过 100 K 的正确选择。
复制:如前所述,Redis 通过几个命令自动执行复制过程,而 Memcached 中的复制再次受制于第三方工具的使用。在架构上,Memcached 由于其简单性可以很好地水平扩展。Redis 通过相当复杂的集群提供可伸缩性。
下表总结了 Memcached 和 Redis 之间的一些主要区别和共同特征:
Memcached 和 Redis 提供的功能
特征 | 内存缓存 | 雷迪斯 |
---|---|---|
低延迟 | 是的 | 是的 |
坚持 | 可以通过第三方工具 | 多种选择 |
多语言支持 | 是的 | 是的 |
数据分片 | 可以通过第三方工具 | 内置解决方案 |
使用方便 | 是的 | 是的 |
多线程支持 | 是的 | 不 |
支持数据结构 | 对象 | 多种数据结构 |
支持交易 | 不 | 是的 |
驱逐政策 | LRU | 多种算法 |
Lua 脚本支持 | 不 | 是的 |
地理空间支持 | 不 | 是的 |
总而言之,Memcached 更适用于更小、更简单的读取密集型系统,而 Redis 适用于复杂且读取和写入密集型的系统。
警告
问题一
从实现细节来看,这两个框架(Memcached 或 Redis)中的哪一个与我们在上一课中设计的分布式缓存具有惊人的相似性? 答案是内存缓存。原因如下:
客户端软件选择使用散列算法的缓存服务器。 服务器软件使用内部哈希表存储每个键的值。 最近最少使用(LRU)被用作驱逐策略。 不同的缓存服务器之间没有通信。
问题二
为什么存在用于持久化 Memcached 数据的第三方工具? 这是因为有大量的数据被读取和写入到缓存服务器,它们可能偶尔会因为某种原因而崩溃。重新启动后,在特定情况下从头开始构建缓存可能需要长达数小时的时间,最终会降低系统性能。因此,缓存数据可能会持久保存到磁盘,以便在重启时加载。
问题三
与仅存储字符串相比,存储不同的数据结构有什么优势? 主要优点是Redis可以就地修改数据,不会因为下载和上传而浪费网络带宽。它节省了网络带宽,但也通过避免数据的序列化和反序列化来节省时间和精力。
结论
无法想象不使用缓存系统的高速大规模解决方案。在本章中,我们介绍了对缓存系统的需求及其基本细节,并编排了一个基本的分布式缓存系统。我们还熟悉了两个最著名的缓存框架的设计和功能。