亚马逊AWS官方博客

通过Amazon CloudWatch配合Amazon ElastiCache for Redis遵循监控最佳实践

原文链接:

https://aws.amazon.com/cn/blogs/database/monitoring-best-practices-with-amazon-elasticache-for-redis-using-amazon-cloudwatch/

 

通过Amazon CloudWatch配合Amazon ElastiCache for Redis遵循监控最佳实践

在维持Amazon ElastiCache资源的可靠性、可用性与性能方面,监控一直是最为重要的手段之一。在本文中,我们将共同了解如何使用Amazon CloudWatch及其他外部工具维持健康运作的Redis集群,并防止其意外中断。我们还将具体讨论对扩展需求进行预测及筹备的几种可行方法。

 

将CloudWatch与ElastiCache配合使用的优势

ElastiCache与CloudWatch相结合,能够极大提升资源相关核心性能指标的可见性。此外,CloudWatch警报还能够帮助您设置指标阈值并触发通知,确保在需要采取预防措施时及时做出提醒。

随时间对趋势加以监控,还可以帮助您检测工作负载的持续增长。您可以为数据点设置最长达455天(15个月)的时间周期,在此窗口内观察CloudWatch指标的扩展情况,据此预测资源的后续利用率与使用情况。

 

监控资源

ElastiCache Redis集群的运行状况由关键组件(例如CPU、内存以及网络)的利用率决定。这些组件的过度使用可能导致系统等待时间延长以及整体性能下降。另一方面,过度配置则可能导致资源得不到充分利用,严重影响成本的优化效果。

ElastiCache提供的指标使您能够监控集群;截至本文撰稿时,AWS已经发布18项新的CloudWatch指标

面向ElastiCache的CloudWatch指标主要分为两类:引擎级指标(由Redis INFO命令生成)以及主机级指标(来自ElastiCache节点的操作系统)。这些指标以60秒为间隔对每个缓存节点进行测量并进行发布。尽管CloudWatch允许您为每项指标任意指定统计信息与检测周期,但只有经过精心设计、相关组合才能真正服务于系统运行。例如,CPU使用率中的“平均”、“最小”以及“最大”等统计信息非常重要,但“总和”信息则基本没有任何实际价值。

CPU

Redis可以使用不同的CPU执行快照保存或者UNLINK等辅助操作,但只能通过单一线程运行命令。换句话说,Redis每次只能处理一条命令。

考虑到Redis的单线程属性,ElastiCache提供EngineCPUUtilization指标,用以提供对Redis进程本身负载情况的精确可见性,从而更好地帮助您了解Redis工作负载运行状态。

不同的用例对于高EngineCPUUtilization的容忍度都有所区别,其中不存在通用性质的阈值。但作为最佳实践,本文建议大家确保您的EngineCPUUtilization始终低于90%。

使用应用程序及预期工作负载对集群进行基准测试,可以帮助您将EngineCPUUtilization与系统实际性能关联起来。我们建议您针对EngineCPUUtilization在不同层级上设置多项CloudWatch警报,以便在达到每项阈值(例如WARN为65%,HIGH为90%)时,抢在集群性能遭遇实际影响前向您发出通知。

如果您集群的EngineCPUUtilization较高,则可以考虑以下补救措施:

  • 较高的EngineCPUUtilization指标很可能源自特定的Redis操作。Redis命令会使用Big O表示法对时间复杂度进行定义。您可以使用Redis SLOWLOG帮助您确定完成命令所需要的时间。一大常见问题在于过度使用Redis KEY命令,请在生产环境中对这条命令保持高度关注。
  • 在Redis命令的时间复杂性方面,非最优数据模型也有可能给EngineCPUUtilization指标带来不必要的压力。例如,集合的基数可能为一项性能因素,而SMEMBERS、SDIFF、SUNION以及其他集命令的时间复杂度则由集内元素的数量所定义。哈希的大小(字段数)与运行的操作类型,也会给EngineCPUUtilization造成影响。
  • 如果您在包含多个节点的节点组中运行Redis,则建议您使用副本来创建快照。在从副本创建快照时,主节点不会受到快照保存任务的影响,因此可以继续处理请求而不会降低速度。请验证该节点是否在使用SaveInProgress创建快照。在完全同步的情况下,快照应始终位于主节点之上。关于更多详细信息,请参阅备份操作的性能影响
  • 大量操作同样可能带来较高的EngineCPUUtilization。请明确操作所对应的具体负载类型。如果高EngineCPUUtilization主要源自大量读取操作,您可以在Redis客户端库中使用ElastiCache读取器端点将其配置为禁用集群模式,或者使用Redis READONLY命令将其配置为集群模式。如果您只从读取副本处进行读取,则可以在副本组或者各个分片中添加其他节点(最多五个读取副本)。如果写入操作带来较高的EngineCPUUtilization,则需要为主节点提供更强大的计算容量。您可以升级至最新一代m5与r5节点类型,使用更强的处理器快速执行任务。如果您已经在使用最新一代节点,则应考虑将禁用集群模式切换至启用集群模式。要完成切换,您可以为现有集群创建一套备份,并将另一套已经启用集群模式的新集群内还原这些数据。在启用集群模式之后,解决方案能够添加更多分片并进行横向扩展。分片数量越多,您能够添加的主节点数量就越多,计算容量自然就越强。

除了使用EngineCPUUtilization指标监控Redis进程负载之外,您还应当注意其余CPU内核的资源使用情况。通过EngineCPUUtilization,您可以监控整个主机的CPU利用率百分比。例如,由于建立连接会带来部分处理负载,因此大量新连接的涌入同样有可能拉高EngineCPUUtilization指标。

对于CPU内核数量小于等于2个的小型节点,您还需要关注CPUUtilization指标。由于除了快照及托管维护事件等操作之外,您还需要保留一部分计算容量并与Redis共享节点CPU核心,因此在EngineCPUUtilization发生变化之前,您的CPUUtilization很可能先一步达到100%。

最后,ElastiCache还支持T2与T3缓存节点。这些缓存节点提供基准水平的CPU性能,并可随时突发峰值CPU容量,直到您的免费配额耗尽为止。如果您使用的正是T2或T3缓存节点,则应监控CPUCreditUsage 与 CPUCreditBalance,这是因为在配额耗尽之后,其性能会逐渐降低至基准水平。关于更多详细信息,请参阅突发性能实例的CPU配额与基准性能

内存

内存是Redis中的一大核心要素。了解集群的内存利用率,有助于避免数据丢失并持续适应数据集规模的不断增长。

Redis INFO命令中的memory部分,提供关于当前节点内存利用率的统计信息。

其中最重要的指标之一为used_memory,即Redis使用分配器所分配的内存容量。CloudWatch提供名为BytesUsedForCache的指标,其衍生自used_memory,您可以使用这项指标确定当前集群的内存利用率。

随着18项全新CloudWatch指标的发布,现在您可以使用DatabaseMemoryUsagePercentage并根据当前内存利用率(BytesUsedForCache)以及maxmemory查看内存利用率百分比。Maxmemory将设置目标数据集的最大可用内存量。您可以使用Redis INFO命令以及Redis节点类型特定参数中的memory部分调车集群的内存上限。其默认取值由需要保留的内存容量决定。因此在设定之后,您的集群maxmemory将有所下降。例如,cache.r5.large节点类型默认最大内存为14037181030字节,但如果您希望默认保留25%的内存,则可用最大内存容量将为10527885772.5字节(14037181030 x 0.75)。

当您的DatabaseMemoryUsagePercentage达到100%时,Redis maxmemory策略将被触发,且根据所选策略(例如volatile lru)决定是否进行数据逐出。如果高速缓存内没有任何对外贸易可以进行逐出(根据逐出策略),则写入操作将失败,Redis主节点随后返回以下消息:(error) OOM command not allowed when used memory > 'maxmemory'

