dot 快速的未来即将在您所在的城市举行活动。

加入我们,参加 Redis Released

在 AWS/Xen 基础架构上测试 fork 时间

作为 Redis 云 提供商,我们一直在测试不同的配置和 Redis 及 AWS 选项,以帮助 Redis 社区获得尽可能最好的性能。本周,我们决定了解 fork 时间如何影响不同的 AWS 平台和 Redis 数据集大小。Redis 使用 Linux forkCOW(复制写入),使用后台保存进程生成即时快照或重写仅附加文件 (AOF)。Fork 是大多数类 Unix 系统中的昂贵操作,因为它涉及到分配和拷贝大量的内存对象(请参见 此处 了解详情)。此外,Xen 平台上 fork 操作的延迟似乎比其他虚拟化平台上的更耗时(如 此处 所述)。鉴于 fork 操作在 Redis 主线程上运行(并且 Redis 架构是单线程的),fork 操作花费的时间越长,其他 Redis 操作就会被延迟得越久。如果考虑到即使在普通的机器上 Redis 每秒也能处理 50K 到 100K 次操作,几秒钟的延迟可能意味着数以十万计的操作速度减慢,而这可能会给应用带来严重的稳定性问题。对于 AWS 上的 Redis 用户来说,这个问题是切实存在的,这是因为大多数 AWS 实例都是基于 Xen。简而言之,我们的测试情景如下——我们在以下平台上运行 Redis(版本 2.4.17)

  • 常规 Xen 管理程序实例 – m1.small、m1.large、m1.xlarge、m2.2xlarge
  • Xen HVM(硬件虚拟机或 硬件辅助虚拟化)实例 – 即集群计算 cc1.4xlarge
  • Redis 使用 AOF “每秒 fsync”策略进行配置,并且关闭了自动 AOF 重写
  • 我们用 Redis 对象填充了 70%-80% 的可用内存,然后在非常高的吞吐量下随机重写这些对象,以在 fork 进程中“接触”尽可能多的内存页面
  • 我们使用 redis-cli 发出了 BGREWRITEAOF 命令,然后查看 Redis INFO 的 latest_fork_usec 字段。我们重复此过程 3-5 次,记录每次测试的平均值

可以在本文结尾找到有关测试设置的更详细描述。以下是我们发现的有关 Fork 时间的信息:

实例类型内存限制已用内存内存使用情况 (%)Fork 时间
m1.small1.7 GB1.22 GB71.76%0.76 秒
m1.large7.5 GB5.75 GB76.67%1.98 秒
m1.xlarge15 GB11.46 GB76.40%3.46 秒
m2.xlarge34 GB24.8 GB72.94%5.67 秒
cc1.4xlarge23. GB18.4 GB80.00%0.22 秒

每 GB 内存的 Fork 时间

正如您所见,实例处理能力与 Fork 操作执行时间之间存在很强的相关性。此外,Xen HVM 实例比常规 Xen 管理程序实例获得了明显更低的延迟。  因此,AWS 上的 Redis 用户应该将其数据集迁移到集群计算实例吗?不一定。原因如下

  • 最小的集群计算实例包含 23GB 和 33.5 EC2 计算单元(2 x Intel Xeon X5570,四核“Nehalem”架构)。这对大多数用户来说非常昂贵,每月花费 936 美元(不包括 EBS 存储空间、存储 I/O 和网络流量,使用按需付费模式在 us-east-1 区域)
  • 尽管集群计算实例具有许多计算单元(33.5),但每个单元都相对较弱。我们通过 cc1.4xlarge 实例测试 Redis 时,我们看到的类似于 m1.large 的结果,成本为 25%。显然,cc1.4xlarge 没有针对高速 Redis 进行优化。

Fork 时间和 Redis Cloud 我们在 Redis Cloud 上的类似场景中测试了 Fork 时间,并将结果与自助 (DIY) 方式中相应实例的结果进行了比较。我们发现了以下内容

每 GB 内存的 Fork 时间

