-->

일단 추천 알고리즘이 들어가기 시작하면 매우 복잡해진다. 여기선 아주 단순하게 구현할 수 있는 방법을 적어본다.

실시간으로 현재 인기 있는 게시글 상위 10개 정도를 추천하기 위해서 판단 기준이 필요하다.

  • 구매순
  • 조회순
  • 좋아요순
  • 댓글순

 

활동 로그를 이용한 실시간 적재

유저가 좋아요, 구매 등이 발생하면 이 테이블에 로그를 기록해 둔다. 

ACTIVITY_LOG_TABLE

Logical Name Physical Name Data Type Length 비고
활동로그 번호 ACTIVITY_LOG_NO number 19 PK
게시글 번호 POST_NO number 19 FK
활동 종류 ACTIVITY_TYPE varchar2 20 ORDER,
VIEW,
LIKE,
COMMENT
활동 수 ACTIVITY_CNT Int  
생성자 CREATED_BY number 19
생성일시 CREATED_AT timestamp    

Index는 POST_NO, CREATED_AT 두 컬럼을 사용한다.

유저가 게시글에 구매, 조회, 좋아요, 댓글이 달리면 기록하기 위한 테이블인데 물론 행동이 발생할 때마다 1 row씩 삽입하는 건 꽤나 비효율적일 것이다. 그래서 Redis 같은 Cache Store에 먼저 등록해 두고 일정 주기로 DB로 insert 할 수 있도록(Write-Back) ACTIVITY_CNT 컬럼을 두었다.

 

Redis 사용 전략

Value를 increment 만큼 증가시키는 HINCRBY 커맨드를 사용한다.

# 특정 사용자(77777)에 대해 views 증가
HINCRBY post:metrics:{postNo}:{userId} views 1

# 좋아요와 댓글은 삭제가 발생할 수 있다. 삭제 API 호출시에는 -1을 increment 해준다.
HINCRBY post:metrics:{postNo}:{userId} comment -1

# 모든 사용자 키 검색
KEYS post:metrics:{postNo}:*

다만 현재 키 계층구조에서 게시글 이후의 업데이트 대상 key만을 조회하려고 한다면 (모든 사용자 키 검색) 경우에 따라 사용하는 커맨드가 달라질 수 있다.

KEYS 커맨드는 Cluster Mode에서 사용할 수 없다. 정확히는 목적지 Node를 명시해야 해당 Node 에서만 탐색이 가능하다. 따라서 이 상황에서는 SCAN 명령어를 통해 조회하는 편이 낫다.

HGETALL 커맨드도 사용할 수 없고 키 조회 자체가 정책적으로 금지되어있다면 차라리 키만 SET에 담아서 DB에 insert 하고 지우는 방법도 있겠다.

# 메트릭을 저장할 Set 생성
sadd post:metrics post:metrics:{postNo}:{userId}
smembers post:metrics

 

5분 정도 주기를 설정해서 Redis에 누적된 데이터를 DB로 전송하는 스케줄링 작업을 세팅한다. 스프링 멀티모듈 사용하고 있다면 batch 모듈 만들어 작업할 수 있고 단일 작업이라 jenkins 같은 cicd 툴 이용해서 엔드포인트 호출하는 식으로 가능할 것 같다. cron 도 가능할 거고.

 

가중치를 이용한 분석 및 노출

특정 시간에 실시간 추천 게시글로 노출이 됐던 목록을 알아내려면 조회용 테이블이 따로 필요하다.

로그 테이블에 있는 데이터를 기준으로 조회 테이블에 데이터를 전부 다 넣고, 가중치에 따른 점수 계산을 실행한다.

그리고 기존 데이터는 inactive 상태로 변경한다. 

POST_METRICS_TABLE

Logical Name Physical Name Data Type Length 비고
메트릭 번호 METRICS_NO number 19 PK
게시글 번호 POST_NO number 19 FK
구매수 ORDERS number 5  
조회수 VIEWS number 5
좋아요 수 LIKES number 5  
댓글수 COMMENTS number 5  
점수 SCORE number 5,2  
상태 STATUS varchar 10 ACTIVE,
INACTIVE,
DELETE
생성자 CREATED_BY number 19
생성일시 CREATED_AT timestamp    
수정자 MODIFIED_BY number 19  
수정일시 MODIFIED_AT timestamp    

Index는 POST_NO, SCORE, CREATED_AT 를 사용한다.

 

그리고 가중치를 조절할 수 있도록 테이블을 생성하고 admin 서비스를 통해 조절하게 한다.

POST_METRICS_WEIGHT_TABLE

Logical Name Physical Name Data Type Length 비고
메트릭 번호 WEIGHT_NO number 19 PK
활동 종류 ACTIVITY_TYPE number 19 ORDER,
VIEW,
LIKE,
COMMENT
가중치 WEIGHT number 5,2  
상태 STATUS varchar 10 ACTIVE,
INACTIVE,
DELETE
생성자 CREATED_BY number 19
생성일시 CREATED_AT timestamp    
수정자 MODIFIED_BY number 19  
수정일시 MODIFIED_AT timestamp    

그리고 초기 데이터를 넣어주면 된다.

+ Recent posts