逐出并不代表必然发生了问题或性能下降。某些工作负载在设计上就考虑到了利用逐出机制。要监控集群内的逐出量,您可以使用Evictions指标。此指标同样可通过Redis INFO命令使用。但请注意,大量逐出同样会拉高EngineCPUUtilization指标。

如果您的工作负载在设计中并未考虑使用逐出,则建议您设置CloudWatch警报以在需要执行扩展操作时,主动根据DatabaseMemoryUsagePercentage指标的变化情况发出警报并扩展内存容量。对于禁用集群模式的场景,您可以扩展至更大的节点类型以获取更高内存容量。而对于启用集群模式的场景,横向扩展以逐步增加内存容量才是最合理的解决方案。

控制数据集增长的另一种方法,是在密钥当中使用TTL(生存时间)。当生存时间到期之后,如果客户端(以被动方式)尝试访问或Redis(以主动方式)定期测试随机密钥,则该密钥将不再提供起效并将被删除。您可以使用Redis SCAN命令来分析数据集内的某些部分,并放大被动方法以删除过期密钥(关于更多详细信息,请参阅EXPIRE过期机制)。在ElastiCache当中,密钥到期可通过Reclaimed CloudWatch指标进行监控。

在执行备份或故障转移的过程中,当将集群数据写入至.rdb文件时,Redis会使用额外的内存来记录对集群的写入操作。如果此额外的内存使用量超过了节点中的可用内存容量,则过度分页及SwapUsage会导致处理速度变慢。因此,我们建议您预留一部分内存容量。预留内存属于专为容纳某些操作(例如备份或故障转移)所预留的内存资源。关于更多详细信息,请参阅管理预留内存

最后,本文建议您为SwapUsage建立CloudWatch警报。此指标不应超过50 MB。如果集群正在消耗swap空间,请在集群的参数组中验证是否配置了充足的预留内存。

网络

决定集群网络带宽容量的一大决定性因素,在于您所使用的实际节点类型。关于节点上网络容量的更多详细信息,请参阅Amazon ElastiCache费率说明

我们强烈建议您在实际生产使用之前对集群进行基准测试,借此评估其性能表现并在监控当中设置正确的阈值。您应以数小时为周期运行基准测试,借此反映临时性网络突发容量的出现频率与潜在需求。

ElastiCache与CloudWatch提供多项主机层级的指标以监控网络利用率,类似于Amazon Elastic Compute Cloud (Amazon EC2)实例。NetworkBytesInNetworkBytesOut分别代表主机已经从网络处读取、以及发送至网络处的字节数。NetworkPacketsInNetworkPacketsOut则分别代表在网络上接收及发送的数据包数。

在定义集群的网络容量之后,您可以借此映射并建立最高网络利用率预期峰值。此峰值不应高于所选节点类型的网络容量。每种节点类型都提供一定的突发容量,但我们建议您预留这部分额外容量以应对流量的意外增加。

根据您所定义的最高利用率,您可以创建CloudWatch警报,确保在网络利用率高于预期或接近此限制时发送电子邮件通知。

如果您的网络利用率持续增加并触发了网络警报,则应采取必要措施以添加更多网络容量。要确保调整正确,您需要确定导致网络利用率提高的因素。您可以使用CloudWatch指标来检测操作强度的变化,并在读取或写入操作类别中对这种波动进行分类。

如果网络利用率的提高源自读取操作,请首先确保使用一切现有读取副本处理读取操作。您可以在配置禁用集群模式下对Redis客户端库中使用ElastiCache读取器端点,也可以在启用集群模式下使用Redis READONLY命令。如果您已经在读取副本中执行读取操作,则可以在副本组或分片当添加更多节点(最多支持五个读取副本)。

如果网络利用率提高源自写入操作,则需要为主节点添加更多容量。在禁用集群模式的场景下,您可以直接将主节点扩展为更大的节点类型。在启用集群模式时,同样可以执行这一纵向扩展操作。

