I am currently trying to set up two Lucee instances to cache to a central EHCache instance.
I’ve tried to use manual discovery as well as automatic discovery with a central EHCache instance as well as cache replication between the Lucee instances as a fallback solution.
Though from the different options it is unclear to me how the correct configuration needs to look like.
The last configuration I’ve tried was //<Host>:<Port>/<Cachename> as manual RMI URL, localhost as host name for the manual discovery, localhost for the listener host name and the corresponding Lucee port.
I’ve also read the post from @dswitzer about improving the EHCache extension, which suggested some syntax for the configuration options.
Have you checked your firewall settings to make sure nothing is being blocked?
What version of the ehCache extension are you using?
From my experience, if you’re running in a cloud environment (especially VMWare), multicasting most likely does not work, so you will need to use a manual configuration.
When configuring things manually, each server is going to need a unique configuration. For example, if you had 3 servers (A, B, C) when configuring the RMI URLs for server A, it would need the URLs for Server B & C, server B would need A & C and finally server C would need A & B. Those URLs should like something like:
Thank you for answering, @dswitzer!
First off, I need to say I’m coming from a Redis background and am still new to how EHCache and the related Lucee extension.
As I understand, the RMI URLs are used to let the different Lucee instances communicate between each other and replicate the cached data between their local EHCache instances, right?
Though I want to avoid the memory overhead caused by separate EHCache instances. So I set up a test environment with a central, independent EHCache server which should be accessed by two Lucee instances.
So I tried adding the EHCache server’s URL at different places. First try was as RMI URL as you discribed it, i.e. //<EHCache server IP>:<EHCache server port>/<cache name> for both Lucee instances. Second try was via the listener config, so the EHCache server IP and port for “Host Name” and “Port” as well as “Remove Object Port” there.
So the main question is whether a configuration with a centralized EHCache is possible/reasonable?
While I was attempting to get the centralized cache working, I also previously tried out the replication config you are describing. So, basically setting //localhost:20000/cache as RMI URL for the first Lucee instance running under port 10000 and //localhost:10000/cache as RMI URL for the second Lucee instance running under port 20000. Though that also didn’t work out, meaning, the servers wrote into their local EHCache instances, though never synchronized between each other.
I tried this with the latest release version of the EHCache extension 2.10.0.36 as well as the latest snapshot version 2.10.0.37.
Also, the Lucee server version I tested on now differs to the one I posted earlier because I have more control over that. My current server config is Lucee 5.4.4.38 on Windows 11 with Java 1.8.0_411 running via WildFly / Undertow - 2.2.28.Final (set up via CommandBox). And yes, I set up my firewall to let requests through.
(Though in the end it should run on the Linux machine with the older Lucee version.)
I won’t claim to be an ehCache expert by any means, but from my experience it’s probably the wrong way to go about using ehCache—especially if you plan on caching complex data. Trying to set up a centralized instance means everything you are pulling from cache has to come across the network. If you’re trying to cache things like component/beans, that means that data has to be serialized to store and then deserialized each time you pull it from cache. From my experience this ends up performing poorly and often can lead to situations where the cache does not provide much benefit.
From what I’ve seen, the best way to use ehCache is to let each instance manage it’s on cache and only have the replication announce to the other nodes when an item needs to be expired from cache. This makes the network traffic really light and since everything is kept in memory locally, makes it really fast.
The downside to this is if you have a really complex process where you are caching the result, it does mean each server has the overhead of initially warming up it’s cache, because it’s not going to be shared across all nodes. However, you can have separate cache pools, so if this is a problem you are trying to solve, you could have a cache pool specifically for large complex cache processes that does serialize your data and propagate it to the other nodes in your environment. I’d argue though that if you have that problem, you’d be better off creating a process to warehouse the data in this process instead of using cache and then just have the servers access the warehoused data and use your normal cache pattern.
By default, Lucee’s ehCache won’t replicate data across nodes (which provides the best performance). So if you cache an item on 1 server it won’t show up on server 2. While this may sound counterintuitive, as I mentioned above the cost of serialization/deserialization and the network traffic often makes this perform slower than just having each server manage adding data to it’s own cache.
However, what should be happening is when you expire an item on server 1, it should expire the item on server 2 so that the next time the item is requested, each server should run the logic forcing an update.
If you want it to really push data across all nodes, then you will need to enable the “Via Copy” replication options, but we have found that just adds way more overhead and really slows things down in most use cases (especially if you want to cache component/beans).
As a general rule, I’ve found these to be the best replication settings for most use cases:
However, this does mean that each server manages the creation of cache items on it’s own, but when an item is flushed from cache it will be expired on all servers, which means if a cached item changes, each server will make sure to update it’s cache next time the cached item is requested.