Redis 偶尔挂起
Redis occasional hangs
我们在服务器上的 Windows 节点 运行 有一个独立的 Redis (2.8.2104)。
另外两个服务器正在与此实例通信。
我们将它与 SignalR 一起使用并用于缓存。转储的大小约为 700MB
有时我们会挂起 1-3 分钟。之后它会自行恢复。
这个错误似乎只在我们的页面上有一些流量时才会发生。
这次我们得到异常,您可以在下面看到
StackExchange.Redis.RedisConnectionException: SocketFailure on EVAL
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at Microsoft.Owin.Cors.CorsMiddleware.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
当我搜索 Redis 日志时,我偶尔会发现这些错误:
[33144] 18 Feb 18:18:44.843 #
=== REDIS BUG REPORT START: Cut & paste starting from here === [33144] 18 Feb 18:18:44.844 # Out Of Memory allocating 308457 bytes. [33144]
18 Feb 18:18:44.844 # --- ABORT [33144] 18 Feb 18:18:44.844 # ---
STACK TRACE
redis-server.exe!LogStackTrace(c:\release\redis\src\win32_interop\win32_stacktrace.cpp:95)(0x00000016,
0x042E0028, 0x00000000, 0x00000001)
redis-server.exe!AbortHandler(c:\release\redis\src\win32_interop\win32_stacktrace.cpp:206)(0x00000001,
0x89EE7767, 0x40150880, 0xBB7A5ED7)
redis-server.exe!raise(f:\dd\vctools\crt\crtw32\misc\winsig.c:587)(0x00000001,
0x00000000, 0x0004B4E9, 0x042E0028)
redis-server.exe!abort(f:\dd\vctools\crt\crtw32\misc\abort.c:82)(0x00000001,
0x4013F888, 0x0004B4E9, 0x00008000)
redis-server.exe!redisOutOfMemoryHandler(c:\release\redis\src\redis.c:3397)(0x0004B4E9,
0x4007DA07, 0x042E0028, 0x4007A27B)
redis-server.exe!zmalloc(c:\release\redis\src\zmalloc.c:147)(0xBDF01150,
0x4007EB2C, 0xBDF01150, 0x446D6B10)
redis-server.exe!sdsnewlen(c:\release\redis\src\sds.c:59)(0xBDF01150,
0xBDF01150, 0x3E74FD95, 0x00000003)
redis-server.exe!_addReplyStringToList(c:\release\redis\src\networking.c:271)(0xBDF01150,
0xBDF01150, 0x042E0028, 0x400E34FE)
redis-server.exe!addReplyBulkCBuffer(c:\release\redis\src\networking.c:517)(0xFFFFFFFF,
0x042E0028, 0x01B77260, 0x01B77260)
redis-server.exe!luaReplyToRedisReply(c:\release\redis\src\scripting.c:792)(0x00000004,
0xBDF01150, 0x00000002, 0x00000002)
redis-server.exe!luaReplyToRedisReply(c:\release\redis\src\scripting.c:839)(0xFFFFFFFF,
0x00A7F690, 0x67897B20, 0xBDF01150)
redis-server.exe!evalGenericCommand(c:\release\redis\src\scripting.c:1048)(0x71E66870,
0x00000000, 0x00000001, 0x000000B2)
redis-server.exe!call(c:\release\redis\src\redis.c:2016)(0x56C60B04,
0x4008B000, 0x00000000, 0x000000B2)
redis-server.exe!processCommand(c:\release\redis\src\redis.c:2235)(0xBDF01150,
0x000000B2, 0x000023B5, 0x00000001)
redis-server.exe!processInputBuffer(c:\release\redis\src\networking.c:1274)(0xBDF01150,
0x00000000, 0x00000000, 0x00000001)
redis-server.exe!readQueryFromClient(c:\release\redis\src\networking.c:1329)(0xFFE51650,
0x00000001, 0x44726F20, 0x0000012C)
redis-server.exe!aeMain(c:\release\redis\src\ae.c:487)(0x56C5C7F8,
0x00000002, 0x00000000, 0x00000002)
redis-server.exe!redis_main(c:\release\redis\src\redis.c:3524)(0x0024BA50,
0x00000002, 0x56C5C7EB, 0x00000002)
redis-server.exe!main(c:\release\redis\src\win32_interop\win32_qfork.cpp:1363)(0x00000016,
0xFFFFFFFF, 0x00000016, 0x0023F3A0)
redis-server.exe!ServiceWorkerThread(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0x4000B3D0,
0x00000000, 0x00000000, 0x00000000)
KERNEL32.DLL!BaseThreadInitThunk(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0xBB0113B0,
0x00000000, 0x00000000, 0x00000000)
ntdll.dll!RtlUserThreadStart(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0x00000000,
0x00000000, 0x00000000, 0x00000000)
ntdll.dll!RtlUserThreadStart(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0x00000000,
0x00000000, 0x00000000, 0x00000000) [33144] 18 Feb 18:18:44.857 #
=== REDIS BUG REPORT END. Make sure to include from START to END. ===
maxheap 设置为 3000mb
服务器总共有 64 GB RAM,大约 10GB 是免费的
还有一件事,但我不确定它是否真的解决了这个问题。
大多数时候问题会增加它的频率。然后,当我重置其中一台服务器的 iis 时,问题完全消失了几个小时或几天。我想到可能有挂起/堆叠的 signalR 队列。但我没有任何进一步的迹象表明可能是这种情况。
有什么提示吗?
我找到了与 signalR 本身无关但客户端 signalR Scaleout 正在使用的解决方案。
我发现,如果您使用默认的 Microsoft.AspNet.SignalR.Redis 包,它会包含对旧 StackExchange.Redis 客户端的私有引用。
此客户端在释放客户端连接句柄时遇到问题。现在,当重新启动 IIS 或 Redis 服务器时,所有这些句柄都将被释放,一切都会再次运行。
一个解决方案是构建自己的 signalR Scaleout 流实现
另一个(对我们来说更容易)是禁用 signalR scaleout 流。
所有其他正在访问 redis 的组件都在使用 ServiceStack.Redis,工作正常。
现在大约一个月后,我们的 Redis 服务器不再有任何问题。
我们在服务器上的 Windows 节点 运行 有一个独立的 Redis (2.8.2104)。
另外两个服务器正在与此实例通信。
我们将它与 SignalR 一起使用并用于缓存。转储的大小约为 700MB
有时我们会挂起 1-3 分钟。之后它会自行恢复。
这个错误似乎只在我们的页面上有一些流量时才会发生。
这次我们得到异常,您可以在下面看到
StackExchange.Redis.RedisConnectionException: SocketFailure on EVAL at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Cors.CorsMiddleware.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Owin.Mapping.MapMiddleware.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at
当我搜索 Redis 日志时,我偶尔会发现这些错误:
[33144] 18 Feb 18:18:44.843 #
=== REDIS BUG REPORT START: Cut & paste starting from here === [33144] 18 Feb 18:18:44.844 # Out Of Memory allocating 308457 bytes. [33144] 18 Feb 18:18:44.844 # --- ABORT [33144] 18 Feb 18:18:44.844 # --- STACK TRACE redis-server.exe!LogStackTrace(c:\release\redis\src\win32_interop\win32_stacktrace.cpp:95)(0x00000016, 0x042E0028, 0x00000000, 0x00000001) redis-server.exe!AbortHandler(c:\release\redis\src\win32_interop\win32_stacktrace.cpp:206)(0x00000001, 0x89EE7767, 0x40150880, 0xBB7A5ED7) redis-server.exe!raise(f:\dd\vctools\crt\crtw32\misc\winsig.c:587)(0x00000001, 0x00000000, 0x0004B4E9, 0x042E0028) redis-server.exe!abort(f:\dd\vctools\crt\crtw32\misc\abort.c:82)(0x00000001, 0x4013F888, 0x0004B4E9, 0x00008000) redis-server.exe!redisOutOfMemoryHandler(c:\release\redis\src\redis.c:3397)(0x0004B4E9, 0x4007DA07, 0x042E0028, 0x4007A27B) redis-server.exe!zmalloc(c:\release\redis\src\zmalloc.c:147)(0xBDF01150, 0x4007EB2C, 0xBDF01150, 0x446D6B10) redis-server.exe!sdsnewlen(c:\release\redis\src\sds.c:59)(0xBDF01150, 0xBDF01150, 0x3E74FD95, 0x00000003) redis-server.exe!_addReplyStringToList(c:\release\redis\src\networking.c:271)(0xBDF01150, 0xBDF01150, 0x042E0028, 0x400E34FE) redis-server.exe!addReplyBulkCBuffer(c:\release\redis\src\networking.c:517)(0xFFFFFFFF, 0x042E0028, 0x01B77260, 0x01B77260) redis-server.exe!luaReplyToRedisReply(c:\release\redis\src\scripting.c:792)(0x00000004, 0xBDF01150, 0x00000002, 0x00000002) redis-server.exe!luaReplyToRedisReply(c:\release\redis\src\scripting.c:839)(0xFFFFFFFF, 0x00A7F690, 0x67897B20, 0xBDF01150) redis-server.exe!evalGenericCommand(c:\release\redis\src\scripting.c:1048)(0x71E66870, 0x00000000, 0x00000001, 0x000000B2) redis-server.exe!call(c:\release\redis\src\redis.c:2016)(0x56C60B04, 0x4008B000, 0x00000000, 0x000000B2) redis-server.exe!processCommand(c:\release\redis\src\redis.c:2235)(0xBDF01150, 0x000000B2, 0x000023B5, 0x00000001) redis-server.exe!processInputBuffer(c:\release\redis\src\networking.c:1274)(0xBDF01150, 0x00000000, 0x00000000, 0x00000001) redis-server.exe!readQueryFromClient(c:\release\redis\src\networking.c:1329)(0xFFE51650, 0x00000001, 0x44726F20, 0x0000012C) redis-server.exe!aeMain(c:\release\redis\src\ae.c:487)(0x56C5C7F8, 0x00000002, 0x00000000, 0x00000002) redis-server.exe!redis_main(c:\release\redis\src\redis.c:3524)(0x0024BA50, 0x00000002, 0x56C5C7EB, 0x00000002) redis-server.exe!main(c:\release\redis\src\win32_interop\win32_qfork.cpp:1363)(0x00000016, 0xFFFFFFFF, 0x00000016, 0x0023F3A0) redis-server.exe!ServiceWorkerThread(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0x4000B3D0, 0x00000000, 0x00000000, 0x00000000) KERNEL32.DLL!BaseThreadInitThunk(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0xBB0113B0, 0x00000000, 0x00000000, 0x00000000) ntdll.dll!RtlUserThreadStart(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0x00000000, 0x00000000, 0x00000000, 0x00000000) ntdll.dll!RtlUserThreadStart(c:\release\redis\src\win32_interop\win32_service.cpp:485)(0x00000000, 0x00000000, 0x00000000, 0x00000000) [33144] 18 Feb 18:18:44.857 # === REDIS BUG REPORT END. Make sure to include from START to END. ===
maxheap 设置为 3000mb 服务器总共有 64 GB RAM,大约 10GB 是免费的
还有一件事,但我不确定它是否真的解决了这个问题。
大多数时候问题会增加它的频率。然后,当我重置其中一台服务器的 iis 时,问题完全消失了几个小时或几天。我想到可能有挂起/堆叠的 signalR 队列。但我没有任何进一步的迹象表明可能是这种情况。
有什么提示吗?
我找到了与 signalR 本身无关但客户端 signalR Scaleout 正在使用的解决方案。
我发现,如果您使用默认的 Microsoft.AspNet.SignalR.Redis 包,它会包含对旧 StackExchange.Redis 客户端的私有引用。
此客户端在释放客户端连接句柄时遇到问题。现在,当重新启动 IIS 或 Redis 服务器时,所有这些句柄都将被释放,一切都会再次运行。
一个解决方案是构建自己的 signalR Scaleout 流实现
另一个(对我们来说更容易)是禁用 signalR scaleout 流。
所有其他正在访问 redis 的组件都在使用 ServiceStack.Redis,工作正常。
现在大约一个月后,我们的 Redis 服务器不再有任何问题。