Redis as Distributed Cache Backend
Goal: Technical
Developer: Norbert Bede, Peter Takacs
Feature Ticket: IDEMPIERE-6989
Redis as an Alternative Distributed Cache Backend
iDempiere's distributed cache interfaces (ICacheService, IMessageService, IClusterService) are pluggable. Until now the only implementation was org.idempiere.hazelcast.service, which runs an embedded Hazelcast cluster inside each iDempiere JVM.
This feature introduces a new bundle — org.idempiere.redis.service — that implements the same interfaces using Redisson against an external Redis server. Hazelcast remains the default.
Problem with Hazelcast in container environments
When iDempiere runs in containers (Docker, Kubernetes, ECS), every pod restart or rolling deployment causes Hazelcast to rebalance its partitions across the cluster. This leads to cache instability and increased database load until the cluster recovers. Since each JVM is part of the cluster, there is no way to restart a node without affecting the others.
How Redis solves this
With Redis, the cache lives outside the iDempiere JVMs. Restarting or replacing a pod does not affect the cache, and other nodes continue working normally. This makes rolling deployments, autoscaling, and blue/green deploys safe without any special coordination.
Setting it up
1. Install Redis. Any Redis 6+ instance works. For a quick local test: docker run -p 6379:6379 redis.
2. Configure the connection. Copy $IDEMPIERE_HOME/redis-template.yaml to $IDEMPIERE_HOME/redis.yaml and uncomment the topology block that matches your setup. The template includes single-node, Sentinel, and Cluster examples with inline comments.
3. Enable the backend. Add the JVM argument -Didempiere.distributed.backend=redis (or set IDEMPIERE_DISTRIBUTED_BACKEND=redis) and restart iDempiere. This flag is required — the org.idempiere.redis.service bundle is already included in the standard iDempiere installation alongside Hazelcast, but it stays passive until this flag is set. Without it, Hazelcast remains the active backend.
A key prefix (idempiere:<INSTANCE_NAME>:) is applied automatically to all Redis keys. The instance name is resolved in this order: redis.instance.name property, IDEMPIERE_INSTANCE_NAME environment variable, ADEMPIERE_DB_NAME, falling back to "default". This avoids key collisions when multiple deployments share a Redis instance.
Capabilities
- Caching: Map, List, and Set operations. An optional Caffeine near-cache can be enabled per cache for fast in-memory reads.
- Distributed locks: tryLock / unlock support via Redisson RLock.
- Messaging: Fire-and-forget pub/sub via RTopic. Durable delivery using Redis Streams (RReliableTopic) is available as an opt-in.
- Cluster membership: Nodes register themselves using heartbeat keys. No Hazelcast discovery configuration is needed.
- Remote execution: IClusterService.execute() is supported via topic-based request/response. Calls can target a single member or a list of members.
- Resilience: A circuit breaker detects Redis unavailability. Optionally, iDempiere can fall back to a local in-memory cache while Redis is down.
- Diagnostics: OSGi console commands are available to inspect Redis state:
redisStatus,redisHealth,redisMembers,redisKeys,redisBound,redisKeyspace.