In this tutorial, we will explore how to test the performance of Redis using Spring Boot. We will compare Spring Data Redis (reactive) and native Redis clients to see the differences in execution speed for a large number of operations.
1. Project Setup
Before starting, ensure your project has the necessary dependencies:
Dependencies
- Spring Boot Starter Data Redis (Reactive)
For reactive Redis operations. - Lettuce (Reactive Redis Client)
Provides low-level reactive Redis operations.
Add these to your pom.xml
or build.gradle
:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </dependency>
Ensure your Redis server is running locally or provide the IP and port in application.properties
if it is running remotely:
spring.redis.host=127.0.0.1 spring.redis.port=6379
2. Understanding Redis Templates
Spring Data Redis exposes template beans to interact with Redis:
ReactiveRedisTemplate<K, V>
for reactive operations.- Supports different operations like:
- Value operations:
increment
,set
,get
,delete
. - Hash operations:
put
,get
,delete
.
- Value operations:
The template works like JDBC Template, providing a high-level abstraction for Redis operations.
3. Performance Test Plan
We want to measure how long it takes to execute a large number of Redis operations:
- Test scenario: Increment a counter 500,000 times in Redis.
- Compare execution times:
- Using Spring Data Redis (Reactive).
- Using native Redis client (Lettuce).
Step 1: Create a Reactive Redis Template
@Autowired private ReactiveRedisTemplate<String, String> reactiveRedisTemplate;
- This template allows reactive operations like
increment
,get
,delete
on keys.
Step 2: Prepare Value Operations
ReactiveValueOperations<String, String> valueOps = reactiveRedisTemplate.opsForValue();
valueOps.increment(key)
increments the value of a key.- We will perform 500,000 increment operations to measure performance.
4. Measure Execution Time
Step 1: Record Start Time
long startTime = System.currentTimeMillis();
Step 2: Execute Operations
- Loop 500,000 times, incrementing a counter in Redis:
for (int i = 0; i < 500_000; i++) { valueOps.increment("counter").subscribe(); }
Step 3: Record End Time
long endTime = System.currentTimeMillis(); System.out.println("Time taken: " + (endTime - startTime) + " ms");
This measures the total time taken for 500,000 operations.
5. Warm-Up Runs
- The first run may be slower due to initialization overhead.
- Run the test 3 times and consider the average time after warm-up.
6. Observed Performance
Example observations:
Client | Average Time (500,000 ops) |
---|---|
Spring Data Redis Reactive | ~17 seconds |
Native Redis (Lettuce) | ~10.5 seconds |
- Using native Redis client significantly improves performance (~7 seconds faster in this test).
- The performance difference exists because Spring Data Redis reactive template introduces some overhead.
7. Using Native Redis with Spring Boot
- If you want maximum performance, use Lettuce directly:
@Autowired private RedisClient redisClient; // Native Lettuce client StatefulRedisConnection<String, String> connection = redisClient.connect(); RedisCommands<String, String> commands = connection.sync(); for (int i = 0; i < 500_000; i++) { commands.incr("counter"); }
- This approach bypasses Spring Data Redis templates and uses the native API.
8. Key Takeaways
- Spring Data Redis Reactive is convenient but slightly slower due to abstraction overhead.
- Native Redis clients like Lettuce provide better raw performance for bulk operations.
- Always do warm-up runs to account for initial startup delays.
- Reactive templates are good for non-blocking applications, but performance-sensitive operations may benefit from direct native clients.