How to Optimize Performance Using Redis and MongoDB in the Mall E-Commerce Project
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. 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 extends this base configuration and enables Spring caching annotations.
@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 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 demonstrates practical Redis usage for performance optimization. This service stores authenticated admin objects and permission lists with a configurable TTL defined by REDIS_EXPIRE.
@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 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 extends MongoRepository and leverages Spring Data MongoDB's query derivation capabilities.
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 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.
@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:
-
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.
-
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.
-
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. -
Consistent key naming using the
REDIS_DATABASEprefix prevents cache collisions and supports multi-environment deployments where multiple instances might share Redis clusters.
Summary
- Redis caching in
mall-commonandmall-securitymodules 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-portalhandles high-volume, schema-flexible write operations such as member browsing history, offering better performance than relational databases for append-heavy workloads. - Resilience patterns like
RedisCacheAspectensure that cache failures do not disrupt core business operations, allowing graceful fallback to database queries. - Centralized configuration via
BaseRedisConfigand utility services likeRedisServiceImplprovide 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →