Designing a Shopping‑Cart Service for Ten‑Million Users

This article explains how to architect a high‑traffic e‑commerce shopping‑cart system that serves tens of millions of users by using a process‑chain engine, Redis Cluster as the primary store, asynchronous persistence to MySQL, and a modular design that supports multiple cart types while ensuring consistency and scalability.

samdeepthink
samdeepthink
samdeepthink
Designing a Shopping‑Cart Service for Ten‑Million Users

When a shopping‑cart service grows from a simple CRUD component to a system handling millions of users, the implementation quickly becomes far more complex. Adding a product may involve inventory checks, promotion rules, packaging fees, calls to a settlement service, and finally persisting the cart, resulting in a dozen steps that can be parallel or sequential, and that may succeed or fail independently.

Global Overview

User actions from a mini‑program or app are routed through a gateway to the cart service. The core logic is driven by a process‑chain engine, the main data lives in a Redis Cluster, and changes are asynchronously persisted to MySQL via a message queue (MQ). Price calculation is delegated to a separate settlement service accessed via RPC, while product, inventory, and promotion data are fetched from dedicated product and marketing services.

Why Not a Monolithic Service Method?

A single Service method would have to handle at least three problems: (1) heavy step overlap between operations such as add‑to‑cart and select‑item, (2) opportunities for parallel execution (e.g., loading related items and cleaning the cart can run concurrently), and (3) the need to return to the client before persistence finishes. A process‑chain engine solves these by enabling step reuse, parallelism, and mixed sync‑async execution.

Process‑Chain Core Abstraction

The engine defines two concepts: ProcessNode, which encapsulates a single step, and ProcessChain, which orders nodes and specifies whether each node runs synchronously ( sync()) or asynchronously ( async(id, node)). An example chain for an add‑to‑cart operation shows a mix of sync and async calls, with the final persistence step marked as asynchronous and non‑blocking.

Operation‑Specific Chains

Four core cart operations (add, select, detail, checkout) share many steps but differ in a few. About 60 % of steps are reused across operations, justifying the engine approach. The longest chain (add) has 15 steps; the detail chain adds more parallel reads because it does not modify data.

Redis as Primary Store

For a ten‑million‑user scenario, Redis is chosen over MySQL for three reasons: (1) write‑heavy workload (tens of thousands of QPS during peaks), (2) natural fit of cart data to Redis Hashes (O(1) HGET/HSET), and (3) built‑in TTL for expiring inactive carts. A typical key layout is cart:user:{userId} with fields for different product types and metadata such as version and timestamp.

Choosing Redis Cluster

Estimating 30 % active users yields roughly 3 million cart hashes (~5 KB each), requiring 15–30 GB of memory after overhead. A single master cannot hold this amount, and RDB snapshots would double memory usage, risking OOM. Cluster mode provides sharding, linear write scalability, and automatic failover, making it the right choice for ten‑million‑level traffic.

Asynchronous Persistence Options

Three approaches are compared: (1) real‑time MQ (seconds latency, moderate complexity), (2) periodic scan (minutes latency, simple), and (3) a hybrid MQ + timer fallback (seconds latency, highest reliability). The hybrid solution is adopted: normal flow uses MQ for near‑real‑time persistence, while a timer task rescans Redis‑MySQL version mismatches every five minutes to recover from MQ failures.

Write‑Merge Strategies

Because a cart only needs to persist its final state, intermediate updates can be merged. Three strategies are evaluated: delayed‑message merging (5 s delay), dirty‑flag with periodic batch, and in‑process batch‑submit. The delayed‑message approach is selected: after a successful Redis write, a 5‑second delayed MQ message is sent if no such message exists, ensuring only the latest state is written to MySQL.

Degradation Plans

If the Redis Cluster fails, the service falls back to direct MySQL reads/writes (reduced QPS but no outage). If MQ fails, Redis continues serving requests while the timer task eventually syncs data. If MySQL fails, user requests still hit Redis; persistence pauses and resumes once MySQL recovers.

Supporting Multiple Cart Types

The system serves personal carts, group‑order carts, and corporate catering carts. Each type uses a distinct Redis key pattern and TTL (e.g., cart:spell:{roomId}:{userId} for group orders with a 1‑day TTL) but shares the same process‑chain infrastructure. Adding a new cart type only requires defining its specific nodes and key pattern.

Collaboration with the Settlement Center

The cart service never calculates prices; it packages the cart items and user info and calls the settlement center via RPC to obtain final prices and discounts. This separation keeps cart logic lightweight and isolates complex pricing rules. If the settlement service is unavailable, the cart returns the original price with a “price loading” flag.

Key Architectural Judgments

Cart data is whole‑record, write‑once‑replace, allowing eventual consistency and delayed writes.

Process‑chain engine is worthwhile when an operation exceeds eight steps and more than half of the steps are shared across operations.

Storage should match data volume; Redis Cluster is chosen only because a single master cannot handle the required memory and QPS.

In summary, the architecture demonstrates how to keep a seemingly simple cart interface manageable at massive scale by abstracting workflow, choosing the right storage tier, and designing resilient async persistence.

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.

Shopping CartRedis ClusterAsynchronous PersistenceProcess Chain Engine
samdeepthink
Written by

samdeepthink

Knowledge Planet: Old Dock's Tech Chronicles Zhihu: SamDeepThinking A technical manager who still codes heavily on the front line. From junior developer to tech lead, then tech manager, now leading the whole front‑ and back‑end development team—leveling up along the way. I have some insights on programming, career development, and tech management.

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.