作者: Nibbling Wei.
什么是 memcached?
Memcached 是一个免费的、开源的、高性能的、分布式的内存对象缓存系统,支持将任何数据类型的块数据存储在键值对中。 从本质上讲,memcached 对所有应用程序都是通用的,但最初用于存储经常访问的静态数据,减轻数据库负载并加速动态 Web 应用程序。
memcached 功能
内存存储Memcached 的所有数据都存储在内存中,与 PostgreSQL 和 MySQL 等持久化数据库相比,存储过程不需要重复往返磁盘,提供内存响应时间(< 1ms),每秒可以执行 10 亿次操作。 分散式分布式多线程架构使其易于扩展。 支持跨多个节点分散数据,允许通过向集群添加新节点来扩展容量。 此外,memcached 指定了一个节点的多个核心,使用多线程来提高处理速度。 键值存储Memcached可以存储任何类型的数据,并支持存储所有频繁访问的数据,适用于各种应用场景。 不支持联邦查询等复杂操作,以提高查询效率。 简单易用Memcached 为各种语言框架提供客户端程序,如 j**a、c++、go 等。 典型应用场景
适用场景
缓存
memcached 的初始用例是存储网页的静态数据(html、css、**session 等),读取频率更高,修改更少。 用户在访问网页时,可以优先返回内存中的静态数据,从而提高 **. 与其他缓存一样,memcached 并不能保证每次访问数据时都存在数据,而是提供短期访问加速的可能性。
数据库前端
Memcached 可以作为客户端和系统中持久化数据库之间的高性能内存缓存,减少对速度较慢的数据库的访问次数,减少后端系统的负载,其中 memcached 基本上等于数据库的一个副本。 读取数据库时,首先检查memcached是否存在,如果不存在,则进一步访问数据库,如果存在则直接返回。 写入数据库时,写入 memcached 并直接返回,空闲时再写入数据库。
例如,在社交应用中,经常会出现“最新评论”和“最热门评论”等功能,这些功能需要大量的数据计算,并且经常被调用。 如果只使用关系型数据库,则需要频繁读取和写入大量磁盘。 在进行此类计算时,大多数数据都会被重用,因此将其保留在内存中一小段时间可以大大加快该过程。 在上次从 1000 条评论中计算出最受欢迎的评论后,重新访问了 800 条评论,它们仍保留在 memcached 中。 下次统计最受欢迎的评论时,只需要从数据库中多出 200 条评论,从而节省了 80% 的数据库读写。
数据量大,读写频率高
Memcached 是一个内存数据库,其访问速度比其他持久化设备快得多。 此外,作为分布式数据库,memcached 支持水平扩展,将高负载请求分布在多个节点上,并提供高并发的访问模式。
不适用场景
缓存对象太大
由于存储设计的原因,官方建议缓存的对象不应大于 1MB,并且 memcached 本身并不是为了存储和处理大型媒体和流式处理大型 blob 而设计的。
您需要遍历数据
Memcached 仅支持几个命令:set、put、inc、dec、del 和 cas,不支持对数据的遍历访问。 memcached需要在恒定的时间内完成读写操作,但遍历数据所花费的时间会随着数据量的增加而增加,这会影响进程中其他命令的执行速度,这不符合设计理念。
高可用性和容错性
memcached 并不保证缓存的数据不会丢失,相反,memcached 有命中率的概念,这意味着预期的数据丢失行为是可以接受的。 当您需要保证数据容灾备份、自动分区、故障转移等功能时,最好将数据存储在持久化数据库(如MySQL)中。
memcached 核心概念
内存管理
如图所示,memcached 用于内存管理
slab为了防止内存碎片,Memcached 使用 SLAB 来管理它。 Memcached 将内存划分为多个区域,称为 slabs。 存储数据时,根据数据的大小选择SLABS,每个SLAB只负责一定范围内的数据存储。 例如,图中的 slab 仅存储大小为 1001 2000 字节的值。 Memcached 默认情况下,下一个 slab 的最大值为 125x,可以通过修改 -f 参数进行修改。 pageslab 由一个页面组成,该页面的固定大小为 1m,可以在启动时使用 -i 参数指定。 如果需要请求内存,memcached 会划分一个新页面并将其分配给需要它的 slab 区域。 分配页面后,在重新启动之前不会对其进行 ** 或重新分配。 chunk存储数据时,memcached 会在页面中分配一个固定大小的块,并将值插入到该块中。 需要注意的是,无论插入的数据大小是多少,块的大小始终是固定的,每条数据都会有一个单独的块,因此同一块中不会存储两个较小的数据。 如果块不够,则只能将其存储在下一个 slab 类的块中,从而造成空间浪费。
lru
如图所示,Memcached 使用修改后的 LRU 机制来管理内存中项目。
hot这是因为项目可能表现出很强的时间局部性或非常短的 TTL(生存时间)。 因此,项目永远不会在热状态内移动:一旦某个项目到达队列的末尾,如果该项目处于活动状态 (3),它将被移动到暖状态,如果处于非活动状态 (5),它将被移动到冷状态。 warm充当扫描工作负载的缓冲区,例如阅读旧帖子的 Web 爬虫。 从未被击中过两次的物品不能进入温暖状态。 暖项目有更大的机会在TTL中幸存下来,同时也减少了锁争用。 如果尾随项处于活动状态,我们将其移回头部 (4)。 否则,我们将非活动项移至冷 (7)。 cold包含活动最少的项目。 非活动项目将从热 (5) 和暖 (7) 流向冷。 一旦内存已满,该项目就会从寒冷的尾巴中移除。 如果某个项目处于活动状态,它将异步排队以预热 (6)。 如果冷服务器发生突发或大量命中,缓冲区队列可能会溢出,并且项目将保持非活动状态。 在超载情况下,从冷移动成为概率事件,而不会阻塞工人。 temp作为新项目的队列,它们的 TTL 很短 (2)(通常为几秒钟)。 临时中的项目不会被替换,也不会流向其他 LRU,从而节省 CPU 和锁争用。 默认情况下,此功能当前未启用。 爬网同时通过 LRU 从下到上向后遍历每个爬网程序项。 爬网程序会检查它传递的每个项目,看看它是否过期,如果是,它就过期了。
主要版本简介
1.6.0:支持外接闪存、更多协议和网络优化15.0:优化 LRU 实现,存储优化14.0:支持 C、J**A 等客户端实现,Binary Protocol 推荐使用最新的稳定版本,接下来,Prometheus 会监控开源 Memcached 的一些关键指标。
系统指标
运行状态
启动状态是监控memcached最基本的指标,表示memcached实例是否正常运行或是否重启。 当 memcached 关闭时,对整个系统功能的影响可能很小,因为对数据的访问会提交到底层持久性数据库,但如果没有 memcached 的缓存会使系统的效率至少降低一个数量级。
检查 memcached 启动了多长时间有助于验证 memcached 是否已重新启动。 由于 memcached 将所有数据都放在内存中,因此当 memcached 重新启动时,所有缓存的数据都将丢失。 这时,memcached 的命中率会急剧下降,导致缓存雪崩,这也会给底层数据库带来很大的压力,降低系统效率。
内存使用量
memcached作为高性能缓存,需要充分利用节点的硬件资源来提供快速的数据存储和查询服务,如果节点的资源使用超出预期或达到极限,可能会导致性能下降或系统崩溃,影响服务的正常运行。 memcached 将数据放在内存中,因此我们需要关注内存使用情况。
如果memcached的内存使用率过高,可能会影响节点的其他运行任务。 需要考虑密钥的设计是否科学,是否增加了硬件资源。
读取和写入指标
读/写速率
读写速率是memcached集群性能的重要指标,如果读写延迟过高,可能会导致系统响应时间长、节点负载高、系统瓶颈等问题。 读写指标提供了memcached运行效率的概览,如果读写延迟较高,运维人员可以关注其他监控数据进行排查。 读写速率慢的原因有很多,例如命中率低和节点资源紧张。 需要采取不同的故障排除和优化措施来提高不同问题的性能。
命令速率
memcached 支持多种命令,例如:set、get、delete、cas、incr 等。 当命令速率较低,导致整体速率较低时,可以考虑调整 Item 存储策略,修改访问方式,提高 memcached 的性能。
命中率
缓存可以提高查询的性能和效率,减少对磁盘的读取次数,从而提高系统的响应能力和吞吐量。 命中率是memcached最重要的指标,指的是上层应用在获取某项数据时,发现可以从memcached获取到该数据,而无需访问底层数据库。 命中率越高,大部分数据都在内存中访问。
在使用缓存的系统中,可能会出现缓存雪崩、缓存穿透、缓存击穿等情况,导致在一定时间内命中率较低,系统的运行情况非常低,因为大部分数据访问都落在磁盘上,底层数据库承受着很大的压力。 我们需要密切关注命中率的变化,以确保 memcached 在系统中发挥应有的作用。 例如,如果某个时间段的响应突然变得非常慢,并且您发现该时间段的命中率非常低,然后查看日志,则发现某个页面由于业务变化而突然从不频繁访问变为高频访问,这就是发生了缓存渗透的情况。 解决命中率低的问题需要结合其他指标进行分析,比如下面的板坯指标。
SLAB 指标
作为键值数据库,memcached 将内存中的一对键值作为项目引用。 了解项目在 memcached 中的存储方式可以优化其内存使用效率并提高命中率。
物品存储
监控 Item 的存储状态:memcached 存储的 Item 总数、**存储的 Item 总数、被驱逐的 Item 总数。 通过查看项目总数的趋势,可以看到 memcached 存储的压力,以及使用 memcached 的应用程序的存储模式。
逐出和逐出的区别在于,当需要逐出一个项目时,Memcached 会查看 LRU 尾部周围的一些项目,以查找可用于重用其内存空间的过期项目,而不是逐出真正的尾部。
SLAB 用法
按照 memcached 的设计思路,每个 slab 存储相同大小的项目,每个项目独占一个块,这是为了提高内存利用率。 但是,在使用过程中,这样的设计仍有优化的空间。
Memcached钙化是一个问题。 当内存达到 memcached 限制时,服务进程会执行一系列内存方案,但无论采用何种内存方案,都只有一个大前提:只有与即将写入块的数据一致的 slab。
例如,我们过去存储大量 64KB 项目,现在我们需要存储大量 128KB 项目。 如果内存配额不够,并且这些 128KB 的 Item 不断更新,为了存储新的数据,memcached 只能选择其他 128KB 的 Item 进行逐出。 我们发现原来的 64KB 项目没有被逐出,并且在过期前一直占用内存空间,导致空间浪费,最终命中率降低。
为了解决钙化问题,有必要了解每个SLAB中项目的分布情况。 我们提供这种类型的监视,以查看存储项目的数量在楼板之间如何比较。 如果发现某些板存储的项目数量比其他板多得多,请考虑调整每个板的大小。 默认板尺寸增长因子为 125,即每块板的容量是前一块板的 125次。 通过降低生长因子和设置板的起始尺寸,使项目均匀分布在板上,可以有效缓解钙化问题,提高内存使用效率。
LRU 指标
区域项目数
在 Memcached 的 LRU 中,每个区域都有不同的功能。 热是最近存储的项目,暖是热的项目,冷是即将过期的项目。 了解每个区域的 Item 数量,可以更深入地了解 memcached 的状态,并提供调优解决方案。 以下是一些示例:
热区域中的项目较少,而其他区域中的项目较多。 这说明新创建的 Item 少了,memcached 中更新的数据少了,系统中的数据主要被读取了。 反之,如果热区有较多的物品,则说明新创建的物品较多,此时系统主要写入。
暖区中的项目多于冷区中的项目。 这时候,物品被击中的情况很多,这是一个很好的情况。 反之,命中率低,需要考虑优化。
移动项目数
无论某个项目是否命中,它位于哪个 LRU 区域。 基于LRU的设计思想,可以通过监控LRU区域内物品的移动来获取数据访问的状态。 以下是一些示例:
从冷区移动到暖区的项目数增加。 表示命中了即将过期的项,当值过大时,表示一些冷门数据突然变成了热数据。 这种情况需要注意,以防止命中率下降。
从热区域移动到冷区域的项目数量很大。 表示插入了大量项目且无法再访问,并且此数据可能不需要缓存,请考虑将其直接存储在底层数据库中以减轻内存压力。
温暖的区域有大量的物品。 表示插入后访问了大量 Item,这是理想的,并且 memcached 存储的数据被频繁访问,命中率高。
连接指标
连接状态
由于 memcached 使用基于事件的架构,因此大量客户端通常不会变慢。 当用户有数十万个连接的客户端时,Memcached 也可以工作。 但是,监控当前的用户连接数可以概述 memcached 的工作方式。
连接错误
memcached 限制单个客户端连接可以对每个事件发出的请求数,该请求数由启用时的 -r 参数确定。 客户端超过此值后,服务器会优先处理其他客户端,然后再继续处理原始客户端请求。 应始终对此进行监控,以确保客户端正确使用 memcached。
memcached默认的最大连接数为1024,运维人员需要监控连接数是否超过限制,影响功能的正常使用。
详细定义了指标
系统指标
读取和写入指标
商店指标
SLAB 存储指标
LRU 存储指标
连接指标
默认情况下,我们提供 memcached 概述
概述
在检查memcached的状态时,可以先检查概览中是否存在异常状态,然后再检查具体指标。
启动状态:绿色表示正常运行,即可以查询到memcached的运行指标红色表示memcached内存使用异常:使用红黄绿颜色提示,内存使用率低于80%时为绿色,80%时为黄色,90%以上为红色命中率:使用红黄绿颜色提示,红色低于10%,10%以下30%为黄色,高于30%为绿色
性能
在下面的面板中,您可以看到 memcached 的速度,它分为以下三类。
qps:每秒可处理的命令总数Command rate:每秒可处理的命令数,分为set、get等。 memcached命令读写rate:每秒可草图的数据量。
命中率
命中率是一个需要重点关注的指标,以下三个面板可以用来了解 memcached 的命中率状态。
Total Hit Rate:总体命中率趋势 命令命中率:每个命令的命中率趋势,一般关注获取板块的命中率 area:命中板所在的区域。
item
item 表示 memcached 的存储状态,通过以下面板查看 memcached 的内存使用状态。
项目总数:memcached存储项目趋势每个板坯中的项目数量:不同板坯中存储的项目数量的变化Slab使用情况,楼板尺寸:每个板坯的使用状态和对应的尺寸,钙化问题可以通过这些指标进行检查 项目移动率:通过检查项目的移动,检查热点, 命中率问题**、过期和 memcached 中的项目被驱逐 编号:当内存不足时,必须有一个项目要从 memcached 中移出
记忆
内存是 memcached 的关键硬件资源,该面板提供了对 memcached 内存使用情况的洞察
最大内存:提供内存的整体状态,以及内存使用情况 使用情况:分析内存使用趋势,OOM 次数:检查 OOM 是否是内存不足导致的
联网
虽然 memcached 提供了高并发无损支持,但网络资源不是无限的,需要持续关注:
最大连接数和连接使用量:查看趋势和仪表盘检查连接数是否满足预期的拒绝连接数:检查是否发生连接被拒绝,确保客户端正常运行,连接过多的请求数:检查趋势,确保客户端没有异常。
处理
句柄是涉及网络连接等资源的系统指标。
在为 memcached 配置告警规则时,建议您根据上述统计的指标,从操作、资源使用、连接使用等方面配置告警规则。 一般来说,我们默认生成影响memcached正常使用的告警规则,优先级更高。 与服务相关的告警,如读/写速率,由用户定义。 以下是一些建议的告警规则。
财富**条件
memcached 宕机时间
Memcached Downtime 是阈值为 0-1 的告警规则。 一般来说,部署在阿里云环境(如ACK)的memcached服务具有高可用能力,当一个memcached实例停止时,其他实例将继续工作。 可能会发生程序错误,导致无法重新部署 memcached 实例,这是一个非常严重的情况。 默认情况下,我们设置了一个警报,即 memcached 在 5 分钟内无法恢复。
memcached 重新启动
对于其他服务,实例重启不是问题。 但是,memcached 是一种典型的有状态服务,其大部分数据存储在内存中。 重启实例时,缓存的数据全部丢失,命中率下降,导致系统性能下降。 因此,建议您监控 memcached 重启告警,并在重启发生后发现相应的问题,以防止情况再次发生。
资源使用情况
内存使用量
当内存使用率过高时,memcached 无法正常工作。 我们将内存使用阈值设置为 80% 的危险和 90% 的警报。 当内存使用率为80%时,节点运行在高负载下,但一般不影响正常使用。 当长期内存使用率达到90%时,会发出告警,提示运维资源不足,可以尽快处理。
项目触发器 OOM
当内存使用量超过节点的总内存时,内存不足 (OOM) 情况可能会导致数据完全缓存刷新,从而中断您的应用程序和业务。 当节点内存利用率指标接近 100% 时,实例更有可能遇到 OOM。 我们设置了一个阈值为 0 1 的警报,一旦发生 OOM 就会发出警报。
连接使用情况
连接被拒绝
一般情况下,连接数的增加不会影响 memcached 的运行,除非超过最大连接数,客户端无法正常获取 memcached 服务。 我们设置了一个阈值为 0 到 1 的告警,一旦连接被拒绝,将立即生成告警,以保证客户端的正常运行。
连接请求过多
我们设置了一个阈值为 0 到 1 的告警,一旦出现大量连接请求,就会立即生成告警,保证客户端的正常运行。 在这种情况下,memcached 暂时不接受连接命令。
命中率低
命中率低的原因有很多,我们需要联系多个指标进行排查。
检查内存使用情况
原因:当内存资源不足时,memcached 无法存储足够的 Item,一些本应是热点的 Item会因为内存不足而被逐出。 故障排除方法:检查 ** 中的“内存使用率”面板,查看内存使用率是否一直很高。 查看告警历史,查看内存资源是否不足。 解决方法:增加相应节点的内存资源。 检查项目
原因:由于内存不足导致的低命中率也反映在项目的相关指标中。 此外,缓存项设计是否合理也可以由项指标来判断。 故障排除方法:分别检查项目总数、驱逐项目数量和项目数量,一般情况下,驱逐项目数量和项目数量在项目总数中所占的比例应该相对较小。 解决方法:增加相应节点的内存资源。 设计缓存策略以尽可能多地存储热数据。 检查 LRU 每个区域中的项目状态
原因:将来可能不需要存储的物品;一些冷门的数据突然变成了热门数据。 故障排除方法:检查 LRU 区域项的指标。 当热区移动到冷区时,项目数量很大。 指示已插入大量项目,并且无法再访问。 从冷区移动到暖区的项目数增加。 表示命中了即将过期的项,当值过大时,表示一些冷门数据突然变成了热数据。 解决方法:设计缓存策略以尽可能多地存储热数据。 优化策略可防止数据在冷点和热点之间切换。 内存使用率高
检查内存使用趋势
原因:节点的内存使用量一直都足够,但在某些时间段内会出现流量激增的情况,导致内存使用量突然增加。 故障排除方法:检查 ** 中的内存使用趋势,看看是否有内存使用率突然发生。 检查组合时间段内的流量。 解决方法:为 memcached 实例设置横向扩展策略,使其节点资源具有弹性。 检查 SLAB 使用情况
原因:发生了存储钙化问题,并且某些平板区域项目占用了内存。 故障排除方法:检查每个 SLAB 区域的使用情况,查看是否有一些特定的 SLA 具有大型存储,以及一些具有小型 SLAB 存储的特定 SLA。 解决方法:调整板尺寸策略:初始板尺寸、板尺寸增长因子,并尝试将项目均匀分布在板上。 自管 Prometheus 监控 Memcached 的痛点:
通常,我们目前的 Memcached 部署在 ECS 上,因此当我们构建自己的 Prometheus 来监控 Memcached 时,我们会面临以下典型问题:
1.由于安全、组织管理等因素,用户服务通常部署在多个孤立的VPC中,Prometheus需要在多个VPC中重复独立部署,导致部署和运维成本较高。
2.每个完整的自建监控系统都需要安装配置Prometheus、Grafana、AlertManager等,过程复杂,实施周期长。
3.ServiceDiscovery 机制与阿里云 ECS 未无缝集成,无法根据 ECS 标签灵活定义爬取目标。 如果想自己实现类似的功能,需要使用 Golang 语言开发**(调用阿里云 ECS POP 接口)并集成到开源的 Prometheus 中进行编译、打包、部署,实现门槛高、流程复杂、版本升级难度大。
4.常用的开源 Grafana Memcached ** 不够专业,缺乏结合 MSSQL 原理和最佳实践的深度优化。
5.缺少memcached告警指标模板,需要用户自行研究和配置告警项,工作量较大。
使用阿里云Prometheus监控自建memcached
登录ARMS控制台。在左侧导航栏,选择Prometheus监控>Prometheus实例,进入Prometheus实例可观察监控页面。 单击目标Prometheus实例名称,进入集成中心页面。 单击 memcached 卡的安装。
设置参数,然后单击“确定”以访问组件。
载入的组件显示在“集成中心”页面的“已安装”区域中。 单击组件卡片,可在弹出面板中查看目标、指标、告警、服务发现配置、导出器等信息。
如下图所示,您可以看到 Prometheus 为 Observable Monitoring 提供的关键告警指标
您可以点击标签页的缩略图,查看对应的 grafana
您可以单击面板中的告警页签,查看 Memcached 的 Prometheus 告警。 您也可以根据业务需要添加报警规则。 关于如何创建Prometheus告警规则,请参见Prometheus告警规则
自建Prometheus与阿里云可观测监控的对比 Prometheus监控 Memcached:
相关链接:
1] ARMS控制台。
2] Prometheus 告警规则。