Skip to content

ConnectionImpl task.Result blocking on heavy load #2679

Open
@ryno1234

Description

@ryno1234

We're having issues, particularly when our server (IIS / ASP.Net 8.0) is under heavy load, where the creation of the ConnectionMultiplexer becomes a blocking thread for many other threads. Below is a screenshot from a memory dump of our production server showing that this line of code is blocking 1,700+ other threads.

image

We can seemingly get around this issue by preventing traffic from going to our server, starting our IIS site, requesting a page that interacts with Redis to almost "warm up" the Redis connection and then reenabling traffic. After that, everything seems to work fine, but if we have traffic going to the server out of the gate during the site's startup (such as after a new deployment), the creation of the multiplexer blocks about 50% of the time (sometimes it blocks, sometimes it doesn't... it all has to do with the traffic pattern).

I'm not sure if this is thread starvation or what. We're not using ConfigureAwait(false) since we're not on .Net Framework.

Here's our connection string configuration = {redactedhost:6379,syncTimeout=5000,allowAdmin=False,connectTimeout=5000,ssl=False,abortConnect=False,connectRetry=5}

We create a Singleton Multiplexer through this startup code

    public static IServiceCollection AddRedisCacheService(this IServiceCollection services)
    {
        services.TryAddSingleton<ICache, RedisCache>();

        // From AddStackExchangeRedisExtensions
        services.TryAddSingleton<IRedisClientFactory, RedisClientFactory>();
        services.TryAddSingleton<ISerializer>(new NewtonsoftSerializer(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }));
       
        services.TryAddSingleton<IRedisConnectionPoolManager, RedisConnectionPoolManager>();

        services.TryAddSingleton((provider) => provider
            .GetRequiredService<IRedisClientFactory>()
            .GetDefaultRedisClient());

        services.TryAddSingleton((provider) => provider
             // Block path is through these calls
            .GetRequiredService<IRedisClientFactory>()  
            .GetDefaultRedisClient()
            .GetDefaultDatabase());

        // Register a 'Configuration Factory' for extensions
        services.AddSingleton<IEnumerable<RedisConfiguration>>(sp => [sp.GetRequiredService<RedisConfiguration>()]);

        return services;
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions