# How to Optimize Performance Using Redis and MongoDB in the Mall E-Commerce Project

> Optimize your e-commerce project performance with Redis and MongoDB. Discover how this hybrid architecture accelerates data retrieval and handles heavy write loads effectively.

- Repository: [macro/mall](https://github.com/macrozheng/mall)
- Tags: performance
- Published: 2026-02-28

---

**The Mall project optimizes performance by using Redis as a high-speed cache layer for frequently accessed data like admin permissions, while leveraging MongoDB for write-heavy, schema-flexible operations such as member browsing history, creating a hybrid architecture that minimizes database load and maximizes throughput.**

The macrozheng/mall project demonstrates how to optimize performance using Redis and MongoDB in a production e-commerce environment. By implementing a tiered data access strategy, the application reduces latency for hot reads through Redis caching while offloading high-volume write operations to MongoDB's document store. This approach creates a resilient and scalable backend architecture that balances speed, consistency, and flexibility.

## Architecture Overview

The Mall project implements a three-layer data strategy to handle different access patterns:

- **Redis Cache Layer** – Stores frequently read data including admin authentication details and permission lists to eliminate repeated MySQL queries.
- **MongoDB Document Store** – Persists high-write, schema-flexible objects such as member read history, product collections, and brand attention data.
- **MySQL Relational Database** – Maintains core business data including products, orders, and user accounts through existing MyBatis mappers.

## Redis Caching Strategy

### Centralized Configuration

The Redis infrastructure is configured through `BaseRedisConfig` in [`mall-common/src/main/java/com/macro/mall/common/config/BaseRedisConfig.java`](https://github.com/macrozheng/mall/blob/main/mall-common/src/main/java/com/macro/mall/common/config/BaseRedisConfig.java). This class constructs a `RedisTemplate<String, Object>` with JSON serialization, enabling any POJO to be cached efficiently. The `RedisConfig` in [`mall-security/src/main/java/com/macro/mall/security/config/RedisConfig.java`](https://github.com/macrozheng/mall/blob/main/mall-security/src/main/java/com/macro/mall/security/config/RedisConfig.java) extends this base configuration and enables Spring caching annotations.

```java
@EnableCaching
@Configuration
public class RedisConfig extends BaseRedisConfig { }

```

### Utility Service Layer

The `RedisServiceImpl` class located at [`mall-common/src/main/java/com/macro/mall/common/service/impl/RedisServiceImpl.java`](https://github.com/macrozheng/mall/blob/main/mall-common/src/main/java/com/macro/mall/common/service/impl/RedisServiceImpl.java) provides high-level operations that abstract low-level Redis template calls. This service exposes methods including `set`, `get`, `hSet`, `sAdd`, and `lPush`, which are used throughout the application for consistent cache interactions.

### Practical Implementation

The admin cache implementation in [`mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminCacheServiceImpl.java`](https://github.com/macrozheng/mall/blob/main/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminCacheServiceImpl.java) demonstrates practical Redis usage for performance optimization. This service stores authenticated admin objects and permission lists with a configurable TTL defined by `REDIS_EXPIRE`.

```java
@Service
public class UmsAdminCacheServiceImpl implements UmsAdminCacheService {
    @Value("${redis.database}") private String REDIS_DATABASE;
    @Value("${redis.key.admin}") private String REDIS_KEY_ADMIN;
    @Value("${redis.expire.common}") private Long REDIS_EXPIRE;

    @Autowired private RedisService redisService;

    public void setAdmin(UmsAdmin admin) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + admin.getUsername();
        redisService.set(key, admin, REDIS_EXPIRE);
    }

    public UmsAdmin getAdmin(String username) {
        String key = REDIS_DATABASE + ":" + REDIS_KEY_ADMIN + ":" + username;
        return (UmsAdmin) redisService.get(key);
    }
}

```

All cache keys are constructed with a prefix (`REDIS_DATABASE`) to prevent collisions across different environments and applications sharing the same Redis instance.

### Resilience Patterns

The `RedisCacheAspect` in [`mall-security/src/main/java/com/macro/mall/security/aspect/RedisCacheAspect.java`](https://github.com/macrozheng/mall/blob/main/mall-security/src/main/java/com/macro/mall/security/aspect/RedisCacheAspect.java) implements defensive programming by decorating cache calls. This aspect catches Redis failures and exceptions, ensuring that a downed cache or network interruption does not break the core business logic. The application can continue operating by falling back to database queries when the cache is unavailable.

## MongoDB for High-Throughput Persistence

### Schema-Flexible Document Storage

MongoDB handles data that requires high write throughput and flexible schemas, such as member browsing history. The `MemberReadHistory` entity contains optional product fields including name, price, and picture URL. Storing this in MongoDB allows the service to add or remove fields without requiring schema migrations or ALTER TABLE operations that would be necessary in MySQL.

### Repository Pattern

The `MemberReadHistoryRepository` interface in [`mall-portal/src/main/java/com/macro/mall/portal/repository/MemberReadHistoryRepository.java`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/java/com/macro/mall/portal/repository/MemberReadHistoryRepository.java) extends `MongoRepository` and leverages Spring Data MongoDB's query derivation capabilities.

```java
public interface MemberReadHistoryRepository 
        extends MongoRepository<MemberReadHistory, String> {
    Page<MemberReadHistory> findByMemberIdOrderByCreateTimeDesc(String memberId, Pageable pageable);
    void deleteAllByMemberId(String memberId);
}

```

This interface provides paginated queries sorted by creation time and bulk deletion operations with minimal boilerplate code, demonstrating how MongoDB handles high-volume read/write operations efficiently.

### Service Implementation

The `MemberReadHistoryServiceImpl` in [`mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberReadHistoryServiceImpl.java`](https://github.com/macrozheng/mall/blob/main/mall-portal/src/main/java/com/macro/mall/portal/service/impl/MemberReadHistoryServiceImpl.java) implements the business logic for tracking member browsing behavior. Each page view creates a new history record, leveraging MongoDB's append-only model for low-contention inserts.

```java
@Service
public class MemberReadHistoryServiceImpl implements MemberReadHistoryService {
    @Autowired private MemberReadHistoryRepository repository;
    @Autowired private UmsMemberService memberService;

    public int create(MemberReadHistory record) {
        UmsMember member = memberService.getCurrentMember();
        record.setMemberId(member.getId());
        record.setCreateTime(new Date());
        repository.save(record);
        return 1;
    }

    public Page<MemberReadHistory> list(Integer pageNum, Integer pageSize) {
        UmsMember member = memberService.getCurrentMember();
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
        return repository.findByMemberIdOrderByCreateTimeDesc(member.getId(), pageable);
    }
}

```

This service only contacts MongoDB for history data, while product-related information can be cached in Redis via `UmsAdminCacheServiceImpl` or other cache layers, ensuring a clear separation of concerns between high-speed caching and high-volume persistence.

## Integration Patterns and Performance Benefits

The combination of Redis and MongoDB in the Mall project creates a complementary architecture that addresses different performance bottlenecks:

1. **Redis eliminates hot-read load** on MySQL by caching frequently accessed data such as admin permissions and user sessions. This reduces database connection pool contention and query execution time for repetitive lookups.

2. **MongoDB handles write-heavy operations** that would overwhelm relational databases. Member browsing history generates high insert volumes with relatively simple query patterns, making MongoDB's append-only storage engine ideal for this workload.

3. **Graceful degradation** is achieved through the `RedisCacheAspect`, which ensures that Redis failures do not cascade into application failures. The system can operate in a degraded mode using direct database access when necessary.

4. **Consistent key naming** using the `REDIS_DATABASE` prefix prevents cache collisions and supports multi-environment deployments where multiple instances might share Redis clusters.

## Summary

- **Redis caching** in `mall-common` and `mall-security` modules provides high-speed data access for frequently read objects like admin details and permissions, significantly reducing MySQL load.
- **MongoDB integration** through Spring Data in `mall-portal` handles high-volume, schema-flexible write operations such as member browsing history, offering better performance than relational databases for append-heavy workloads.
- **Resilience patterns** like `RedisCacheAspect` ensure that cache failures do not disrupt core business operations, allowing graceful fallback to database queries.
- **Centralized configuration** via `BaseRedisConfig` and utility services like `RedisServiceImpl` provide consistent caching behavior across all modules with JSON serialization and configurable TTL values.

## Frequently Asked Questions

### How does Redis caching improve performance in the Mall project?

Redis improves performance by storing frequently accessed data such as admin authentication details and permission lists in memory. When a user requests this information, the application retrieves it from Redis in sub-millisecond time rather than executing SQL queries against MySQL. This reduces database connection pool contention and eliminates repetitive query execution for hot data paths, as implemented in `UmsAdminCacheServiceImpl`.

### When should I use MongoDB instead of MySQL in this architecture?

You should use MongoDB for data that exhibits high write volumes, flexible schemas, or simple query patterns that don't require complex joins. In the Mall project, MongoDB stores member browsing history because each page view generates a new record, creating an append-heavy workload that would cause table bloat and performance degradation in MySQL. MongoDB's document model also allows the `MemberReadHistory` schema to evolve without migration scripts.

### What happens if the Redis cache becomes unavailable?

The Mall project implements resilience patterns through `RedisCacheAspect` to handle Redis failures gracefully. If the cache becomes unavailable, the aspect catches connection exceptions and allows the application to fall back to direct database queries. This prevents a single point of failure from cascading into a complete system outage, ensuring that business operations continue in a degraded mode rather than failing entirely.

### How are cache keys organized to prevent collisions?

The project uses a hierarchical key naming strategy defined in `UmsAdminCacheServiceImpl` and other cache services. All keys incorporate the `REDIS_DATABASE` value as a prefix, followed by a functional key type (like `REDIS_KEY_ADMIN`), and finally the unique identifier (such as username). This structure ensures that different environments or modules sharing the same Redis instance cannot accidentally overwrite each other's data, supporting multi-tenant deployments safely.