Redis错误爆发

3
我们最近为分布式锁专门创建了一个名为Standard 1 GB的Azure Redis缓存,该缓存与我们的主Redis缓存分离。这样做是为了改善我们的主Redis缓存的稳定性,这一直是一个长期存在的问题,而此举似乎在很大程度上有所帮助。
在我们的新缓存中,我们观察到每1-3天内同一时间突然出现约100个错误。这些错误可能是以下两种之一:No connection is available to service this operation(StackExchange.Redis错误)或者Could not acquire distributed lock: Conflicted(RedLock.net错误)。
由于这些错误来自不同的程序包,我怀疑Redis缓存本身就是问题所在。在此期间,没有任何统计数据看起来异常,并且工作量应该适合标准的1GB大小。
我猜测这可能是网络性能 Low 的广告所引起的,这是可能的原因吗?
2个回答

2

你的理论听起来很有道理。

检查网络带宽不足

这里有一个方便的表格显示了各种定价层次的最大观测带宽。查看你的SKU的观察到的最大带宽,然后转到Azure门户中的Redis选项卡并选择指标。设置聚合到最大值,并查看缓存读取和缓存写入的总和。这是消耗的总带宽。将这两个总和叠加在出现错误的时间段上,看看问题是否是网络吞吐量。如果是这种情况,请扩展规模。

检查服务器负载

在指标选项卡上还可以查看服务器负载。这是Redis忙碌的百分比,无法处理请求。如果达到100%,Redis无法响应新请求,并且您将遇到超时问题。如果是这种情况,请扩展规模。

重复使用ConnectionMultiplexer

如果您每个请求都启动StackExchange.Redis.ConnectionMultiplexer的新实例,则也可能会用尽与Redis服务器的连接。基于您的SKU可用连接数的服务限制在此处的定价页面上。您可以在指标选项卡上查看是否超过了您的SKU允许的最大连接数,选择最大聚合并将连接客户端作为指标。

线程耗尽

这听起来不像是你的错误,但我会把它包含在Redis问题的这个流氓画廊中,因为它会涉及Azure Web应用程序。默认情况下,线程池将从4个线程开始,这些线程可以立即分配给工作。当你需要超过四个线程时,它们以每500ms一个线程的速率分配。因此,如果您在短时间内向Web应用程序倾销了大量请求,则可能会排队等待工作,并最终在到达Redis之前丢弃请求。要测试是否存在此问题,请转到Web应用程序的指标并选择线程,将聚合设置为最大值。如果您在短时间内看到巨大的峰值与您的麻烦相对应,则找到了罪魁祸首。解决方案包括正确使用async / await。当这对您没有帮助时,请使用ThreadPool.SetMinThreads将其设置为更高的值,最好接近或高于您在爆发期间看到的最大线程使用量。


1

Rob提供了一些很好的建议,但是希望补充一下关于流量突增和线程池设置不当的故障排除信息。请参见:Azure Cache for Redis客户端问题的故障排除

流量突增与线程池设置不当相结合可能会导致在客户端尚未消耗Redis服务器已发送的数据时出现延迟。

使用ThreadPoolLogger示例监视线程池统计信息的变化。您可以使用来自StackExchange.Redis的TimeoutException消息进行进一步调查,例如:

System.TimeoutException: Timeout performing EVAL, inst: 8, mgr: Inactive, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 64221, ar: 0,
IOCP: (Busy=6,Free=999,Min=2,Max=1000), WORKER: (Busy=7,Free=8184,Min=2,Max=8191)

请注意,在IOCP部分和WORKER部分,您有一个Busy值大于Min值。这种差异意味着您的ThreadPool设置需要调整。 您还可以看到in: 64221。这个值表示客户端的内核套接字层已经接收了64,211字节的数据,但应用程序尚未读取。这种差异通常意味着您的应用程序(例如StackExchange.Redis)没有像服务器发送数据一样快地从网络中读取数据。 您可以配置您的线程池设置,以确保您的线程池在突发情况下快速扩展。 希望您会发现这些额外的信息很有帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接