Spring Redis cache expiration in memory - spring-data-redis

Using Spring Redis cache and wonder if is possible to set some data cache duration in memory. Cache of cache. If i know that data in Redis will not change for 5 minutes i dont need that Spring Redis cache touch the Redis everytime when some #Cacheable method is called.
Is Redisson the answer?

AFAICT, Redisson is simply a client-side facade or enhanced Redis (Java) client used to interface with a Redis node (or cluster) in a more powerful and convenient way, not unlike Spring Data Redis. For example, and as you already know, using Redis as a caching provider in Spring's Cache Abstraction.
Redis does seem to support client-side caching (a local cache in addiion to the remote (server) cache?), when using a Redis client/server topology. This would be transparent to you application (e.g. #Cacheable) and configured in the Redis client driver, AFAIK.
However, given my lack of experience with Redis, or even Redisson for matter, I cannot speak to this feature in detail. Redis client-side caching may need to be supported by the Redis client drivers (e.g. Jedis, Lettuce, even Redisson, etc).
NOW THE LONG-WINDED ANSWER FOR THE INTERESTED READER:
What you are describing when you state a "cache of cache" hearsay, is really having a "locally available cache" in addition to the "remote, or server-side cache". This assumes, of course, you are running Redis in a client/server (not embedded), and possibly distributed/clustered (maybe HA), capacity in the first place.
Ideally, you would choose a caching provider that supported this sort of arrangement out-of-the-box, natively. And, despite popular belief (for example), much of what Redis "reinvented" (horizontal scale-out or cluster, HA, even persistence) already existed in other, more mature solutions, built from the ground up with these concerns in mind.
SIDENOTE: Granted, the referenced article above is dated, but also a bit naive.
A "cache of (a) cache" is technically referred to as the Near Caching pattern.
It is where the "local" (application/client-side) cache mirrors the "remote" (server-side and primary) cache to avoid [a] network hop(s), i.e. latency, by only accessing the remote cache when necessary (e.g. cache miss), preferably in a "single-hop", "fault-tolerant" fashion, when the server-side is distributed and clustered.
However, a fundamental difference between the local cache and server-side, remote cache is that the local cache only stores a subset of the data from the remote cache based on "interests".
NOTE: In Redis's documentation, they referred to this as "tracking". There are different ways, across different providers, to express "interests" or track what the client has accessed. Be mindful of the different approaches here since they consume different system resources.
You might have a distributed (Web / Microservice) application architecture where several client application instances serve different demographics or populations of end-users. Clearly, those client application instances might use shared, but different subsets of the primary dataset stored in the servers. This is where the local cache and "registering interest" only in the data that matters to, or is used by, the client application comes into play.
"Registering interest" is important since the server-side, remote cache can notify clients ("push", rather than a client "pulling") hosting a local cache when data on the server changes that a client is interested in since more than 1 client might have interest in and use the same data (e.g. "record", and the intersection of data).
So, how do we properly address this concern without unnecessarily introducing extra (layers of) complexity into our system/application architecture?
Well, for one, it starts by choosing the right caching provider for the problem at hand.
DISCLAIMER: my experience stems from Apache Geode, which is the OSS variate of VMware Tanzu GemFire and a I am responsible for all things Spring for Apache Geode at VMware.
While I am a bit biased here it is not uncommon for other caching providers (and complete IMDG solutions) to support the same arrangement. For example, 1 of my personal favorites is Hazelcast.
Hazelcast calls this particular caching arrangement, or topology, an "embedded" cache and even refers to this as "near cache" in the documentation.
The nice thing about a local, embedded "Near Cache" is that it avoids latency through unnecessary networks hops, however, interest registration is key to keep data consistent, as far as possible.
I have documented, talked about and even demonstrated different caching patterns when using Spring for Apache Geode in the Spring Boot for Apache Geode documentation here and Near Caching in particular, along with the Near Caching Sample in the Samples with the other caching patterns).
I am sure you can find similar resources with other caching providers, even Redis.
At any rate, this documentation should help you understand different concerns to be aware of (e.g. memory consumption) when choosing any topology and configuration.
Good luck!

