Comments (13)
@jodydonetti I will keep testing the library. Even probably will put on one of our services that run in production.
keep up with great work!
from fusioncache.
Meanwhile I published an alpha2 release, containing the change in the log level we discussed here.
from fusioncache.
@arnoldsi-vii I think you will need the backplane (it is alpha release right at this moment). #11
you can probably reduce the impact somewhat by decreasing the cache timeout on the read API so that it picks up any changed values much sooner.
from fusioncache.
Hi @arnoldsi-vii , thanks fro trying out FusionCache!
we started to get the
Unable to activate FAIL-SAFE (no entries in memory or distributed)
warning.
Thanks for pointing this out, I should probably change that logging.
Let me explain.
What seems to be an effective warning-level log entry, in reality is more like a trace-level log entry: basically it is saying "hey, I tried to see if there was a valid cache entry to eventually use as a fallback when it is needed, but I didn't find any". Thing is, this is totally fine! For example every first time you ask for a specific cache entry this would happen, since the very first time there cannot be a stale data to use.
So what I'm saying is that there's nothing to worry about.
The "problem" is that I'm using the same log level used for fail-safe activation (by default is warning, see here) even for this message (see here), whereas I should've used something different, like trace for example.
I'll change this in the next release, thanks!
Here is my code:
Looking at your code and I'm wondering if you have a reason to use 2 calls (a "get" + a "set") instead of a single GetOrSet
call, which is highly optimized and prevents things like cache stampede (see here for more info).
Also, which "get" method are you actually using? I'm asking because you wrote GetAsync
but the only "get" methods available are:
TryGetAsync
GetOrDefaultAsync
GetOrSetAsync
Which one you used?
It managed to set data on high volume of requests, but after many many misses
I'd like to understand more about this: it may be the fact you are not using the GetOrSet
method as I've said above, or maybe something else. Without the use of GetOrSet
what happens is that all the "get"s finish without finding any data (so you'll get a lot of MISS), followed by a lot of "set" calls (whereas only 1 per each key would be needed) and that is basically what a cache stampede problem is.
Try with this code:
public async Task<Data> GetDataAsync(string identifier, IdentifyBy identifyBy)
{
var cacheKey = $"Info:{identifier}:{identifyBy}";
var data = await _cache.GetOrSetAsync<Data>(
cacheKey,
_ => {
_logger.LogInformation($"Data Information was not in the cache. identifier: {identifier} by { identifyBy }");
return new Data { Id = 1 };
},
TimeSpan.FromMinutes(10)
);
return data;
}
Or, if you want an even shorter version without the logging line:
public async Task<Data> GetDataAsync(string identifier, IdentifyBy identifyBy)
{
return await _cache.GetOrSetAsync(
$"Info:{identifier}:{identifyBy}",
new Data { Id = 1 },
TimeSpan.FromMinutes(10)
);
}
Please try one of these versions and let me know.
from fusioncache.
Hi @jodydonetti,
Thank you for your response. We do using GetOrDefaultAsync
and the reason for separate Get and Set is due legacy issues that we cannot change at this point.
from fusioncache.
Ok, so to recap: because of legacy issues you cannot switch from 2 calls (a get + a set) to 1 call (GetOrSet
). But by sticking to separate get and set calls you cannot use the cache stampede prevention, therefore you will keep seeing a lot of cache MISS + some cache SET, and this is true for FusionCache, EasyCaching and every solution out there (basically without using a specific method there's no way to optimize that flow).
Having said this, is there anything else I can help you with?
PS: of course I will still update the logging message about being Unable to activate FAIL-SAFE (no entries in memory or distributed)
, since that should be trace-level and not warnign-level 👍
from fusioncache.
Hi @arnoldsi-vii can I close this issue or is there anything else I can do?
Btw I'm still intrigued to understand why you can use 2 calls (Get+Set ) but not 1 single call (GetOrSet) in your GetDataAsync(string identifier, IdentifyBy identifyBy)
method. If it's private code/reasons and you don't want to share I can understand, it's just that now I'm curious 😬
from fusioncache.
@jodydonetti long time ago we had deadlock situation when we used GetOrSet with one item required by other. It was design flow, but back then we best solution (time wise) was separate them. Now changing everything back to GetOrSet will create a lot of regression tests for us. New methods are using GetOrSet :)
from fusioncache.
@jodydonetti long time ago we had deadlock situation when we used GetOrSet with one item required by other. It was design flow, but back then we best solution (time wise) was separate them. Now changing everything back to GetOrSet will create a lot of regression tests for us. New methods are using GetOrSet :)
Got it, makes sense! And thanks for the explanation 👍
from fusioncache.
@jodydonetti I kept testing the library on 2 projects. One is updating the data, the other is API for read data.
Both connected to same Redis server.
When both applications are loaded both reading the data properly.
Now the "Save data" service is removing old Redis entry and creating a new one.
After the save process the app getting unable to activate FAIL-SAFE (no entries in memory or distributed)
, but it's not all. The Redis record is updated properly, but when second application is making an api call, it's getting the data saved in memory and not a new data that Redis contains.
Do you have an idea what might be an issue?
This is the configuration:
services.AddFusionCache(options =>
{
options.DefaultEntryOptions = new FusionCacheEntryOptions
{
// CACHE DURATION
Duration = TimeSpan.FromMinutes(15),
// FAIL-SAFE OPTIONS
IsFailSafeEnabled = true,
FailSafeMaxDuration = TimeSpan.FromHours(2),
FailSafeThrottleDuration = TimeSpan.FromSeconds(30),
// FACTORY TIMEOUTS
FactorySoftTimeout = TimeSpan.FromMilliseconds(200),
FactoryHardTimeout = TimeSpan.FromMilliseconds(1500),
// DISTRIBUTED CACHE
DistributedCacheSoftTimeout = TimeSpan.FromSeconds(1),
DistributedCacheHardTimeout = TimeSpan.FromSeconds(2),
AllowBackgroundDistributedCacheOperations = false,
// JITTERING
JitterMaxDuration = TimeSpan.FromSeconds(2)
};
// DISTIBUTED CACHE CIRCUIT-BREAKER
options.DistributedCacheCircuitBreakerDuration = TimeSpan.FromSeconds(2);
// CUSTOM LOG LEVELS
options.FailSafeActivationLogLevel = LogLevel.Warning;
options.SerializationErrorsLogLevel = LogLevel.Warning;
options.DistributedCacheSyntheticTimeoutsLogLevel = LogLevel.Warning;
options.DistributedCacheErrorsLogLevel = LogLevel.Error;
options.FactorySyntheticTimeoutsLogLevel = LogLevel.Debug;
options.FactoryErrorsLogLevel = LogLevel.Error;
});
I would like to know if anyone in the community talked same issues
from fusioncache.
@wileyveteran from my understanding the current version also supposed to sync cache
from fusioncache.
Hi @arnoldsi-vii what version are you using?
Anyway @wileyveteran is correct in saying that to have data in sync between 2 nodes (or in general 2 app instances, even in the same node) you need the backplane #11, which has been just released in alpha (see here).
To be clear, the backplane is the actual mechanism used to have different memory cache instances talk to each others to sync cache entries, so that when one is removed on one hand, it will be also removed on all the others.
Let me know if there's something I can help you with.
from fusioncache.
Hi all, just wanted to update you on the next version: I released right now the BETA2 for the next big release, which includes among other small things a big fix for the DI setup part.
This will probably be the last release before the official one.
Closing this issue since as of now I don't see anything to do here. Happy to re-open in case I'm missing something.
Thanks all.
from fusioncache.
Related Issues (20)
- [FEATURE] 🪞 Remove all usage of reflection HOT 6
- [FEATURE] Better detection of incoherent `CacheName`s options HOT 4
- [QUESTION] Can I use FusionCache only for getting data from a 2nd level (distributed) without InMemory part? HOT 5
- [FEATURE] 📢 Add `IgnoreIncomingBackplaneNotifications` options HOT 2
- [FEATURE] Improve nullable for GetOrSet with non-null factory HOT 8
- Explicitly tell the Factory that it failed HOT 9
- [FEATURE] Combination of eager refresh with distributed cache duration. HOT 5
- [FEATURE] Add a method for list all caches in IFusionCacheProvider (Ex: for dispose purposes) HOT 4
- Possibility of creation of a count variable in distributed cache HOT 2
- [FEATURE] Post factory executed event with possibility to change the cache settings before it be inserted in cache HOT 3
- Syncing different cloud instances HOT 4
- [BUG] Value is stored for longer than FailSafeMaxDuration HOT 7
- [BUG] AllowBackgroundDistributedCacheOperations serialization and cache operations seem to be happening in the foreground HOT 3
- best way to store FusionCacheEntryOptions in iConfiguration HOT 3
- Nullable `Size` option HOT 3
- [BUG] Deadlock caused by cancellation of eager refresh HOT 8
- [BUG] Slow Performance of FusionCache compared to Microsoft.Extensions.Caching.Memory.MemoryCache HOT 4
- [BUG] FailSafe max duration is somehow ignored HOT 7
- [FEATURE] Optimise dependencies by adding TFM HOT 9
- 💡 Add this project to awesome-italia-opensource HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fusioncache.