The past days I've been working with Azure Caching. Good practice is to use the local cache functionality to prevent roundtrips to the distributed cache.
As can be read in the documentation; when you make a call to dataCache.Get(...), the application first checks if a version in the local cache is available and, if not, the object is retrieved from the distributed cache.
The problem is that the local version can be older than the distributed version of the object. To solve this problem, the method 'dataCache.GetIfNewer(...)' is available that can be used to check if the version of the local object differs from the distributed version and, if it does, it returns the new object.
So far, so good...now my questions; I've created two seperate applications (app A en app B) to test the Azure Caching mechanism. Both applications run on two different (physical) locations so they both have their own local-cache but they both use the same distributed cache.
Is it true that something has changed in the process of invalidating the local cache? I've tested the following scenario and found out that the local cache is update automatically:
App A stores the value "123" in the distributed cache using the key "CacheTest"
App B uses the dataCache.Get(...) method to retrieve the object for the key "CacheTest" which cannot be found in the local cache so it is retrieved from the distributed cache en returns the object with value "123".
App A changes the object with key "CacheTest" to the value "456"
App B uses the datacache.Get(...) method to (again) retrieve the object. Because the object should be in the local cache, I would expect the value "123" but it returns the new value "456"!
How strange is that? Is something changed in Azure Caching lately? And yes...I'm sure that I've turned on local caching and yes, I've set the time-out on the local cache to 3600 seconds (1 hour).
Can somebody confirm that Azure Caching has been changed?
Edit for Nick:
So what you're saying is that the next lines of code that I've found on a Dutch Microsoft site are nonsense? When the local-cache is updated automatically, there's no need to call the 'GetIfNewer' method: http://www.dotnetmag.nl/Artikel/1478/Windows-Azure-AppFabric-Caching
///
/// Ensures that the newest version of a cached object is returned
/// from either the local cache or the distrbuted cache.
///
public TCachedObjectType GetNewest<TCachedObjectType>(string key) :
where TCachedObjectType : class
{
DataCacheItemVersion version;
// Gets cached object from local cache if it exists.
// Otherwise gets cached object from distributed cache and
// adds it to local cache.
object cachedObject = cache.Get(key, out version);
// Gets cached object from distributed cached if it is newer
// than given version.
// If newer it adds it to local cache.
object possiblyNewerCachedObject =
cache.GetIfNewer(key, ref version);
if (possiblyNewerCachedObject != null)
{
// Cached object from distributed cache is newer
// than cached object from local cache.
cachedObject = possiblyNewerCachedObject;
}
return cachedObject as TCachedObjectType;
}
If the described behaviour is the same as appfabric velocity, the behaviour described is as expected. When local caching is enabled it means that when a given node requests a cache item from the distributed cache, it asks the distributed cache what the current version is.
If the locally cached version matches the distributed version, it returns the data from the local cache. If not, it retrieves the latest value from the distributed cache, caches it locally and then returns it.
The idea is that if any node updates the key, all nodes will always be ensured to get the latest version even if appfabric had already cached them locally. The distributed cache keeps track of the latest versions and where their data is stored.
Related
Lets say I have a large object stored in ObjectStorage (in MBs) --
What will happen now if someone (lets say connection A) tries to retrieve it (downloading it) while someone else (lets say connection B) is updating the object by uploading a new version of blob into the same object?
Will connection A still see the old version while the new version of blob has not completely uploaded or will see a corrupted data? At what time A will start seeing the new version of the object?
If you are downloading an object while it is overwritten you will continue to see the old object.
The system does out-of-place overwrites so the old data is available however if the download goes on for a very long time the old data will be garbage collected and the download will fail (this is a very extreme scenario)
What is the mechanism by which the cache and cache entries work? When is it that the data from the cache server is retrieved?
If a new client connects to Apache Ignite and calls the Ignite#getOrCreateCache() by passing in a name of cache that already exist, does the entire cache get downloaded?
After getting a reference to an existing cache and calling the IgniteCache#get("key") does only the value associated with the key gets returned or the entire cache?
The mechanism by which cache entries work is as follows:
You call IgniteCache#get(key) on a Ignite client. Ignite determines which is the closest server from where this key's value can be retrieved or if a near cache is enabled in the Ignite Client, then it checks if the key's value is present in the near cache or not.
The key's value is then serialized on the server side and sent across the network to your Ignite client(provided the value is not in near cache or the Ignite server is not on the same machine).
The Ignite Client De-serializes the value and returns the object.
Only the specific value is retrieved from the Ignite server and the entire cache is never downloaded on your client.
P.S. Whenever you ask questions related to Apache Ignite use the tags grid-gain and ignite.
We are using AppFabric Caching services with local cache enabled.
the in-memory operations being performed on data (acquired from Cache) seem to be getting saved in local cache (without explicitly placing the updated objects in cache).
What I've read in documentation, local cache just holds a local copy and there are mechanisms to invalidate local Cache as well.
What can I do in order to over-write this local-cache behavior (as per my initial understanding, local-cache contents are read-only, which does not seem the case here)
this the configuration being used:
DataCacheFactoryConfiguration configuration = new DataCacheFactoryConfiguration();
configuration.TransportProperties.MaxBufferSize = int.MaxValue;
configuration.TransportProperties.MaxBufferPoolSize = long.MaxValue;
configuration.MaxConnectionsToServer = MaxConnectionsToServer;
DataCacheServerEndpoint server = new DataCacheServerEndpoint(host, port);
List<DataCacheServerEndpoint> servers = new List<DataCacheServerEndpoint>();
servers.Add(server);
configuration.Servers = servers;
DataCacheLocalCacheProperties localCacheProperties = new DataCacheLocalCacheProperties(MaxObjectCount, LocalCacheTimeout, DataCacheLocalCacheInvalidationPolicy.TimeoutBased);
configuration.LocalCacheProperties = localCacheProperties;
How can I overwrite this behavior of local cache (not using local cache is not an option due to lot of read operations going on) ?
Thanks in advance,
I think this is explained in the documentation (emphasis added):
Locally cached objects are stored within the same process space as the
cache client process. When a cache client requests a locally cached
object, the client receives a reference to the locally cached object
rather than a copy
and
After objects are stored in the local cache, your application
continues to use those objects until they are invalidated, regardless
of whether those objects are updated by another client on the cache
cluster. For this reason, it is best to use local cache for data that
changes infrequently.
I have AppFabric installed and working great caching my ASP.Net Sessions. I have 3 W2k8 Enterprise servers as my cache hosts. I created my cache with the Secondaries=1 option. I'm trying to test the High Availability option. In order to do this, I would like to login to my website, find the cache server that has my session and unplug it from the network (simulating a server crash). If I can still work as a logged in user, I can prove that High Availability is working and the secondary copy of my session was promoted.
How can I see a list of the objects in the cache and where the primary/secondary objects "live"?
The get-cache Powershell command can show you your caches running in a cluster, and where their objects (and regions) are located.
Use this code to get all cache objects. Be careful though because depending on your cache size it can take a significant amount of time to dump all cache objects:
foreach (var regionName in cache.GetSystemRegions())
{
foreach (KeyValuePair<string, object> cacheItem in cache.GetObjectsInRegion(regionName))
{
// TODO: process cacheItem.Key and cacheItem.Value
}
}
Let's say I have a bunch of users who all access the same set of files, that have permission system:anyuser. User1 logs in and accesses some files, and then logs out. When User2 logs in and tries to access the same files, will the cache serve the files, or will it be cleared between users?
The cache should serve the files (in the example above).
How long a file will persist in the OpenAFS cache manager depends on how the client is configured, variables include the configured size of the cache, whether or not the memcache feature is enabled, and how "busy" the client is.
If OpenAFS memcache (cache chunks stored in RAM) is enabled, then the cache is cleared upon reboot. With the more traditional disk cache, the cache can persist across reboots. Aside from that key difference files persist in the cache following the same basic rules. The cache is a fixed size stack, recently accessed files stay in the cache and older files are purged as needed when newer files are requested.
More details are available in the OpenAFS wiki:
http://wiki.openafs.org/