Related

Can/should SignalR Backplane be used to build a distributed cache?

Our web app uses in-memory caching (Application Data Caching) to improve throughput such that frequently queried data does not have to be loaded from the database (SQL Server) for every request. Potentially, it will be deployed in a web-farm so we have to solve the classical problem of having to synchronize the caches of all nodes. So what we need is a distributed cache.
Readily available solutions are NCache and REDIS (and probably more). However, since we are already using SignalR Backplane to communicate changes to our dataset to a Windows Service (and browser clients), I'm wondering if it could be used to implement a distributed cache.
Doing so, we would (more or less) re-use our existing dataset-has-changed messages but subscribe to them in the web app itself to invalidate its cache. The upside being that we don't have to introduce a new library/technology.
I guess my biggest questions are: Does that make sense? And, is SignalR Backplane reliable enough to make sure no events get lost resulting in out-dated caches? Or is this architectural misuse?
Signalr is for realtime solution not for static.
In your solution, you will select data on one service, and you will send it to another service by backplane. Then what ? Probably you will save this to memory. What happens if one of the service has restarted ? Data will gone. You will never face this problem with redis. Additionally, you will consume your local memory for this data.
Also how you will manage expiration ? Plus you will make effort to implement this cache system with signalr.
I don't suggest you to use signalr backplane for this. Stick with Redis or smilar technologies.

Highly configurable and efficient ESB / SOA / integration framework

my plan is to develop or use a Java-based integration framework (ESB, SOA whatever) that deals with services, with the following constraints:
a Service can be deployed on multiple machines but doesn't have to be present on every one of them
a Service can be deployed and re-deployed (with a newer version) separately
a Service is connected to other services either by:
in-memory connections
(async / sync) remoting to other machines
the routing logic of the Service connections should be configurable on the fly, without re-deploying or restarting anything
I know that OpenESB is close to these requirements, however it requires redeployment of the service to change the routing (suppose the connections are HTTP BC based), but I'm unfamiliar in this regard with MuleESB, WSO2, JBossESB, whatever open source ESB... Is there any good solution for this (e.g. configurable in-memory and/or remoting routing)? I don't really care about clustering as I plan to use the servers separately, and the designated (if required) JMS solution would be HornetQ if that matters.
You mention several different concepts, but a combination of an ESB pattern, Apache Load Balancer and Maven should get you close. Do not get to hung up on the product, settle on a paradigm/pattern and the decision of the product will be easy, it either does things the way you like or does not.
Here is the pattern I use.
SOA Design Patterns
This may also interest you SOA for executives
Cheers
After a long discussions about the pros and cons, we are going to have a HornetQ-based (JMS MQ) solution, where we create message routing rules and sometimes processing codes that handle the different kind of routing. HornetQ is able to handle the in-jvm requirement too, but that part will be covered under the hood.

Physically Separating Secure and Non Secure Web Requests

We have been doing some research into physically isolating the secure and non-secure sections of our web application into two applications. All "http" requests would be served by one server (or cluster) and all "https" requests would be served by another server (or cluster).
The reason that we are looking into this is partially for the survivability of the application. Since the secure section of the application is revenue generating we could, for example, have a larger and/or more powerful cluster to serve the requests. Conversely, when we upgrade the hardware in the secure application, it could be re-purposed to serve the non-secure site - basically extending the life of the servers.
Has anyone worked with this approach? We had an RFP out to a (well known) vendor last year for an architectural assessment and this was one of the possible paths that was recommended. While I see the potential upside, I worry about things such as maintenance, deployment, version control, etc.
Depending how your app is architected, it seems to me that if you used virtualisation / load balancing you could have the same benefits of guaranteed resources and isolation for the paid area, while also being able to dynamically burst resources to deal with spikes in load in either area. Your current proposal allows you to guarantee and prioritise resources, but it may result in some of them being idle.
Plus it would be easier to manage load through configuration, as it would then be a pure deployment issue and an entirely separate concern. You'd also be more independent of your hardware upgrade path as you'd just be adding/assigning virtual machines to the new hardware.

