본문 바로가기

Spring boot

RedisTemplate.opsForValue().decremet()

반응형

이전 포스팅에서 명시적으로 락을 걸어주고 MySQL락과 성능 테스트를 했는데 별 차이가 안났엇다.

 

이전 포스팅 : https://red-tiger.tistory.com/118

 

Spring Redis 분산 락 사용법

우선 Redis의 고급 기능 들을 지원해주는 Redisson 클라이언트 종속성을 build.gradle에 넣어준다 당연한 얘기지만 로컬환경에 redis를 미리 다운 받아 놔야한다.macOS에서는 brew 로 쉽게 설치가 가능하다

red-tiger.tistory.com

 

 

그런데 알고보니 해당 key에 해당하는 value를 별도의 락 없이(정확히 얘기하면 redis 자체가 원자적으로 작동한다) value를 줄여주는 메소드를 발견했다.

 public void decreaseValueWithLock(String key){


        redisTemplate.opsForValue().decrement(key);

        /*
        // RLock 인스턴스를 생성합니다. key 값에 "_lock"을 붙여서 고유한 락 이름을 생성합니다.
        RLock lock = redissonClient.getLock(key + "_lock");

        try{
            // tryLock 메서드를 사용하여 락을 시도합니다. 10초 동안 락을 기다리고, 락을 획득한 후에는 5초 동안 락을 유지합니다.
            if(lock.tryLock(10,5, TimeUnit.SECONDS)){
                try{
                    Integer value = redisTemplate.opsForValue().get(key);
                    if(value != null & value > 0){
                        value--;
                        redisTemplate.opsForValue().set(key,value);
                    }
                } finally{
                    // try 블록 내에서 작업이 끝나면 항상 락을 해제합니다.
                    lock.unlock();
                }
            } else{
                // 락을 획득하지 못했을 경우 메시지를 출력합니다.
                System.out.println("Could not acquire lock for key : " + key);
            }
        } catch (InterruptedException e){
            // 인터럽트 예외가 발생한 경우 현재 스레드의 인터럽트 상태를 설정합니다.
            // tryLock 메서드 호출 중 인터럽트가 발생할 수 있으므로 이를 처리하기 위한 catch 블록
            Thread.currentThread().interrupt();
        }*/
    }

 

바로 RedisTemplate.opsForValue().decrement() 이다

심지어 속도도 엄청 빠르다!! 티켓 10만개, 멀티스레드 2개 에서 18초 정도가 나왔었는데

 

 

 

저 메소드를 활용해서 하면 7초 밖에 안나온다!!! 

그래서 복잡한 로직 없이 해당 key값의 value만 낮춰줄꺼면 저 메소드를 사용해주면 확실한 성능 차이를 느낄 수 있다.

반응형