正如您在此处看到的,与常规 Xen 管理程序平台相比,Redis Cloud 中的 Fork 时间明显更短。此外,随着数据集大小的增长,每 GB Fork 时间下降。Redis Cloud 上的 Fork 时间比 Xen HVM(cc1.4xlarge 实例)稍微长一些——对于约 1GB 的小型数据集,它是 0.03 秒,而 0.008 秒。然而,因为您的数据集大小与您的应用访问 Redis 的速率之间可能存在相关性,因此使用 Redis Cloud 时延迟请求的数量应该很小。对于较大的数据集,Redis Cloud Fork 时间为 0.03 秒/GB,而 Xen HVM 为 0.01 秒。尽管如此,在 Redis Cloud 中,我们仍然更喜欢使用 m2.2xlarge 和 m2.4xlarge 实例而不是 cc1.4xlarge 和 cc2.8xlarge 实例,原因如下

  • m2.2xlarge 和 m2.4xlarge 实例比 cc1.4xlarge 和 cc2.8xlarge (分别)有更大的内存
  • 每个 Redis 进程在 m2.2xlarge 和 m2.4xlarge 实例上运行速度快 x2-x3 倍
  • 人们可以在 Redis Cloud 中轻松设置内存中复制,这完全消除了 Fork 时间问题。在此配置中,从属分片处理持久存储访问,而主分片完全专用于处理客户端请求。

Redis Cloud 如何最大程度地减少 Fork 时间? Redis Cloud 应用了几种机制和技术来维持高性能

  • 我们在最强大的 AWS 实例(m2.2xlarge 和 m2.4xlarge)上运行所有用户的
  • 我们使用了多种内存优化技术,因此占用的内存页面更少
  • 我们对大型数据集自动分片——这确保了任何数据集大小的低而可预测的 Fork 时间

结论通过此测试我们验证了 AWS 标准 Xen 管理程序实例上的 fork 进程会导致 Redis 操作(因此也会导致您的应用程序执行)出现较大的延迟。每个 GB 的 fork 时间随着实例的加强而有所改进,但我们认为这仍然不可接受。虽然使用 AWS 集群计算实例几乎可以消除 fork 时间,但此类实例非常昂贵,没有为 Redis 操作进行优化。Redis Cloud 以合理的设施价格提供最低的 fork 时间,当数据集大小时,我们的 fork 时间会进一步缩短。 基准测试设置对于想要详细了解我们基准的人员,以下是我们使用的资源的一些详细信息

  • 自行构建 (DIY) Redis
    • 实例:m1.small、m1.large、m1.xlarge、m2.2xlarge 和 cc1.4xlarge
    • 标准 EBS 卷:所有实例 100GB(非 raid)
  • 使用 m2.4xlarge 实例的 Redis Cloud 集群,在每个集群节点上使用 2x1TB 的标准 EBS 卷(raid)

这是我们用于生成负载的设置

  • m2.2xlarge 实例,运行我们的 memtier_benchmark 负载生成工具(我们开发的一款高级负载生成工具,我们很快将在我们的github帐户中共享)。
独立的 Redis 设置
Redis 版本:2.4.17
操作系统:Ubuntu 12.04 LTS(64 位)
内核:3.2.0-23-virtual
亚马逊区域:US-EAST-1
测试的亚马逊实例:m1.small、m1.large、m1.xlarge、m2.xlarge、cc1.4xlarge

Redis Cloud 设置

Redis 版本:2.4.15
操作系统:Ubuntu 12.04 LTS(64 位)
内核:3.2.0-23-virtual
亚马逊区域:US-EAST-1
测试的亚马逊集群实例:m2.4xlarge

EBS 卷设置

标准 EBS 卷:1TB

RAID 设置

RAID 软件:MD
MD 版本:v3.2.5

RAID 配置

mdadm –create ebs-stripe –name ebs-stripe –homehost any –raid-devices 2 /dev/xvdj /dev/xvdk –chunk 256 –level 0 #其中 xvdj 和 xvdk 是每个 1TB 的 EBS 卷

memtier_benchmark 设置
版本:2.3.0-7
操作系统:Ubuntu 12.04 LTS(64 位)
内核:3.2.0-23-virtual
亚马逊区域:US-EAST-1
测试的亚马逊实例:m2.2xlarge