Hazelcast and Redis in Gaming

We did not pick one cache — we mapped each workload to CAP

On a live gaming platform, someone always asks: “Hazelcast or Redis?”

As if one logo must win the whole cluster.

We did not choose that way. After modularizing game engines — lobby, game, transactions on their own paths — we needed recoverable game state when a node dies, coordination across JVM services, and high-volume leaderboard reads that could tolerate a little lag. Hazelcast and Redis each fit a different CAP shape.

This article is Hazelcast and Redis — not vs. How we use a remote Hazelcast distributed cluster for replicated table state and failover, and Redis for leaderboards. CAP is the lens; live tables, pinned game nodes, and money kept off the tick are the examples.

Architecture, to us, is not picking logos. It is design, prototypes, and naming tradeoffs out loud. Choose C or A because the business can live with the downside — CAP is a lens, not a bible.

CAP in one minute

LetterPlain meaning
C — ConsistencyEvery read sees the latest write (or you get an error)
A — AvailabilityNon-failing nodes keep answering
P — Partition toleranceSystem keeps running when the network splits

P is not optional at scale. Under partition you pick C (refuse stale / fence / error) or A (keep serving, maybe stale).

If the business says…Lean towardGaming example
“Wrong money or double owner is unacceptable”C (refuse / fence / error)Table ownership, routing on failover
“Empty screen or long outage hurts more than slightly stale data”A (keep serving)Leaderboard top 100, presence hints
WorkloadCAP leanTool
Live table state + failoverC when JVM or grid member failsHazelcast IMap + CP
Leaderboard top 100A — empty board worse than stale rankRedis ZSET
Wallet / payoutDurable CDB + queue

Same company, same platform — different maps, different clusters, different backup settings.

Our model: pinned node + IMap replica

We pin one game to one game node. That node is the active writer — pot, seats, turn, timers — single owner, local memory, fast tick.

Every state-changing action (fold, call, raise, timer) also replicates a snapshot to Hazelcast `IMap` on a remote cluster with sync backup. If the pinned node dies, a new node loads that snapshot and resumes — same pot, same turn.

LayerRole
Pinned game node (local)Active writer during play — every fold/call/raise mutates local state first (fast tick)
Hazelcast IMap (sync backup)Recovery copy — replicate snapshot on each state change; new node loads table if pinned node dies
CP lock + fencingOnly one game node may resume the table after failover
Table → node routing (IMap)Where clients reconnect after failover
Queue + DBBuy-in / payout — durable money truth, not per-action IMap

Normal action: local mutate → IMap.set(tableId, snapshot) → broadcast

Game node dies: CP lock → new node IMap.get → hydrate → clients reconnect

oney still flows queue + DB — not per-action cache ledger.

Hazelcast: remote distributed cluster (not embedded)

Dedicated six-member grid. Game / lobby / transaction services are clients only.

ModelWhat it meansWhat we did
EmbeddedEach game JVM is also a Hazelcast memberNo — different scale lifecycles
Client → remote clusterGame services are HZ clients; grid is dedicatedYes — our model
[ Game node A — active writer ]  ──client──┐
[ Game node B — failover target ] ──client──┼──►  [ Hazelcast cluster ]
[ Lobby service ]                ──client──┘         game state IMap (sync backup)
                                                    routing IMap, CP locks

Why remote cluster: scale game fleet independently; blast radius; tune sync backup on grid nodes; game JVM churn does not reshape partitions.

Jobs we gave Hazelcast

JobWhy Hazelcast (remote cluster)
Replicated game state (IMap)Every state-changing action → snapshot to IMap with sync backup; new game node loads table if pinned node dies
Table → node routingCentral IMap; all services know where each table lives
Ownership on failoverCP subsystem + fencing — only one node may resume the table
Soft metadataPresence, session hints — rebuildable; async OK

CAP justification: losing a live money table mid-hand, or two nodes serving different pots, is unacceptable → sync backup on game-state `IMap`, CP + fencing on failover.

What we did not do: two writers without fencing wallet ledger in HZ async-only zero-backup on game-state maps.

Redis: leaderboards (AP-leaning)

JobWhy Redis
Global / seasonal leaderboardsZSET — score-ordered ranks, top-N in one structure
High read volumeSimple, fast, operationally familiar
Ranking displayProduct tolerates seconds of staleness across replicas

Leaderboards are AP-friendly: show rank #6 when true rank just became #5 beats an empty board. Redis ZSET, high reads, replica lag OK for display.

What we did not do: Redis as sole payout source; linearizable global #1 on every read full match simulation in Redis.

WorkloadCAP preferenceChoiceWhy
Live table / pot / turnStrong C per matchGame node + HZ IMapLocal active writer; replicate snapshot to sync-backed IMap for failover
Table → node routingC on failoverHazelcastSync backup on dedicated HZ members; game nodes are clients
Ownership after node deathCP (no split-brain)Hazelcast CPOne successor; fence old owner
Buy-in / payout handoffDurable, orderedQueue + DBNot cache-as-ledger; gameplay stays off money path
Leaderboard / rankingA over strict CRedisZSET top-N; brief staleness OK; high read QPS
Presence / soft hintsEventual OKHZ async or TTLRebuildable; not money truth

When things fail

Game node goes down

1. Pinned node dies mid-match

2. One successor acquires CP lock (fences old node)

3. ‘IMap.get(tableId)` → rebuild local state

4. Routing updated → players reconnect

5. Resume or void by product rules

CAP: C on failover — we paid sync replication during play.

Hazelcast grid member goes down

1. HZ member loss → backup promotes → short rebalance

2. Game clients retry `get`/`set`

3. Replicated game state survives on promoted copy

Avoid: state living only in one JVM with no recoverable `IMap` copy.

Anti-patterns

  • One cache for everything — CAP differs by workload
  • Redis Redlock for table ownership — we used Hazelcast CP + pinned node
  • Hazelcast for every leaderboard — Redis ZSET won for AP serving
  • Async / zero-backup on game-state `IMap`
  • Strong consistency everywhere — unnecessary for presence and ranks

Wrapping-Up

Hazelcast and Redis — not vs.

Hazelcast — remote cluster: replicated game state in `IMap`(sync backup), routing, CP on failover. Active writer on pinned node; recoverable copy on the grid.

Redis — leaderboards: available top-N, briefly stale OK.

CAP: pick C or A per workload. Architecture: design, prototype, name tradeoffs. Sync backup costs latency — we paid it where failure consistency mattered. Replica lag costs perfect ranks — we paid it where availability mattered.

Draw the workload on CAP first. Then place Hazelcast, Redis, and the game server.

if your platform debates “Hazelcast or Redis” as one winner — what workload would you map first?

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *