Memcached、Redis、Dynamo的区别

470 阅读6分钟

Memcached

可以从 memcached.org 下载的Memcached是一个分布式高性能对象缓存系统。它非常受欢迎,并被Facebook,Twitter,维基百科和YouTube等许多高流量场所使用。

Memcachedis非常简单,并且具有最少的功能集。例如,不支持备份、故障转移或恢复。它具有简单的API,几乎可以与任何Web编程语言一起使用。

在应用程序堆栈中使用 Memcached 的主要目的通常是减少数据库负载。

可以参考下图,了解典型 Web 应用程序中 Memcached 的可能配置。

image.png

Memcached 的核心是一个平板分配器。Memcached 将其值存储在平板中。平板本身由页面组成,而页面又由块或桶组成。板坯的最小尺寸为 1 kB,板坯尺寸以 1.25 的幂增长。因此,板坯尺寸可以是 1 kB(1.25 次方 0)、1.25 kB(1.25 次方 1)、1.5625 kB(1.25 次方 2)等。Memcached 可以存储最大 1 MB 的数据值。值由键存储和引用。密钥的大小最多为 250 字节。每个对象都存储在最接近大小的块或存储桶中。这意味着大小为 1.4 kB 的对象将存储在大小为 1.5625 kB 的卡盘中。这会导致空间浪费,尤其是当对象仅比下一个较小的块大小大时。默认情况下,Memcached 会耗尽所有可用内存,并且仅受底层架构的限制。

下图说明了一些基本的 Memcached 特性。

image.png

LRU 算法控制旧缓存对象的逐出。LRU 算法基于每个板类工作。存储和清理对象时可能会发生碎片。重新分配内存可以解决此问题的一部分。

Memcached 是一种对象缓存,它不组织集合中的数据元素,如列表、集、排序集或映射。另一方面,Redis 为所有这些丰富的数据结构提供支持。Redis在方法上类似于Memcached,但更健壮。

接下来,简要探讨了Redis。

Redis

Redis 中的所有内容最终都表示为一个字符串。甚至列表、集、排序集和映射等集合也由字符串组成。Redis 定义了一个特殊的结构,它称之为简单动态字符串或 SDS。该结构由三部分组成,即:

  • buff-存储字符串的字符数组

  • len-存储增益数组长度的长类型

  • free- 可供使用的附加字节数

尽管您可能会认为单独存储 len 作为开销,因为它可以根据 buff 数组轻松计算,因此它允许在固定时间内查找字符串长度。

Redis 将其数据集保存在主内存中,并根据需要将其保存到磁盘。与MongoDB不同,它不使用内存映射文件来实现此目的。相反,Redis 实现了自己的虚拟内存子系统。将值交换到磁盘时,指向该磁盘页的指针将与密钥一起存储。

除了虚拟内存管理器之外,Redis 还包括一个事件库,可帮助协调非阻塞套接字操作。

下图描述了 Redis 架构的概述

image.png

Redis 不依赖于操作系统交换,因为:

Redis 对象不会与交换页面进行一对一映射。交换页的长度为 4,096 字节,Redis 对象可以跨越多个页面。同样,多个 Redis 对象可以位于单个交换页面中。因此,即使访问了一小部分 Redis 对象,也可能触及大量交换页面。操作系统交换会跟踪交换页面访问。因此,即使访问了交换页中的字节,交换系统也会将其排除在外。

与MongoDB不同,RAM和磁盘中的Redis数据格式并不相似。与RAM数据相比,磁盘上的数据被压缩得更多。

面向列的数据库

接下来也是最后一点,注意力被转移回面向列的数据库。但是,这次它是一类特殊的面向列的数据库,那些最终一致的数据库。

最终一致的非关系数据库 谷歌的Bigtable是列数据库的灵感来源,而亚马逊的Dynamo是最终一致性商店的原型。Amazon Dynamo 背后的想法于 2007 年在操作系统原则研讨会上提出。在适当的时候,Dynamo的想法被整合到Apache Cassandra,Voldemort,Riak和Dynomite等开源实现中。

Amazon Dynamo 为推动其庞大电子商务系统的许多内部亚马逊服务提供支持。此系统具有一些基本要求,例如高可用性和容错。但是,数据集的结构使得在大多数情况下按主键查询就足够了。

不需要关系引用和联接。Dynamo 建立在一致哈希、对象版本控制、基于 gossip 的成员协议、默克尔树和提示切换的思想之上。

Dynamo 支持简单的基于获取和放置的数据存储接口。放置请求包括与对象版本相关的数据,这些数据存储在上下文中。Dynamo 旨在随着数据的增长而增量扩展。因此,它依赖于一致的哈希来实现有效的分区。

Consistent Hashing

Consistent Hashing是分布式哈希表的重要原则。在Consistent Hashing中,添加或删除槽不会显著更改密钥到槽的映射。为了理解这种哈希方案,让我们首先看一个基本的哈希方案,并了解添加或删除插槽时出现的问题。

在一组节点之间的非常基本的密钥分配策略可以涉及模函数的使用。因此,可以在7个节点之间分配50个密钥, 具有值85的关键字去往节点1,因为85对7的模是1,并且具有值18的关键字去往节点4,因为18对7的模是4,等等。在节点数量发生变化(即添加新节点或删除现有节点)之前,此策略一直有效。当节点的数目改变时,应用于现有键的模函数产生不同的输出,并导致在节点之间重新排列键。这并不是那么有效,这时Consistent Hashing来拯救。在一致散列中,不当添加或删除节点时主要受影响。解释一致散列的一个好方法是画一个圆圈,并在上面标记节点,如图所示。

image.png

现在,键本身已分配给它们最接近的节点。这意味着在图 中1、2,3 分配给节点 A,4 分配给 B,5 和 6 分配给 C,7 和 8 分配给 D。为了设置这样的方案,您可以创建一个大的哈希空间,将所有 SHA1 键说到一个非常大的数字,并将其映射到一个圆圈上。从 0 开始并顺时针方向,将所有值映射到最大值,此时您将在 0 处重新启动。节点也将在同一方案中进行哈希和映射。

现在,假设节点A被移除,而节点E被添加到一个新的位置,如图所示,则发生最小重排。1被分配给E,2和3被分配给B,但其他的都不受影响。

image.png

一致散列提供了有效的分区,而对象版本控制则有助于保持数据的一致性。


本文正在参加「金石计划 . 瓜分6万现金大奖」