티스토리 뷰

Server

[Spring] Redis 실제 사용해보기

니용 2022. 12. 16. 22:09
반응형

이전 글에서 Redis Connection 과 Configuration 을 진행하였다면 다음으로는 Redis 실제로 사용하는 코드를 작성해볼까 합니다. 

이번에는 서버의 헬스 체크를 하는 모듈을 작성해보았어요. 

@Component
public class RedisComponent {

    @Resource(name = "redisTemplate")
    private ValueOperations<String, String> valueOperations;
    private String checkedSuffix = "-checked";

    public boolean isServerDown(String serverName) {
        final String value = valueOperations.get(serverName);
        if(value == null) {
            setServerStatus(serverName, "UP");
            valueOperations.set(serverName + checkedSuffix, "", Duration.ofHours(2));
            return false;
        }

        final String checked = valueOperations.get(serverName + checkedSuffix);
        return value.equals("DOWN") && StringUtils.isBlank(checked);
    }

    public void setServerStatus(String serverName, String status) {
        valueOperations.set(serverName, status, Duration.ofHours(2));
    }

    public void setSendChecked(String serverName) {
        valueOperations.set(serverName + checkedSuffix, "checked", Duration.ofHours(2));
    }
}

 

이전 글에서 Bean으로 등록한 redisTemplate 의 키값을 가진 RedisTemplate 을 가져옵니다.

@Resource(name = "redisTemplate")
private ValueOperations<String, String> valueOperations;

 

public boolean isServerDown(String serverName) {
    final String value = valueOperations.get(serverName);
    if(value == null) {
        setServerStatus(serverName, "UP");
        valueOperations.set(serverName + checkedSuffix, "", Duration.ofHours(2));
        return false;
    }

    final String checked = valueOperations.get(serverName + checkedSuffix);
    return value.equals("DOWN") && StringUtils.isBlank(checked);
}

그리고 함수 중 하나인 현재 서버가 내려갔는지 체크하는 로직입니다. 이 로직에서 보시다시피 Redis DB 에서 값을 가져올 때는 valueOperations.get(key) 의 구조로 가져오게 되고, 데이터 조회를 하여 없는 경우 null 을 가져옵니다. 가장 안전한 방법인 StringUtils.isBlank(valueOp.get(key)) 값으로 가져오는 것이 안전한 방법입니다.

 

public void setServerStatus(String serverName, String status) {
    valueOperations.set(serverName, status, Duration.ofHours(2));
}

위의 함수에서는 그저 Redis DB 에 set을 하는 것이 전부입니다. valueOp.set(key, value, Duration) 을 파라미터로 넣어 호출하였고, 제가 가장 많이 사용하는 방법 중 하나입니다. Duration 을 설정해주지 않으면 캐시 메모리에서 데이터가 증발하는 시간이 정해지지 않아 계속 남은 쓰레기 값이 될 수 있습니다.

ValueOperation interface

 

그리고 값이 존재할때만 셋을 해주거나 여러 값을 세팅하는 함수들도 있으니 참고하면 좋겠습니다. (워낙 설명도 잘 되어 있습니다.)

 


 

사실 이렇게 Operation 을 class 변수로 선언하여 사용하는 것은 좋지 않습니다. 하지만 저는 이런 구조가 익숙하기도 하고 HashMap<String, String> 구조로 되어 있는 것을 꺼내쓰기 편한 구조이고 빠른 접근 방법이어서 그런지 편했습니다.

아래는 각 종 오퍼레이션을 메소드 및 자료구조별로 나눠둔 표입니다.

Method Operation 자료구조
opsForValue() ValueOperations String
opsForList() ListOperations List
opsForSet() SetOperations Set
opsForZSet() ZSetOperations Sorted Set
opsForHash() HashOperations Hash

 

1. opsForList

List를 반환하는 Redis List Type 의 예제입니다. 단순 리스트를 반환하는 것이 아닌 range 메소드를 활용하여 범위 값으로 가져올 수 있습니다.

private RedisTemplate<String, Object> redisTemplate;
public List getOpsForList() {
    redisTemplate.opsForList().rightPush("key", "value");
    RedisOperations<String, Object> operations = redisTemplate.opsForList().getOperations();
    final List<Object> range = operations.opsForList().range("chatNumber", 0, -1);
    return range;
}

 

2. opsForSet

Redis 내에서 set 의 형태로 제공되는 오퍼레이션입니다. 해당 타입은 속도가 정말 빠르지만 순서가 없습니다. add, pop 으로 데이터를 넣고 조회할 수 있습니다.

 public void getOpsForSet() {
    final SetOperations<String, Object> stringObjectSetOperations = redisTemplate.opsForSet();
    stringObjectSetOperations.add("key", Object.class); // 데이터 추가
    stringObjectSetOperations.pop("key"); // 데이터 삭제
}

 

 

 

3. opsForZSet

Redis 내에서 정렬된 set을 지원합니다. 

public void getOpsForZSet() {
    ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();
    zSetOperations.add("Key", "Value", score);
    System.out.println(zSetOperations.range("ZKey", 0, -1));
}

 

4. opsForHash

HashMap을 입력하고 그 데이터를 가져올 수 있는 2중 맵의 구조 오퍼레이션을 제공합니다. 메모리 차지도 적게한다고 합니다. 수백만개의 오브젝트를 넣을 수 있어서 엄청난 효율성을 가진다고 하네요.

public void getOpsForHash() {
    HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();
    Map<String, Object> map = new HashMap<>();
    map.put("key1", "value1");
    map.put("key2", "value2");
    map.put("key3", "value3");
    hashOperations.putAll("keys", map);

    String key1 = (String) redisTemplate.opsForHash().get("keys", "key1");
    String key2 = (String) redisTemplate.opsForHash().get("keys", "key2");
    String key3 = (String) redisTemplate.opsForHash().get("keys", "key3");
}

 

반응형
댓글
공지사항