-
-
Notifications
You must be signed in to change notification settings - Fork 80
feat(caching): introduce FusionCache for flexible L1/L2 caching #914
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
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
5e00fa3
feat: add FusionCache for resource watcher to enable L1 and L2 cachin…
kimpenhaus 6d8def6
refactor: optimize resource watcher cache handling and remove redunda…
kimpenhaus 3d2e607
refactor: enhance resource watcher cache configuration and logging scope
kimpenhaus f184048
refactor: rename cache extension methods and adjust visibility
kimpenhaus 9bcf9c0
Merge branch 'buehler:main' into entity_cache
kimpenhaus 5e4de87
refactor: update cache key prefix in `CacheExtensions` to use `CacheC…
kimpenhaus a8f2ba3
Merge remote-tracking branch 'origin/entity_cache' into entity_cache
kimpenhaus 8ce68a8
docs: add caching documentation and adjust sidebar positions
kimpenhaus 2a6f4fc
docs: enhance caching documentation with configuration examples and F…
kimpenhaus 6623e28
Merge branch 'main' into entity_cache
buehler File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
--- | ||
title: Caching | ||
description: Caching - Memory and Distributed | ||
sidebar_position: 7 | ||
--- | ||
|
||
## ResourceWatcher | ||
|
||
The `ResourceWatcher` uses a cache instance to store the `.metadata.generation` value of each observed resource. | ||
The key for the cache entry is the resource's unique ID (`metadata.uid`). | ||
|
||
The primary purpose of the cache is to skip reconciliation cycles for events that do not represent an actual change to a resource's specification (`.spec`). | ||
|
||
1. **`MODIFIED` Event Type**: | ||
- Kubernetes only increments the `.metadata.generation` value of a resource when its specification (`.spec`) changes. | ||
Updates to status fields (`.status`), while also triggering a `MODIFIED` event, do not increase the `generation`. | ||
- When a `MODIFIED` event arrives, the `ResourceWatcher` compares the `generation` of the incoming resource with the value stored in the cache. | ||
- If the new `generation` is not greater than the cached one, the reconciliation is skipped. | ||
This is a critical optimization, as status updates can occur very frequently (e.g., from other controllers) and typically do not require action from your operator. | ||
- Only when the `generation` has increased is the resource forwarded for reconciliation, and the new `generation` value is stored in the cache. | ||
|
||
2. **`ADDED` Event Type**: | ||
- On an `ADDED` event, the watcher checks if the resource is already present in the cache. | ||
- This prevents resources that the operator already knows about (e.g., after a watcher restart) from being incorrectly treated as "new" and reconciled again. | ||
|
||
3. **`DELETED` Event Type**: | ||
- When a resource is deleted, the watcher removes the corresponding entry from the cache to keep the memory clean. | ||
|
||
### Default Configuration: In-Memory (L1) Cache | ||
|
||
By default, and without any extra configuration, `KubeOps` uses a simple in-memory cache. | ||
|
||
- **Advantages**: | ||
- Requires zero configuration. | ||
- Very fast, as all data is held in the operator pod's memory. | ||
|
||
- **Disadvantages**: | ||
- The cache is volatile. If the pod restarts, all stored `generation` values are lost, leading to a full reconciliation of all observed resources. | ||
|
||
### Advanced Configuration: Distributed (L2) Cache | ||
|
||
For robust use in production or HA environments, it could be essential to extend cache with a distributed L2 cache and a backplane. | ||
This ensures that all operator instances share a consistent state. | ||
A common setup for this involves using [**Redis**](https://github.com/redis/redis). | ||
|
||
### FusionCache | ||
|
||
KubeOps utilizes [`FusionCache`](https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/AGentleIntroduction.md) for seamless support of an L1/L2 cache. | ||
Via `OperatorSettings.ConfigureResourceWatcherEntityCache`, an `Action` is provided that allows extending the standard configuration or | ||
overwriting it with a customized version. | ||
|
||
Here is an example of what a customized configuration with an L2 cache could look like: | ||
|
||
```csharp | ||
builder | ||
.Services | ||
.AddKubernetesOperator(settings => | ||
{ | ||
settings.Name = OperatorName; | ||
settings.ConfigureResourceWatcherEntityCache = | ||
cacheBuilder => | ||
cacheBuilder | ||
.WithCacheKeyPrefix($"{CacheConstants.CacheNames.ResourceWatcher}:") | ||
.WithSerializer(_ => new FusionCacheSystemTextJsonSerializer()) | ||
.WithRegisteredDistributedCache() | ||
.WithDefaultEntryOptions(options => | ||
options.Duration = TimeSpan.MaxValue); | ||
}) | ||
``` | ||
|
||
For an overview of all of FusionCache's features, we refer you to the corresponding documentation: | ||
|
||
https://github.com/ZiggyCreatures/FusionCache/blob/main/docs/CacheLevels.md |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
{ | ||
"position": 8, | ||
"position": 9, | ||
"label": "Testing", | ||
"collapsible": true, | ||
"collapsed": true | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using KubeOps.Abstractions.Builder; | ||
using KubeOps.Operator.Constants; | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
using ZiggyCreatures.Caching.Fusion; | ||
|
||
namespace KubeOps.Operator.Builder; | ||
|
||
/// <summary> | ||
/// Provides extension methods for configuring caching related to the operator. | ||
/// </summary> | ||
internal static class CacheExtensions | ||
{ | ||
/// <summary> | ||
/// Configures resource watcher caching for the given service collection. | ||
/// Adds a FusionCache instance for resource watchers and applies custom or default cache configuration. | ||
/// </summary> | ||
/// <param name="services">The service collection to add the resource watcher caching to.</param> | ||
/// <param name="settings"> | ||
/// The operator settings that optionally provide a custom configuration for the resource watcher entity cache. | ||
/// </param> | ||
/// <returns>The modified service collection with resource watcher caching configured.</returns> | ||
internal static IServiceCollection WithResourceWatcherEntityCaching(this IServiceCollection services, OperatorSettings settings) | ||
{ | ||
var cacheBuilder = services | ||
.AddFusionCache(CacheConstants.CacheNames.ResourceWatcher); | ||
|
||
if (settings.ConfigureResourceWatcherEntityCache != default) | ||
{ | ||
settings.ConfigureResourceWatcherEntityCache(cacheBuilder); | ||
} | ||
else | ||
{ | ||
cacheBuilder | ||
.WithOptions(options => | ||
{ | ||
options.CacheKeyPrefix = $"{CacheConstants.CacheNames.ResourceWatcher}:"; | ||
options.DefaultEntryOptions | ||
.SetDuration(TimeSpan.MaxValue); | ||
}); | ||
} | ||
|
||
return services; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace KubeOps.Operator.Constants; | ||
|
||
/// <summary> | ||
/// Provides constant values used for caching purposes within the operator. | ||
/// </summary> | ||
public static class CacheConstants | ||
{ | ||
/// <summary> | ||
/// Contains constant values representing names used within the operator's caching mechanisms. | ||
/// </summary> | ||
public static class CacheNames | ||
{ | ||
/// <summary> | ||
/// Represents a constant string used as a name for the resource watcher | ||
/// in the operator's caching mechanisms. | ||
/// </summary> | ||
public const string ResourceWatcher = "ResourceWatcher"; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.