Anyone using Memcached with ASP.NET on a distributed farm?

We have 22 HTTP servers each running their own individual ASP.NET Caches. They read from a read only DB that is only updated off peak hours.
We use a file dependency to invalidate the cache, prompting the servers to "new up" their caches...If this is accidentally done during peak hours, it risks bringing down our DB cluster due to the sudden deluge of open connections.
Has anyone used memcached with ASP.NET in this distributed form? It seems to me that it would offer a huge advantage of having to only build up one cache (and hit the DB 21 times less), while memcached would handle distributing it on each box.
If you have, do you place it on the same box as the HTTP boxes, or do you run a separate cache tier? How well does it scale, can we expect it to need powerful servers? Our working dataset is not huge (We fit it into 4 gigs of memory on each HTTP box just fine).
How do you handle invalidation?
Looking for experiences and war stories.
EDIT: Win2k3, IIS6, 64-bit servers...4 gigs per box (I believe, we may have upped it to 16 gigs when we changed to 64-bit servers).
"memcached would handle distributing it on each box"
memcached does not distribute or replicate a cache to each box in a memcached farm. The memcached client basically hashes the key and chooses a cache server based on that hash. When one of the memcached servers fail you will lose whatever cached items existed on that server, however, the client will recognize the failure and begin writing values to a different server. This being the case, your code needs to account for missing items in the cache and reset them if necessary.
This article discusses the memcached architecture in more detail: How memcached works.
Best practice (according to the memcached site) is to run memcached on the same box as your web server app or else you're making http calls (which isn't all that bad, but it's not optimal). If you're running a 64-bit app server (which you probably should if you're going to be running memcached), then you can load up each of the servers with loads of memory and it will be available to memcached. There's not much in the way of CPU resources used by memcached, so if your current app server isn't very taxed, it will remain that way.
Haven't used them together, but I've used them both on separate projects.
Last I saw the documentation explicitly said that sharing with the web server was ok.
Memcache really only needs RAM and if you take your asp.net cache out of the equation how much RAM is you web server actually using? Probably not much. It won't compete much with your web server for CPU and it doesn't need disk at all. You might consider segmenting off the network traffic (if you don't already) from the incoming web requests.
It worked well and was fast I didn't have any problems with it.
Oh, invalidation was explicit on the project I used it on. Not sure what other modes there are for that.
If you want to get replication accross your memcached servers then it maybe worth a look at repcached. It's a patch for memcached that handles the replication part.
Worth checking out Velocity, which is a distributed cache provided by Microsoft. I cannot give you a point-by-point comparison to memcached, but Velocity is integrated with ASP.NET and will continue to get more development and integration.

What are the strongest features of Memcached?

In particular what strengths does it have over caching features of Asp.net
memcached is a distributed cache -- the whole cache can be spread into multiple boxes. so for example you can use memcached to store session data in cluster environment, so this data is available to any box of the cluster.
memcached can be compared to Microsoft's Velocity (http://blogs.msdn.com/velocity/).
Another nice feature is that memcached runs as a stand alone service. If you take your application down, the cached data will remain in memory as long as the service runs.
We use memcached as a caching back-end in a ASP.NET web site. We have 12 memcached boxes.
UP for memcached:
Much more scalable, just add boxes with memory to spare
The cache nodes are very ignorant: this means that they have no knowlegde about the other nodes participating. This makes the management and configuration of such a system extremely easy.
All of the webservers have the same values in cache (so you never see hopping values deending on which webserver serves your request)
DOWN for memcached:
compared to in-memory cache, it is very slow. Mostly because of serialization/deserialization and network latency
The cache nodes are very ignorant: ther is, for example, no way to iterate over all of the cached items
Memcached is the simplest en fastest tool is you need distributed caching. If you can use in-process in-memory cache for your application, that will always be faster. We use a cache manager that will offload certain items to memcached and keep others in local cache.

Resources