.NET Memory SlidingExpiration在AWS Lambda中未按预期工作的问题
问题描述
我正在使用Microsoft.Extensions.Caching.Memory(版本6.1),发现缓存项在未被访问的情况下约5分钟就被移除。我已显式设置AbsoluteExpirationRelativeToNow和SlidingExpiration,本地运行完全正常,但在AWS Lambda环境中,缓存项似乎仍会在5分钟后被移除。
以下是部分代码:
using Microsoft.Extensions.Caching.Memory; ... public myClass(IMemoryCache memoryCache, Repository myRepository, ILogger<myClass> logger) { _memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache)); _myRepository = myRepository ?? throw new ArgumentNullException(nameof(myRepository)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } ... public async Task<bool> isItemInCache(int id) { bool ret = true; var key = id; if (!_memoryCache.TryGetValue<bool>(key, out ret)) { // query data from MSSQL string valueFromDB = _myRepository.GetAsync(id, config_id).Result; _logger.LogInformation(accountId + " Getting config from MSSQL: " + valueFromDB); Boolean.TryParse(valueFromDB, out ret); var memoryCacheEntryOptions = new MemoryCacheEntryOptions() { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60), SlidingExpiration = TimeSpan.FromMinutes(30) }; _memoryCache.Set<bool>(key, ret, memoryCacheEntryOptions); } else { _logger.LogInformation(id + " Getting config from MemoryCache: " + ret.ToString()); } return ret; }
Startup.cs中的依赖注入部分:
/**Here is part of my dependency injection on Startup.CS file:**/ services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.SetMinimumLevel((LogLevel)((int) logLevel)); loggingBuilder.AddSerilog(); }) .AddSingleton(Configuration) .AddMemoryCache() .....
我怀疑SlidingExpiration是否被AWS环境的某些设置或策略覆盖,请问有人知道缓存项无法在内存中保留超过5分钟的原因吗?
回答
这跟SlidingExpiration或缓存配置被覆盖无关,核心原因是AWS Lambda的容器生命周期机制:
- Lambda执行代码时会启动一个专用容器,请求处理完成后,容器会被保留一段时间(AWS未明确固定时长,但通常空闲状态下约5分钟后会被回收)。一旦容器被回收,内存中的所有数据(包括
IMemoryCache的缓存项)都会被彻底清空。 - 本地环境中进程持续运行,缓存可以严格遵循你设置的过期规则;但Lambda中,缓存的实际有效期完全绑定容器的存活时间——如果容器在5分钟后被回收,哪怕你设置了60分钟的绝对过期时间,缓存也会同步丢失。
解决方案
改用分布式缓存:如果需要持久化、跨容器的缓存能力,推荐使用AWS原生的分布式缓存服务:
- ElastiCache(Redis/Memcached):专为缓存场景优化,支持自定义过期策略,完全独立于Lambda容器生命周期。
- DynamoDB:可作为低成本缓存层,通过TTL(Time To Live)属性实现缓存自动过期,数据不会随Lambda容器回收丢失。
优化内存缓存的使用(仅适用于短期复用场景):
- 接受内存缓存仅在容器存活期间有效,可将缓存的绝对过期时间设置为略低于容器的预期存活窗口(比如4分钟),避免缓存还未到过期时间就随容器被回收。
- 修复代码中的异步阻塞问题:
_myRepository.GetAsync(id, config_id).Result会阻塞线程,建议改为await _myRepository.GetAsync(id, config_id),避免潜在的性能瓶颈和死锁风险。
容器预热(不推荐长期使用):可以通过定时发送预热请求延长容器存活时间,但这种方式会增加额外成本,仅适合特定临时场景。
内容的提问来源于stack exchange,提问作者Itamar Ribeiro
相关产品推荐
相关产品推荐

