I'm struggling to work out what this error message from the Stack Exchange Redis client is telling me:
Unhandled Exception: System.AggregateException: One or more errors
occurred. (Timeout awaiting response (outbound=0KiB, inbound=0KiB,
32516ms elapsed, timeout is 30000ms), inst: 0, qu: 0, qs: 1, in: 0,
serverEndpoint: Unspecified/XXX:6379, mgr: 9 of
10 available, clientName: YYY, IOCP:
(Busy=0,Free=1000,Min=2,Max=1000), WORKER:
(Busy=1025,Free=31742,Min=1024,Max=32767), v: 2.0.571.20511 (Please
take a look at this article for some common client-side issues that
can cause timeouts:
https://stackexchange.github.io/StackExchange.Redis/Timeouts)) --->
StackExchange.Redis.RedisTimeoutException: Timeout awaiting response
(outbound=0KiB, inbound=0KiB, 32516ms elapsed, timeout is 30000ms),
inst: 0, qu: 0, qs: 1, in: 0, serverEndpoint:
Unspecified/XXX:6379, mgr: 9 of 10 available,
clientName: YYY, IOCP: (Busy=0,Free=1000,Min=2,Max=1000),
WORKER: (Busy=1025,Free=31742,Min=1024,Max=32767), v: 2.0.571.20511
(Please take a look at this article for some common client-side issues
that can cause timeouts:
https://stackexchange.github.io/StackExchange.Redis/Timeouts
I'm using this code to select the least loaded connection multiplexer and back off, but I'm still getting timeouts when firing a large number of string set commands.
public class RedisConnectionManager : IRedisConnectionManager
{
private const int MaxQueueLength = 10;
private readonly List<Lazy<ConnectionMultiplexer>> _connectionMultiplexers;
public RedisConnectionManager(List<Lazy<ConnectionMultiplexer>> connectionMultiplexers)
{
this._connectionMultiplexers = connectionMultiplexers;
}
public async Task<ConnectionMultiplexer> GetLeastBusyConnectionAsync()
{
var leastBusyConnection = this._connectionMultiplexers.OrderBy(connection => connection.Value.GetCounters().Interactive.TotalOutstanding).First();
await WaitUntilConnectionAvailableAsync(leastBusyConnection);
return this._connectionMultiplexers.OrderBy(connection => connection.Value.GetCounters().Interactive.TotalOutstanding).First().Value;
}
private static async Task WaitUntilConnectionAvailableAsync(Lazy<ConnectionMultiplexer> leastBusyConnection)
{
while (leastBusyConnection.Value.GetCounters().Interactive.TotalOutstanding > MaxQueueLength)
{
await Task.Delay(100);
}
}
}
There are several answers on SO over regarding this.
In your particular case, it looks like the issue with ThreadPool throtlling, where busy threads are 1025 which are more than Min configured 1024 threads.
WORKER: (Busy=1025,Free=31742,Min=1024,Max=32767)
Have a look here, however beware of the other server performance consequences (depending on your use case) as mentioned in the article.
https://gist.github.com/JonCole/e65411214030f0d823cb#file-threadpool-md
Related
.NET 7.0 and StackExchange.Redis version=2.6.70.
I am facing this error when the cache is on the server but not when running locally with the cache in container on my machine.
StackExchange.Redis.RedisTimeoutException: Timeout performing PSETEX (5000ms),
inst: 0,
qu: 1,
qs: 0,
aw: False,
bw: SpinningDown,
rs: NotStarted,
ws: Idle,
in: 0,
serverEndpoint: 0.0.24.235:6379,
mc: 1/1/0,
mgr: 10 of 10 available,
clientName: 6fe450d7aad5(SE.Redis-v2.6.70.49541),
IOCP: (Busy=0,Free=1000,Min=1,Max=1000),
WORKER: (Busy=1,Free=32766,Min=32,Max=32767),
POOL: (Threads=5,QueuedItems=0,CompletedItems=279236),
v: 2.6.70.49541 (Please take a look at this article for some common client-side issues that can
cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)\n at
StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1
processor, ServerEndPoint server, T defaultValue) in
//src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1887\n at
StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor`1 processor,
ServerEndPoint server, T defaultValue) in //src/StackExchange.Redis/RedisBase.cs:line 62\n at
StackExchange.Redis.RedisDatabase.StringSet(RedisKey key, RedisValue value, Nullable`1 expiry,
Boolean keepTtl, When when, CommandFlags flags) in
/_/src/StackExchange.Redis/RedisDatabase.cs:line 3128\n at
ConfigurationManagementMicroService.Cache.CacheService.SetData[T](String key, T value,
DateTimeOffset expirationTime) in
/src/ConfigurationManagementMicroService/Cache/CacheService.cs:line 36\n
This is how I am connecting:
ConnectionHelper.lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
var config = new ConfigurationOptions()
{
EndPoints = { { ip, Convert.ToInt32(port) } },
AbortOnConnectFail = false,
};
return ConnectionMultiplexer.Connect(config);
}
Sync handshake could be an issue or big sized payload? Give analysis on this.
I'm trying to connect to the AWS Redis instance via the below c# code.
var option = new Microsoft.Extensions.Caching.StackExchangeRedis.RedisCacheOptions
{
ConfigurationOptions = ConfigurationOptions.Parse("master.test-redis-cluster.89run.use1.cache.amazonaws.com:6379,ssl=true,sslProtocols=Tls,abortConnect=false"),
InstanceName = "testapi",
};
IDistributedCache distributedCache = new RedisCache(option);
distributedCache.SetAsync("testKey", System.Text.Encoding.UTF8.GetBytes("testData"));
When I'm trying to set the value in the cache, I'm getting the below error. Though there is enough Threads, i'm getting this error.
{
"Redis-Message": "HMGET testapi1fb31d10-ebee-4f39-9a73-9bc8901461e5",
"Redis-Timeout": "5000",
"Redis-OpsSinceLastHeartbeat": "0",
"Redis-Queue-Awaiting-Write": "0",
"Redis-Queue-Awaiting-Response": "0",
"Redis-Active-Writer": "False",
"Redis-Backlog-Writer": "CheckingForTimeout",
"Redis-Server-Endpoint": "master.test-redis-cluster.89run.use1.cache.amazonaws.com:6379",
"Redis-Multiplexer-Connects": "1/1/0",
"Redis-Manager": "10 of 10 available",
"Redis-Client-Name": "testapi-app-deployment-7674cf88nnl5(SE.Redis-v2.6.70.49541)",
"Redis-ThreadPool-IO-Completion": "(Busy=0,Free=1000,Min=16,Max=1000)",
"Redis-ThreadPool-Workers": "(Busy=0,Free=32767,Min=16,Max=32767)",
"Redis-ThreadPool-Items": "(Threads=16,QueuedItems=0,CompletedItems=495)",
"Redis-Busy-Workers": "0",
"Redis-Version": "2.6.70.49541",
"redis-command": "HMGET testapi1fb31d10-ebee-4f39-9a73-9bc8901461e5",
"redis-server": "master.test-redis-cluster.89run.use1.cache.amazonaws.com:6379",
"ex_msg": "The timeout was reached before the message could be written to the output buffer, and it was not sent, command=HMGET, timeout: 5000, inst: 0, qu: 0, qs: 0, aw: False, bw: CheckingForTimeout, serverEndpoint: master.test-redis-cluster.89run.use1.cache.amazonaws.com:6379, mc: 1/1/0, mgr: 10 of 10 available, clientName: testapi-app-deployment-7674cf88nnl5(SE.Redis-v2.6.70.49541), IOCP: (Busy=0,Free=1000,Min=16,Max=1000), WORKER: (Busy=0,Free=32767,Min=16,Max=32767), POOL: (Threads=16,QueuedItems=0,CompletedItems=495), v: 2.6.70.49541 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)"
}
Not able to figure out why.
Since there is no connection error, it seems the code was able to connect to Redis. Also in error payload size is not there so again huge payload size possibility is ruled out.
Please note:
There are many similar questions in stack overflow and tried all of them. But, no luck.
We recently updated our API from .net 3.1 to 6. After this, we started to face this issue, and currently, API is not working at all. There is a sufficient number of threads and works I can see. Also we tried by increasing the timeout but again no luck.
I've implemented this second level cache for EF Core exactly as described in the readme. Tonight I ran a load test on the system with about 500 virtual users and I am getting lots of timeouts like the following below:
Azure Redis Premium 6 GB
Message: Timeout performing GET (5000ms), next: GET 8664A5E9, inst: 51, qu: 0, qs: 101, aw: False, rs: ReadAsync, ws: Idle, in: 65536, serverEndpoint: xxxxx.redis.cache.windows.net:6380, mc: 1/1/0, mgr: 10 of 10 available, clientName: RD2818785C3C7F, IOCP: (Busy=6,Free=994,Min=4,Max=1000), WORKER: (Busy=63,Free=8128,Min=4,Max=8191), v: 2.1.58.34321 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)
Relevant Startup Code
const string providerName1 = "Redis1";
services.AddEFSecondLevelCache(options =>
options.UseEasyCachingCoreProvider(providerName1, CacheExpirationMode.Absolute, TimeSpan.FromMinutes(5)).DisableLogging(true)
);
ConnectionMultiplexer.SetFeatureFlag("preventthreadtheft", true);
services.AddEasyCaching(option => {
option.UseRedis(config => {
config.DBConfig.Configuration = AppConfig.RedisConnectionString;
config.DBConfig.AllowAdmin = true;
}, providerName1);
});
private DbContextOptionsBuilder<DBContext[![enter image description here][2]][2]> GetDBConfig(IContext context) {
var optionsBuilder = new DbContextOptionsBuilder<DBContext>();
optionsBuilder.UseSqlServer(AppConfig.DatabaseConnection)
.AddInterceptors(context.GetInstance<SecondLevelCacheInterceptor>())
//.UseLoggerFactory()
.EnableSensitiveDataLogging(true);
return optionsBuilder;
}
I am trying to compose a worker verticle that will bridge Google cloud PubSub topic subscription with an event-bus of the vert.x by adopting kotlin example of PubSub combined with this answer regarding worker with an infinite blocking loop processing.
It does works but Vert.X keep nagging into the log that Thread blocked by throwing an exception sometime after the message was from PubSub was received (please ignore blocking initialization for now):
9:15:12 AM: Executing task 'run'...
WARNING: You are a using release candidate 2.0.0-rc5. Behavior of this plugin has changed since 1.3.5. Please see release notes at: https://github.com/GoogleCloudPlatform/app-gradle-plugin.
Missing a feature? Can't get it to work?, please file a bug at: https://github.com/GoogleCloudPlatform/app-gradle-plugin/issues.
:compileKotlin UP-TO-DATE
:compileJava NO-SOURCE
:processResources NO-SOURCE
:classes UP-TO-DATE
Mar 10, 2019 9:15:18 AM io.vertx.core.impl.launcher.commands.Watcher
INFO: Watched paths: [/home/username/IdeaProjects/project_name/./src]
Mar 10, 2019 9:15:18 AM io.vertx.core.impl.launcher.commands.Watcher
INFO: Starting the vert.x application in redeploy mode
:run
Starting vert.x application...
f48ba7fd-a52b-487f-b553-2b74473e58ba-redeploy
Creating topic gcs-project-id:vertx.
Mar 10, 2019 9:15:18 AM com.google.auth.oauth2.DefaultCredentialsProvider warnAboutProblematicCredentials
WARNING: Your application has authenticated using end user credentials from Google Cloud SDK. We recommend that most server applications use service accounts instead. If your application continues to use end user credentials from Cloud SDK, you might receive a "quota exceeded" or "API not enabled" error. For more information about service accounts, see https://cloud.google.com/docs/authentication/.
Mar 10, 2019 9:15:21 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 2759 ms, time limit is 2000 ms
Topic gcs-project-id:vertx successfully created.
Creating subscription gcs-project-id:kotlin.
Mar 10, 2019 9:15:22 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 3759 ms, time limit is 2000 ms
Mar 10, 2019 9:15:23 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 4758 ms, time limit is 2000 ms
Mar 10, 2019 9:15:24 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-eventloop-thread-0,5,main] has been blocked for 5759 ms, time limit is 2000 ms
io.vertx.core.VertxException: Thread blocked
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:469)
at com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly(Uninterruptibles.java:142)
at com.google.common.util.concurrent.Futures.getUnchecked(Futures.java:1309)
at com.google.api.gax.rpc.ApiExceptions.callAndTranslateApiException(ApiExceptions.java:52)
at com.google.api.gax.rpc.UnaryCallable.call(UnaryCallable.java:112)
at com.google.cloud.pubsub.v1.SubscriptionAdminClient.createSubscription(SubscriptionAdminClient.java:359)
at com.google.cloud.pubsub.v1.SubscriptionAdminClient.createSubscription(SubscriptionAdminClient.java:260)
at com.example.project.MainVerticle.subscribeTopic(MainVerticle.kt:76)
at com.example.project.MainVerticle.init(MainVerticle.kt:46)
at io.vertx.core.impl.DeploymentManager.lambda$doDeploy$8(DeploymentManager.java:492)
at io.vertx.core.impl.DeploymentManager$$Lambda$28/1902260856.handle(Unknown Source)
at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:320)
at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38)
at io.vertx.core.impl.EventLoopContext$$Lambda$29/1640639994.run(Unknown Source)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:462)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:897)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Subscription gcs-project-id:kotlin successfully created.
Listening to messages on kotlin:
Mar 10, 2019 9:15:25 AM io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer
INFO: Succeeded in deploying verticle
Message Id: 462746807438186 Data: Bazinga
Message Id: 462746750387788 Data: Another message
Mar 10, 2019 9:16:25 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-worker-thread-0,5,main] has been blocked for 60171 ms, time limit is 60000 ms
io.vertx.core.VertxException: Thread blocked
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:492)
at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:680)
at com.example.project.MainVerticle$start$1.handle(MainVerticle.kt:32)
at com.example.project.MainVerticle$start$1.handle(MainVerticle.kt:13)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:272)
at io.vertx.core.impl.ContextImpl$$Lambda$33/1101004004.run(Unknown Source)
at io.vertx.core.impl.TaskQueue.run(TaskQueue.java:76)
at io.vertx.core.impl.TaskQueue$$Lambda$26/1213216872.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Mar 10, 2019 9:16:26 AM io.vertx.core.impl.BlockedThreadChecker
WARNING: Thread Thread[vert.x-worker-thread-0,5,main] has been blocked for 61172 ms, time limit is 60000 ms
io.vertx.core.VertxException: Thread blocked
at sun.misc.Unsafe.park(Native Method)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:492)
at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:680)
at com.example.project.MainVerticle$start$1.handle(MainVerticle.kt:32)
at com.example.project.MainVerticle$start$1.handle(MainVerticle.kt:13)
at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:272)
at io.vertx.core.impl.ContextImpl$$Lambda$33/1101004004.run(Unknown Source)
at io.vertx.core.impl.TaskQueue.run(TaskQueue.java:76)
at io.vertx.core.impl.TaskQueue$$Lambda$26/1213216872.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
And here is source-code:
package com.example.project_name
import com.google.api.gax.rpc.ApiException
import com.google.cloud.pubsub.v1.*
import com.google.pubsub.v1.ProjectSubscriptionName
import com.google.pubsub.v1.ProjectTopicName
import com.google.pubsub.v1.PubsubMessage
import com.google.pubsub.v1.PushConfig
import io.vertx.core.*
import java.util.concurrent.LinkedBlockingDeque
class MainVerticle : MessageReceiver, AbstractVerticle() {
private val projectId = "gcs-project-id"
private val topicId = "vertx"
private val topic: ProjectTopicName = ProjectTopicName.of(projectId, topicId)
private val subscriptionId = "kotlin"
private val subscription = ProjectSubscriptionName.of(projectId, subscriptionId)
private val messages = LinkedBlockingDeque<PubsubMessage>()
private lateinit var subscriber: Subscriber
override fun receiveMessage(message: PubsubMessage, consumer: AckReplyConsumer) {
messages.offer(message)
consumer.ack()
}
override fun start() {
vertx.executeBlocking<Void>({
try {
println("Listening to messages on $subscriptionId:")
subscriber.awaitRunning()
while (true) {
val message = messages.take()
println("Message Id: ${message.messageId} Data: ${message.data.toStringUtf8()}")
}
} finally {
subscriber.stopAsync()
it.complete()
}
}, { println("done, ${it.cause()}") })
}
override fun init(vertx: Vertx?, context: Context?) {
super.init(vertx, context)
try {
createTopic()
subscribeTopic()
subscriber = Subscriber.newBuilder(subscription, this).build()
subscriber.startAsync()
} catch (e: ApiException) {
// example : code = ALREADY_EXISTS(409) implies topic already exists
println("Failed: $e")
}
}
override fun stop(stopFuture: Future<Void>?) {
super.stop(stopFuture)
try {
deleteSub()
deleteTopic()
} catch (e: ApiException) {
println("Failed: $e")
} finally {
subscriber.stopAsync()
stopFuture!!.complete()
}
}
private fun createTopic() { // expects 1 arg: <topic> to create
println("Creating topic ${topic.project}:${topic.topic}.")
TopicAdminClient.create().use { topicAdminClient -> topicAdminClient.createTopic(topic) }
println("Topic ${topic.project}:${topic.topic} successfully created.")
}
private fun subscribeTopic() { // expects 2 args: <topic> and <subscription>
println("Creating subscription ${subscription.project}:${subscription.subscription}.")
SubscriptionAdminClient.create().use { it.createSubscription(subscription, topic, PushConfig.getDefaultInstance(), 0) }
println("Subscription ${subscription.project}:${subscription.subscription} successfully created.")
}
private fun deleteTopic() {
println("Deleting topic ${topic.project}:${topic.topic}.")
TopicAdminClient.create().use { it.deleteTopic(topic) }
println("Topic ${topic.project}:${topic.topic} successfully deleted.")
}
private fun deleteSub() { // expects 1 arg: <subscription> to delete
println("Deleting subscription ${subscription.project}:${subscription.subscription}.")
SubscriptionAdminClient.create().use { it.deleteSubscription(subscription) }
println("Subscription ${subscription.project}:${subscription.subscription} successfully deleted.")
}
}
fun main(vararg args: String) {
Vertx.vertx().deployVerticle(MainVerticle(), DeploymentOptions().apply {
isWorker = true
})
}
I am clearly missing something. Also if you have a better approach that can integrate/unify Google’s PubSub library (that has its own async loop) with Vert.X I’d be happy to hear over my primitive example approach.
The problem is with your while loop.
"Blocking" in this case does not mean that you can just keep running forever.
Your call to it.complete() is never reached, and at some point Vert.x will complain about that.
See the manual on Running blocking code, specifically the WARNING section.
To solve your problem, you will need to schedule your calls to messages.take() in one way or another, for example using setPeriodic. Inside the interval handler, empty your queue with executeBlocking, then give back control by calling complete(), either before or after you have scheduled the processing of the messages, depending if you care about the result.
I am trying to join a KNX multicast group (ip: 224.0.23.12; port:3671) but receive an OtherIoError.
The socket connection appears OK since I can send to the multicast group (checked by Wireshark). To be sure, I tested with only one network interface activated and tried to replace the local_addr with 127.0.0.1 as well as the local IP address. My Rust version is 0.13.0-nightly (5ba610265 2014-12-25 18:01:36 +0000) running on Windows 7 (64bit).
Similar code works in Go as well with other software joining this multicast group.
use std::io::net::udp::UdpSocket;
use std::io::net::ip::{Ipv4Addr, SocketAddr};
fn main() {
let local_addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 3671 };
let mut socket = match UdpSocket::bind(local_addr) {
Ok(s) => s,
Err(e) => panic!("couldn't bind socket: {}", e),
};
match socket.join_multicast(Ipv4Addr(224, 0, 23, 12)) {
Err(why) => println!("! {}", why.kind),
Ok(_) => {},
};
drop(socket)
}
Ok, I think this is a bug in Rust.
This Microsoft KB says:
Note that this includes Winsock.h. If the project is linked with Ws2_32.lib, setsockopt will fail with runtime error 10042 (WSAENOPROTOOPT). This is because in Winsock.h, IP_ADD_MEMBERSHIP is defined as "5". The corresponding Winsock runtime can not resolve option 5 at the IPPROTO_IP level, so the failure occurs with error code 10042.
The Rust constants are defined as 5 and 6, so perhaps someone grabbed the wrong constants from somewhere? I'll probably file an official Rust bug for this.