How to Safeguard High‑Volume Contract Queries with Bloom Filters and Redis Caching

This article analyzes the massive daily query load on JD Logistics' contract center, identifies cache‑penetration issues, and proposes a three‑layer protection architecture—Bloom filter, Redis cache, and database fallback—detailing implementation steps, performance metrics, and consistency handling.

dbaplus Community
dbaplus Community
dbaplus Community
How to Safeguard High‑Volume Contract Queries with Bloom Filters and Redis Caching

Background

The JD Logistics Contract Center is the single entry point for contract creation, stamping, customization, archiving and querying across many business lines. The billing system queries the center for each logistics order to verify that a merchant has a signed contract and to calculate accurate fees.

Workload Characteristics

Average daily query volume ≈ 20 million (≈ 2000 万) requests.

Peak traffic reaches 40 k requests per minute during office hours (09:00‑12:00, 13:00‑18:00).

~40 % of queries return no result because the merchant has never signed a contract; the remaining queries typically return 3‑5 contracts per merchant.

Requests are largely random and contain many invalid merchant identifiers.

Three‑Layer Protection Architecture

To sustain the high‑concurrency workload while guaranteeing data consistency, a three‑layer design is applied:

Bloom filter layer – filters out the majority of invalid requests (cache‑penetration).

Redis cache layer – serves most valid queries with low latency.

Database fallback layer – provides the ultimate source of truth when the first two layers miss.

Cache‑database consistency is maintained by broadcasting contract‑status updates through a message‑queue (MQ) to all nodes.

Layer 1 – Local Bloom Filter

A Bloom filter uses a fixed‑size bitmap and multiple hash functions to test element existence without storing the actual keys. It offers:

Space‑efficient bit representation.

O(K) insertion and query time (K = number of hash functions).

Parallelizable hash computation.

Drawbacks are a configurable false‑positive rate and the inability to delete elements. Because contract data is immutable, deletion is not required. The filter is instantiated locally on each application instance to avoid an extra network hop. When a new contract is created or an existing one changes, the change is broadcast via MQ so every instance updates its filter consistently.

Layer 2 – Redis Cache

Redis stores contract lists keyed by merchant_code. If a request does not contain a merchant code, the service first resolves the code from merchant name or business account, then queries Redis. This key design keeps Redis keys small and avoids large “big‑key” problems.

Cache‑related risks and mitigations:

Cache avalanche : set TTL with a random offset (e.g., 1‑3 minutes) so expirations are spread over time.

Cache breakdown : use a distributed lock (e.g., RedLock) so that only one request builds the cache on a miss while others wait.

Never‑expire cache : keep contracts in Redis indefinitely and refresh them via a background job; this eliminates sudden expirations.

Cache consistency is achieved by listening to contract‑status change events and broadcasting delete or update commands through MQ, ensuring stale entries are removed promptly.

Layer 3 – Database Fallback

If a request bypasses both the Bloom filter and Redis, the service queries the relational database. To protect the DB during traffic spikes (e.g., promotional events), a ducc switch can temporarily disable DB access when load exceeds a predefined threshold.

Additional safeguards:

Pre‑cache all merchant‑contract data with randomized TTLs during off‑peak hours to smooth sudden traffic bursts.

Monitor DB‑access threads and throttle when concurrency approaches limits.

Key Operational Metrics

Average daily queries: ~20 M, evenly distributed across the day.

Peak QPS: ~667 (40 k/min).

Invalid‑query ratio: ~40 %.

Typical result set size per merchant: 3‑5 contracts.

Conclusion

The combination of a local Bloom filter, Redis caching with randomized TTL and distributed locking, and a guarded database fallback provides a robust solution for high‑concurrency contract queries. MQ‑driven cache invalidation guarantees data consistency, while the ducc switch and pre‑caching protect the database from overload during traffic spikes.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendSystem Designcachinghigh concurrencybloom-filter
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.