Distributed cache implementation of IDistributedCache using PostgreSQL.
A distributed cache is a cache shared by multiple app servers, typically maintained as an external service to the app servers that access it. A distributed cache can improve the performance and scalability of an ASP.NET Core app, especially when the app is hosted by a cloud service or a server farm.
You can read more about distributed caching here.
Add a reference to the RafaelKallis.Extensions.Caching.Postgres package.
dotnet add package RafaelKallis.Extensions.Caching.Postgres
The following code enables the Postgres Cache in your application:
builder.Services.AddDistributedPostgresCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("Database");
options.SchemaName = "public";
options.TableName = "__CacheEntries";
});
The following options are available:
ConnectionString
: The connection string to the PostgreSQL database.SchemaName
("public"
): The schema name where the cache table is located.TableName
("__CacheEntries"
): The name of the cache table.MigrationsHistoryTableName
("__CacheMigrationsHistory"
): The name of the cache table.Owner
("CURRENT_USER"
): The owner of the cache table.KeyMaxLength
(1024
): The maximum length of the cache key.UsePreparedStatements
(true
): Whether to use prepared statements for cache operations.MigrateOnStart
(true
): Whether to automatically migrate the database on application start.UseUnloggedTable
(false
): Whether to create the cache table as an unlogged table.DefaultSlidingExpiration
(20 minutes
): The default sliding expiration for cache entries.GarbageCollectionInterval
(30 minutes
): The interval at which the garbage collection runs.
If you are using PgBouncer as a connection pooler with the transaction pooling mode, some additional configuration is required.
If you are using pgbouncer version 1.21 or later:
- Set the
max_prepared_transactions
to a value greater than 0 in your PgBouncer configuration. - Add
No Reset On Close=true;
to your connection string.
For older PgBouncer versions:
- Set
UsePreparedStatements
tofalse
in the Postgres Cache configuration.
Additional references for PgBouncer configuration:
- PgBouncer
max prepared statements
Documentation - Npgsql PgBouncer Documentation
- Postgres Release Announcement
- Google Results
Make sure the connection string contains No Reset On Close=true
.
OpenTelemetry is a widely-adopted framework for distributed observability across many languages and components. Its tracing standards allow applications and libraries to emit information on activities and events, which can be exported by the application, stored and analyzed. Activities typically have start and end times, and can encompass other activities recursivelyr. This allows you to analyze e.g. exactly how much time was spent in the database when handling a certain HTTP call.
Add a reference to the RafaelKallis.Extensions.Caching.Postgres.OpenTelemetry package.
dotnet add package RafaelKallis.Extensions.Caching.Postgres.OpenTelemetry
The following code enables the OpenTelemetry instrumentation for the Postgres Caching in your application:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddDistributedPostgresCacheInstrumentation()
.AddConsoleExporter())
.WithMetrics(metrics => metrics
.AddDistributedPostgresCacheInstrumentation()
.AddConsoleExporter());
Name | Description | Units | Instrument Type | Value Type | Attributes |
---|---|---|---|---|---|
cache.operation.count |
The number of cache operations | {operation} | Counter | Int64 | cache.operation.type (get , set , refresh , remove ); cache.operation.key |
cache.operation.duration |
The duration of cache operations | s | Histogram | Int64 | cache.operation.type (get , set , refresh , remove ), cache.operation.key |
cache.operation.io |
The amount of bytes read and written during cache operations | By | Histogram | Int64 | cache.operation.type (get , set , refresh , remove ), cache.operation.key |
cache.hit_ratio |
The hit ratio of the cache | ObservableGauge | Double | ||
cache.gc.count |
The number of garbage collections | {run} | Counter | Int64 | |
cache.gc.duration |
The duration of garbage collections | s | Histogram | Int64 | |
cache.gc.removed_entries |
The number of entries that were removed during garbage collection, due to expiration | {entry} | Histogram | Int64 |
Health checks are typically used with an external monitoring service or container orchestrator to check the status of an app. Before adding health checks to an app, decide on which monitoring system to use. The monitoring system dictates what types of health checks to create and how to configure their endpoints.
Add a reference to the RafaelKallis.Extensions.Caching.Postgres.HealthChecks package.
dotnet add package RafaelKallis.Extensions.Caching.Postgres.HealthChecks
The following code enables the health checks for the Postgres Cache in your application:
builder.Services.AddHealthChecks()
.AddDistributedPostgresCacheHealthCheck(options =>
{
options.DegradedTimeout = TimeSpan.FromMilliseconds(500);
options.UnhealthyTimeout = TimeSpan.FromSeconds(30);
});