使用Azure Redis缓存时如何处理故障转移和陈旧数据



我开始在我的项目中使用分布式Azure Redis缓存

下面是我的启动配置:

if (cacheEnvironmentLocal.HasValue && cacheEnvironmentLocal.Value)
{
services.AddDistributedMemoryCache();
}
else
{              
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = cacheConnectionString;
});
}

我使用AddStackExchangeRedisCache,它已经有默认的重试和超时策略,所以这是好的。

据我所知,它还实现了ForceReconnect,以便在出现问题时重新创建连接。

我正在使用Azure Redis的标准层,这意味着我有两个节点(主节点和副本节点),很明显,在大多数情况下,其中一个会工作,但在一些更大的问题(一些硬件或网络问题导致缓存不可用一段时间)可能会失败。

我担心的假设性例子:

当缓存关闭时,我试图从缓存中删除一些东西,但我得到一个异常,并继续我的代码。

但是当缓存恢复运行时,缓存中有过时的数据。

下次我尝试获取这个值时,它将是一个旧的值,应用程序将会表现得很奇怪。

Get和Set这是ok的,因为如果缓存不工作,我将捕获异常并继续,但删除是问题,因为缓存中的数据是陈旧的。

下面是我的remove函数的代码:
/// <summary>
/// Removes the object from the cache.
/// </summary>
/// <typeparam name="T">Type of the vaule.</typeparam>
/// <param name="id">Id of the object.</param>
public void Remove<T>(string id)
where T : class
{
var key = GenerateKey(id, GetTypeName<T>());
if (string.IsNullOrEmpty(key))
{
logger.Warning("Id or type for the cache were not provided properly");
return;
}
try
{
distributedCache.Remove(key);
}
catch(Exception e)
{
logger.Error(new CacheException(Error_02.CacheRemoveFailed, e));
}
}

现在我捕获了可能的异常并继续。对于get和set,我也这样做。

我读过但找不到答案的文章:

  • https://learn.microsoft.com/en-gb/azure/azure-cache-for-redis/cache-failover how-do-i-make-my-application-resilient

    https://learn.microsoft.com/en-us/azure/architecture/framework/resiliency/reliability-patterns弹性

    https://learn.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific azure-cache-for-redis

    https://learn.microsoft.com/en-gb/azure/azure-cache-for-redis/cache-best-practices-connection using-forcereconnect-with-stackexchangeredis

    https://learn.microsoft.com/en-gb/azure/azure-cache-for-redis/cache-configure memory-policies

    https://learn.microsoft.com/en-gb/azure/azure-cache-for-redis/cache-administration重启

我的问题是

是否有一种方法来清除缓存(FLUSHDB)编程时,这样的问题发生,所以当缓存又回来了,我有一个干净的板?

虽然没有内置功能,但您可以将其作为代码的一部分实现,或者使用外部服务来实现。

理想情况下,对于您提到的场景,您应该重试键删除,而不是继续或排队删除,以确保一致性,同时不阻塞执行。

根据你分享的代码,你的缓存实现可以让get操作在出现时返回值或错误时返回null,而其他操作,如updatedelete,可以将操作排队并在旁边处理它们。这个单独的线程可以根据需要等待和处理失败。

根据您的场景,您还可以设置键在一定时间后过期,这将确保它们被删除,并确保您的应用程序获取最新的值。

最新更新