Reputation: 1
So I have an app deployed in appengine and it uses JCache
as the cache API.
Fact 1: The cache is loaded with data from the DB every day between 00:01 am and 00:04 am. This process works and there is no issue with this.
Fact 2: I use "dedicated
" cache (as against shared
cache).
Fact 3: I have chosen auto-scaling
with min-instances: 0
and max-instances: 1
, thereby implying that "start an instance when a user makes a request" and "shut that instance down after 'N' minutes of inactivity", where N is approximately 15 minutes.
Scenario 1:
Scenario 2:
Question: How can one hold reference to the actual cache object between when an instance going down and another instance comes up?
Here is the relevant code for the above:
appengine-web.xml file:
<automatic-scaling>
<min-idle-instances>0</min-idle-instances>
<max-idle-instances>0</max-idle-instances>
<min-instances>0</min-instances>
<max-instances>1</max-instances>
</automatic-scaling>
this is how the cache is loaded every night (this code is in CacheController
)...
Calendar calnExpr = null;
List<EstbStaffAsst> listOfEstbStaffAsst = null;
calnExpr = Calendar.getInstance(TimeZone.getTimeZone(CacheController.getEstbTZFromCache()));
calnExpr.set(Calendar.HOUR_OF_DAY, 23);
calnExpr.set(Calendar.MINUTE, 59);
calnExpr.set(Calendar.SECOND, 59);
calnExpr.set(Calendar.MILLISECOND, 999);
mapProperties.put(GCacheFactory.EXPIRATION, new Date(calnExpr.getTimeInMillis()));
try {
cacheStffAsst = CacheController.getCacheStffAsst();
if ((null == cacheStffAsst) || (cacheStffAsst.isEmpty())) {
cacheStffAsst = cacheFactory.createCache(mapProperties);
}
listOfEstbStaffAsst = EstbStffAsst.getList();
if(null != listOfEstbStaffAsst && !(listOfEstbStaffAsst.isEmpty()) && listOfEstbStaffAsst.size() > 0) {
cacheStffAsst.put("estbStaffAsst", listOfEstbStaffAsst);
cacheManager.registerCache("estbStaffAsst", cacheStffAsst);
}
}
catch(Exception e) {
}
and this is how an attempt (in vain) is made in the static block of CacheController
to see if the cache exists (alas it does not after every instance bounce)....
cacheManager = CacheManager.getInstance();
cacheStffAsst = cacheManager.getCache("estbStaffAsst");
Solution 1: configure auto-scaling
as min-instances: 1
and max-instance: 1
so 1 instance is always running. But this is expensive.
Solution 2: configure auto-scaling
as min-instances: 0
and max-instance: 1
and keep pinging this instance with a "keep-alive" http post every 10 minutes. This, I believe, is a brute force method of achieving the same result as Solution 1 above. So it too is expensive.
Solution 3: Write start up and shutdown hooks and listen for messages on these hooks. Upon receiving a "shut(ing) down" msg, serialize the class that holds references to the cache (in this case the CacheController
) and store the serialized blob on, say, Cloud Storage. Upon receiving the "start(ing) up" message, read the serialized blob from cloud storage, reconstruct the app object that holds reference to the cache
I have tried (1) and (2) above and discarded them because they are expensive. I have not tried Solution 3. But before I do, I wanted to know if it is normal to build cache upon every instance startup?
If it is normal, then, isn't the whole purpose of the cache lost because every time an instance is bounced and the cache has to be reloaded, significant I/O costs are incurred.
If it is not normal, then, is there a better way to hold references to the cache between instance shutdown and startup?
Upvotes: 0
Views: 31