[230315 - TIL] cache 사용시 고려할 점 - 캐시 데이터의 유효성

Dongwoo Kim·2023년 3월 15일
0

TIL / WIL

목록 보기
94/113

1. 개요

최근 api서버에 응답데이터를 cache를 이용해서 관리하였다. 캐시 기능을 구현하면서 추가적으로 고려해야했던 것과 부수적으로 구현한 기능을 정리해보자.


2. 캐시 데이터의 유효성

가장 큰 관점은 캐시에 저장한 데이터가 언제까지 유효한가? 이다. 해당 데이터가 수정되거나 다시 계산해야할 필요가 있으면 캐시데이터를 업데이트해야할 것이다. 내가 구현했던 기능에서의 고려했던 점은 다음과 같다.

2-1) 데이터를 업데이트할 때

해당 api는 DB에서 가져온 데이터를 계산해서 결과값을 요청 데이터에 따라 캐시에 저장하는 기능이였다. 따라서 DB의 데이터가 업데이트가 되면 결과값도 달라지기 때문에 캐시데이터도 업데이트해야할 필요성이 있다.

2-2) 새로운 데이터로 계산해야할 때

적용기간에 따라 계산해야할 데이터를 필터링한 후 계산을 했기 때문에 현재 시간에 따라 캐시데이터에 저장할 때는 유효하지 않았지만 시간이 지남에 따라 계산에 사용해야할 데이터가 있을 수 있다. 따라서 업데이트 해야할 시간을 데이터와 함께 저장해야했다.

2-3) 적용기간이 끝난 데이터가 있을때

반대로 시간이 지남에 따라 적용기간이 끝나서 계산에 사용하지 말아야할 데이터가 있을 수 도 있다. 따라서 2-2)에서 계산한 캐시업데이트시간과 현재 사용한 데이터 중에서 가장 빠른 종료시간과 비교해서 캐시업데이트시간을 업데이트하는 로직을 추가했다.


3. 코드

해당 코드의 로직을 정리하자면 다음과 같다.

def get_target_data_obj_dict_and_cache_update_date(product_):
"""해당 상품에 대한 적용 data 오브젝트들을 반환하는 함수
"""

    # 적용가능 설정에 따른 데이터 필터링
    data_obj_list_by_period = Data.objects.filter(query)

    # 적용예정인 data들로부터 캐시업데이트시간 계산
    now = timezone.now()
    cache_update_date = get_cache_update_date_from_future_data(data_obj_list_by_period, now)

    # 적용시작된 data 필터링
    data_obj_list_by_start_date = filter_data_list_by_start_date(data_obj_list_by_product, now)

    # 유형별로 적용할 data 탐색
    target_data_obj_dict = find_target_data_obj_by_data_type(data_obj_list_by_start_date, product_obj)

    # 적용할 data들의 종료시간으로부터 캐시업데이트시간 계산
    cache_update_date = get_cache_update_date_from_data_end_date(target_data_obj_dict, cache_update_date)

	return target_data_obj_dict, cache_update_date
def get_target_data_data_with_cache(product_):
"""해당 상품에 대한 적용 data 조회 & 캐시화 함수 : 캐시식별자 - 상품번호
"""

	# 상품번호에 대한 적용 data 정보가 캐시에 있는지 확인
    target_data_cache_id = '_'.join(['target_data',str(product_.product_no)])
    target_data = cache.get(target_data_cache_id)

    now = timezone.now()

    # 적용 data 정보가 캐시에 없거나 업데이트 날짜가 지났으면 새롭게 적용혜택 조회
    if (not target_data 
            or (target_data["cache_update_date"] is not None 
                and target_data["cache_update_date"] <= now)):

        target_data_obj_dict, cache_update_date = get_target_data_obj_dict_and_cache_update_date(product_)
       
        # 계산 로직
        tartget_data = calculate_discount_price(target_data_obj_dict)
       
        target_data = {
            "target_data": tartget_data,
            "cache_update_date": cache_update_date,
        }

        cache.set(target_data_cache_id, target_data)

    return target_data
profile
kimphysicsman

0개의 댓글