Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redis Connection across Tenants #13531

Merged
merged 18 commits into from
Apr 20, 2023
Merged

Redis Connection across Tenants #13531

merged 18 commits into from
Apr 20, 2023

Conversation

jtkech
Copy link
Member

@jtkech jtkech commented Apr 6, 2023

Fixes #12822

So here we register a host level factory allowing all tenants to share the same Redis Connection.

For now I didn't implement a connection pool, we assume that all tenants use the same config to connect to Redis, the difference being still done by prefixing the keys according to the tenant names.

For info I needed to wrap the aspnetcore RedisCache so that it doesn't dispose the shared Redis Connection each time a tenant is reloaded or released (e.g. on enabling a feature).

@ShaneCourtrille
Copy link
Contributor

We've completed a performance test against this and the results were so shocking that I'm hesitant to trust them until we get this tested in other environments. Basically, we went from 1800 connections during the performance test down to 34 connections. As a reminder, we aren't testing the multiple connection string part of this as our tenants within an environment share the same Redis server instance.

Our automation tests will be running against this tonight so we'll see what kind of results we see there tomorrow as these test out the editing side of things which isn't touched in our performance tests.

@jtkech
Copy link
Member Author

jtkech commented Apr 13, 2023

Hope it will still work but looks promising ;)

/// <summary>
/// Host level factory allowing to share a <see cref="IDatabase"/> across tenants.
/// </summary>
public sealed class RedisDatabaseFactory : IRedisDatabaseFactory, IDisposable, IAsyncDisposable
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be in Redis.Abstractions. I understand why it's there, and the OC.Infra project should not depend on Redis.

await _semaphore.WaitAsync();
try
{
_database ??= (await ConnectionMultiplexer.ConnectAsync(options)).GetDatabase();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw your comment about assuming all tenants use the same redis connection string. I wouldn't make this assumption and just create a dictionary here.

@jtkech
Copy link
Member Author

jtkech commented Apr 14, 2023

@sebastienros Okay I will do the changes this week end

Do we want it for 1.6.0?

Where do you want to define and register this host level Redis database factory?

Or maybe redefine it in the module and then use a static dictionary?

return database;
}

await _semaphore.WaitAsync();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a concurrent dictionary. Maybe use TryGetOrAdd(Lazy)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I thought about it but at some point you were not a fan of using Lazy ;)

Okay will do

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on the context, here I think it's important to not create multiple connections for the same string, so I agree with the locking, and because we have a CD I think the Lazy pattern should be used.

@jtkech jtkech merged commit 0a108d1 into main Apr 20, 2023
@jtkech jtkech deleted the jtkech/redis-connection branch April 20, 2023 22:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move Redis Connection pooling to be cross-tenant
4 participants