另外,启用集群模式时,您还可以使用另外一种读取及写入用例扩容方法。此方法将添加更多分片并执行横向扩展,确保每个节点只负责数据集中的部分较小子集,由此保证每个节点的网络利用率保持在较低水平。

尽管横向扩展能够解决大部分网络相关问题,但这里还是要讨论几种关于高热度键的极端情况。所谓高热度键,是指访问特别频率、远超正常比例的特定键或键子集,因此导致单一分片可能需要承受高于其他分片的流量规模。如果这些键保留在同一分片上,则会带来很高的网络利用率。在这类罕见示例中,如果不变更现有数据集,则向上扩展方法往往比较适用。当然,您也可以重构数据模型以重新均衡网络利用率。例如,您可以复制字符串并拆分存储有多个元素的对象。关于在集群所有分片上分布高访问频度键及其网络消耗的详细信息,请参阅Redis集群规范

连接

CloudWatch为构建集群连接提供两项指标:

  • CurrConnections – Redis引擎所注册的并发连接及活动连接数。此指标派生自Redis INFO命令中的connected_clients属性。
  • NewConnections – 在特定时段内,Redis已接受的连接总数,包括所有处于活动状态及关闭状态的连接。此指标同样源自Redis INFO命令。

要监控连接,我们主要需要关注Redis中的maxclients限制指标。ElastiCache为该指标设定的默认值为65000。换句话说,每个节点最多可以使用65000个并发连接。

CurrConnectionsNewConnections指标均可帮助检测并预防性能问题。例如,CurrConnections的不断增加可能快速耗尽65000个可用连接。这类指标增加可能表示应用程序端出现了问题,且连接未能正确关闭,因此最终还是在服务器端占用了连接。除了调查应用程序的行为以解决问题之外,您也可以在集群中使用tcp-keepalive以检测并终止潜在的死对等连接。在Redis 3.2.4及更高版本中,默认的tcp-keepalive计时器时长为300秒。对于旧版本,默认情况下禁用tcp-keepalive。您可以在集群的参数组中调整tcp-keepalive计时器。

NewConnections的监控同样非常重要。请注意,最大客户端限制65000不适用于此指标,因为其衡量的是指定时间内创建的连接总数,而各项连接之间并不一定同时发生。在1分钟的数据采样期间,一个节点可能会收到10万个NewConnections,但从未达到2000个CurrConnections(同时连接)。在此特定示例中,工作负载并未达到Redhis需要介入的连接限制风险。但是期间发生的大量连接快速开启及关闭同样可能会影响到节点性能。创建TCP连接需要耗费几毫秒时间,这也属于应用程序在运行Redis操作时经常出现的额外有效载荷。

根据最佳实践的要求,应用程序应尽可能复用现有连接,以避免创建新连接并造成额外成本。您可以通过Redis客户端库(如果支持)使用适合当前应用程序环境的框架以建立连接池,也可以亲手动手从零开始创建连接池。

更重要的是,由于TLS握手会带来额外的时间与CPU使用率,因此在集群内使用ElastiCache传输加密功能时,请关注对新连接数量的控制。

复制

如果存在至少一个读取副本,则主节点需要向读取节点发送复制命令流。通过ReplicationBytes指标,您可以看到需要复制的数据量。尽管此指标代表副本组上的写入负载,但无法帮助我们了解副本运行状况的具体见解。为此,您可以使用ReplicationLag指标。此指标提供一项非常便捷的表示形式,用以表现副本与主节点之间的延迟。从Redis 5.0.6版本开始,此指标数据将以毫秒为单位进行捕捉。尽管比较罕见,但您可以通过监控ReplicationLag指标以检测潜在的问题,其中复制滞后的峰值将表明主节点或副本无法及时处理复制操作。一旦发生这类情况,您可能需要对副本执行完全同步。完全同步代表更为复杂的过程,需要在主节点上创建快照,并可能导致性能下降。您可以将ReplicationLag指标与SaveInProgress指标确定完全同步尝试。

严重的复制滞后趋势,往往源自写入操作过多、网络容量耗尽或者基础服务降级等问题。

对于禁用集群模式的单一主节点,如果您的写入活动强度过高,则需要考虑启用集群模式,借此将写入操作分散到多个分片及其关联的主节点之上。如果复制滞后源自网络容量耗尽,则请参考本文“网络”部分的步骤进行操作。

延迟

您可以使用一组CloudWatch指标来衡量命令的延迟,通过这些指标为每种数据结构计算总延迟。您可以使用Redis INFO命令中的commandstats统计信息计算出这项结果。

在以下图表中,我们可以看到StringBasedCmdsLatency指标,代表的是特定时间范围之内运行的、基于字符串的命令的平均延迟(以微秒为单位)。

此延迟不包含网络与I/O时间,这些属于Redis处理操作时耗费的时间。关于延迟指标的更多详细信息,请参阅Redis指标

如果CloudWatch指标指示出特定数据结构的延迟有所增加,则可以使用Redis SLOWLOG来确定哪些具体命令的运行时间较长。

如果您的应用程序遇到高延迟,但CloudWatch指标指示Redis引擎级延迟很低,则应主要关注网络延迟。Redis CLI提供一款延迟监控工具,适用于以隔离方式调查网络或应用程序问题(min,max以及avg皆以毫秒为单位):

$ redis-cli –latency-history -h mycluster.6advcy.ng.0001.euw1.cache.amazonaws.commin: 0, max: 8, avg: 0.46 (1429 samples) — 15.01 seconds rangemin: 0, max: 1, avg: 0.43 (1429 samples) — 15.01 seconds rangemin: 0, max: 10, avg: 0.43 (1427 samples) — 15.00 seconds rangemin: 0, max: 1, avg: 0.46 (1428 samples) — 15.00 seconds range

min: 0, max: 9, avg: 0.44 (1428 samples) — 15.01 seconds range

最后,您还可以监控客户端当中是否存在可能影响应用程序性能、或者导致处理时间增加的活动。

ElastiCache事件与Amazon SNS

与您资源相关的各类ElastiCache日志事件(包括故障转移、扩展操作、计划内维护等),皆包含日期与时间、源名称、源类型以及描述。您可以在ElastiCache控制台上、使用Amazon命令行界面(AWS CLI)的describe-events 命令以及ElastiCache API轻松访问这类事件。

以下截屏所示,为ElastiCache控制台内的事件:

 

监控事件可以帮助您随时了解集群的当前状态,并根据事件采取必要的措施。尽管ElastiCache事件可以通过多种方式获取,但我们强烈建议您在ElastiCache配置中使用Amazon Simple Notification Service (Amazon SNS)发送重要的事件通知。关于更多详细信息,请参阅管理 ElastiCache Amazon SNS通知

在将SNS主题添加至ElastiCache集群中时,与此集群相关的所有重要事件都将被发布至SNS主题当中,并可通过电子邮件进行发送。关于为Amazon SNS发布的ElastiCache事件的更多信息,请参阅事件通知与Amazon SNS

在配合集群使用Amazon SNS时,您还可以通过编程方式对ElastiCache事件采取措施。例如,AWS Lambda函数可以订阅SNS主题并在检测到特定事件时自动运行。关于更多详细信息,请参阅使用Amazon Lambda、Amazon Route 53以及Amazon SNS监控Amazon ElastiCache for Redis(禁用集群模式)读取副本端点

 

总结

在本文中,我们讨论了ElastiCache Redis资源监控方面的常见挑战与相关最佳实践。借助本文中提到的知识,您现在可以轻松检测、诊断并维护ElastiCache Redis资源。

 

本篇作者

Yann Richard

AWS ElastiCache解决方案架构师。他的个人目标是在次毫秒级内完成数据传输,并在4小时之内完成马拉松。