Performance Optimization of a New‑Car E‑commerce CRM System: Distributed Locks with ZooKeeper and Redis Cache Improvements

This article details how a new‑car e‑commerce CRM system was optimized for high availability by introducing ZooKeeper‑based distributed locks, mitigating herd effects, segmenting locks per merchant, and redesigning Redis caching with sorted sets to efficiently rank consultants by daily call volume, resulting in significant performance gains under high concurrency.

HomeTech
HomeTech
HomeTech
Performance Optimization of a New‑Car E‑commerce CRM System: Distributed Locks with ZooKeeper and Redis Cache Improvements

Background : The new‑car e‑commerce CRM system collects, manages, and analyzes customer information, and the newly introduced consultant mode generates high‑quality leads that require reliable, high‑performance processing.

Distributed Lock Optimization

To avoid duplicate consultant data when multiple instances concurrently read from Redis and MySQL, a distributed lock mechanism based on ZooKeeper is employed.

Why use a distributed lock?

When the Redis cache is empty, threads query MySQL and push results back to Redis. Under high concurrency, multiple threads may see an empty cache simultaneously, leading to duplicate entries.

ZooKeeper Distributed Lock Principle

Temporary sequential nodes are created under a lock path; the node with the smallest sequence number acquires the lock, while others watch the predecessor node. The lock is re‑entrant by associating the current thread as the key.

Key Lock Acquisition Code

// Get all temporary nodes under the lock path
List<String> children = getSortedChildren();
String sequenceNodeName = ourPath.substring(basePath.length() + 1);
PredicateResults predicateResults = driver.getsTheLock(client, children, sequenceNodeName, maxLeases);
if (predicateResults.getsTheLock()) {
    haveTheLock = true;
} else {
    String previousSequencePath = basePath + "/" + predicateResults.getPathToWatch();
    synchronized (this) {
        try {
            client.getData().usingWatcher(watcher).forPath(previousSequencePath);
            if (millisToWait != null) {
                millisToWait -= (System.currentTimeMillis() - startMillis);
                startMillis = System.currentTimeMillis();
                if (millisToWait <= 0) {
                    doDelete = true; // timed out - delete our node
                    break;
                }
                wait(millisToWait);
            } else {
                wait();
            }
        } catch (KeeperException.NoNodeException e) {
            // Node deleted, retry acquire
        }
    }
}

Performance Optimizations for the Distributed Lock

Avoiding the herd effect : Instead of all threads watching a single znode, each thread creates a sequential temporary node and only watches the node with the next smaller sequence, reducing unnecessary wake‑ups.

Lock segmentation : Locks are partitioned by merchant ID, allowing parallel processing of different merchants and preventing a single lock from becoming a bottleneck.

Timeout tuning : Reducing the lock acquisition timeout (e.g., from 60 seconds to 6 seconds) prevents threads from waiting excessively and exhausting server memory.

Redis Cache Optimization

To rank consultants by their daily call volume, a Redis sorted set is used where the merchant ID is the key, the consultant ID is the member, and the score represents the number of calls for the day.

When a call record is generated, it is first persisted in MySQL for durability. Then the Redis sorted set is updated: if the consultant already exists, incrementScore() is called; otherwise the consultant is added with an initial score of 1. The sorted set expires daily.

Diagram of the data flow:

The resulting cache shows consultants already ordered by call count without duplicates, enabling fast retrieval for the front‑end.

Conclusion

The described optimizations—introducing ZooKeeper‑based distributed locks, mitigating herd effects, segmenting locks per merchant, and redesigning Redis caching with sorted sets—significantly improved the CRM system’s throughput and stability under high concurrency, laying a foundation for future features such as voice recognition and intelligent outbound calls.

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.

BackendJavaPerformance OptimizationredisZooKeeperdistributed-lock
HomeTech
Written by

HomeTech

HomeTech tech sharing

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.