We have a cluster-environment too. We use Hazelcast for such jobs. With Hazelcast you could embed the codeblock for updating within a "Hazelcast-Lock-Section". It is not my favourite solution, but this is how it is done in our application (and maybe suits hazelcast your needs).
I opt for a smaller and easier solution: I would write a small (buzzword-alarm: micro-) service using Spring Boot.
Its only job is to update the data. It does not interfere with your application. And when it has finished its job, it could notify the application (if necessary). And the best part: you need no negotiation between instances.
The advantages of a small service are:
separation of concerns. A separate service which does only one thing (and does that well).
runs independent of other parts of the application.
errors are obviously limited to this service
easy to (un-)deploy
Advantages of Spring Boot:
- Monitoring
- Monitoring2
- Did I mention Monitoring?
- Easy to set up
- Integrates nicely with all the other Spring Goodness
Other frameworks, which might be interesting for such a task are Dropwizard or Vert.x. I tried neither, but maybe you take a look.
P.S.:
Data from the database is cached in memory in each instance of the web app
Don't do that. There are nicer solutions like memcached or redis