
key에는 날짜값을 포함시킨다. value에는 사용자 id를 저장한다. @Service @RequiredArgsConstructor public class DailyActiveUserService { private final DailyActiveUserRepository dailyActiveUserRepository; private final RedisTemplate<String, String> redisTemplate; ... public void recordActiveUserWithRedis(Long userId) { LocalDate today = LocalDate.now(); String key = "dau:" + today.toString(); // dau:YYYY-MM-DD // Redis에 userId를 Set 자료구조로 저장 // Redis 명령어의 'SADD [key] [value]'와 동일하다. redisTemplate.opsForSet().add(key, userId.toString()); } public long getDauWithRedis(LocalDate date) { String key = "dau:" + date.toString(); // Redis에 저장된 Set을 활용하여 DAU를 계산 // Redis 명령어의 'SCARD [key]'와 동일하다. return redisTemplate.opsForSet().size(key); } }
@RestController @RequestMapping("/dau") @RequiredArgsConstructor public class DailyActiveUserController { private final DailyActiveUserService dailyActiveUserService; ... // 활동 유저 기록 API @PostMapping("/record/redis") public void recordActiveUserWithRedis( @RequestBody RecordActiveUserRequestDto recordActiveUserRequestDto ) { dailyActiveUserService.recordActiveUserWithRedis(recordActiveUserRequestDto.getUserId()); } // DAU 조회 API @GetMapping("/count/redis") public long getDauWithRedis( @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date ) { return dailyActiveUserService.getDauWithRedis(date); } }



import http from 'k6/http'; import {check} from 'k6'; export const options = { vus: 1000, duration: '10s', }; export default function () { // 1. 유저 활동 기록 const userId = Math.floor(Math.random() * 100000) + 1; // 1 ~ 100000 사이의 랜덤 userId const payload = JSON.stringify({ userId: userId, }); const params = { headers: { 'Content-Type': 'application/json', }, }; const recordRes = http.post('http://localhost:8080/dau/record/redis', payload, params); check(recordRes, { 'record status is 200': (r) => r.status === 200, }); // 2. DAU 조회 // 오늘 날짜를 YYYY-MM-DD 형식으로 가져온다. const today = new Date().toISOString().split('T')[0]; const countRes = http.get(`http://localhost:8080/dau/count/redis?date=${today}`); check(countRes, { 'count status is 200': (r) => r.status === 200, }); }
$ k6 run scripts/script_4-2.js

$ keys * # 데이터가 저장된 key 확인하기 $ SCARD dau:2026-01-08 # 해당 Set에 저장된 데이터 개수 확인하기 # MEMORY USAGE [key] $ MEMORY USAGE dau:2026-01-08 # 특정 key가 차지하고 있는 메모리 확인
