20240221

귤금·2024년 2월 21일

Node.js 4기 TIL

목록 보기
40/86

Today?

Node 4기 챌린지반 - Instagram (Part.2)

레코드 캐싱 비결 : Redis 해시

캐싱?

  1. 레코드 저장과 응답 성능 향상을 위해서...
  2. 데이터 저장, EC2 고메모리 유형에 맞아야 함
  3. 기존 인프라에 맞아야 함
  4. 서버가 다운되어도 지속성(다시 채울 필요x)

SQL 대신 Redis를 사용하는 인스타그램...

Redis란?

  • 캐싱을 할 때 가장 많이 사용되는 소프트웨어
  • 메모리에 {key - value}를 저장... 키-밸류 스토어.
    • 한 쌍을 하나의 해시 내에 효율적으로 그룹화하여 저장 -> 메모리 사용 감소!
    • 어떤 해시에 속하는지 결정(해시함수)
      • 어떤 바구니(버킷)에 담기는지!
      • 인스타그램의 경우, 미디어 ID를 1000으로 나누어서 버킷 번호를 결정함 -> 균등한 분포
      • 버킷 번호를 저장, 이걸로 해당 해시를 조회... 'hashbucket:123' 같은 key로 Redis에서 해시 조회, 이제 이 버킷에서 'abc' 조회
  • 정렬된 세트, 리스트와 같은 강력한 집합 유형 제공

링크드리스트 자료구조

  • 테일(꼬리) 존재

추천기능

추천 알고리즘
유저의 활동 내역을 기반으로 구현함... 이렇게 쌓인 데이터를 활용

베이지안 추론

  • 베이즈 정리 : 사후 확률 = 우도*사전확률/증거
  • 사전 확률
    • 우리가 이미 알고 있는 특정 가설의 확률
    • 예 : 동전의 앞면이 나올 확률은 1/2
  • 우도
    • 주어진 가설 하에서 관찰된 데이터의 확률
    • 예 : 동전을 10번 던져서 실제로 앞면이 7번 나왔다 -> 우도의 확률
  • 사후 확률
    • 데이터를 보고 나서 업데이트된 가설의 확률
    • 사전 확률과 우도를 결합하여 얻어지는 확률

즉, 계속 검증하고 계속 사전확률과 비교하여 더 나은 예측을 함
점진적으로 더 나온 콘텐츠 제공

인스타가 생각하는 게시물 추천의 필요조건

  1. 인스타그램 알고리즘 자체적으로 랭킹이 높은 게시물 추천
    • 랭킹 시스템 : 추천에 있어 필수적 요소...
    • 서비스마다, 개인마다 랭킹 산정
  2. 특정 유저의 게시물만 너무 많이 나오지 않도록 추천

피드&스토리 기능의 랭킹 산정 요소

  1. 게시물 그 자체 요소
    • 얼마나 인기 있었는지 + 얼마나 많은 사람들이 좋아했는지
    • 동영상의 경우 재생시간은 얼마나 되는지
    • 게시물 첨부된 위치
  2. 게시한 사람에 대한 정보
    • 유저 기준으로 얼마나 흥미로운 사람인지
    • 다른 유저들이 게시한 사람과 얼마나 상호작용을 하였는지
      • 예 : 내가 팔로우한 사람의 팔로잉
  3. 유저의 활동내역
    • 무엇에 관심있는지
    • 그리고 도전적인 피드도 계속 던져줌(좋아하는 걸 더 늘려나가고, 서비스를 계속 이용하도록)

새로운 컨텐츠(도전적인 컨텐츠) 추천 기준

릴스 랭킹 산정 요소

  • 유저의 활동 내역
    • 최근에 좋아하거나 댓글 단 내역 확인 후 예측
  • 게시한 사람과 상호작용한 내역
  • 릴 자체에 대한 정보
    • 비디오 기본 정보 (픽셀, 프레임, 오디오트랙 등)
  • 게시한 사람에 대한 정보
    • 게시자의 인기

개인과제

구조 분해 할당...

사실 너무 기초적인 개념인데 내가 잡고 가지 못했던 것 같다...

3계층 아키텍처로 기존 코드를 리팩토링하면서, req.user에 할당했던 userId를 컨트롤러 계층에서 서비스 계층으로 넘어가는 시점에 불러오지 못하는 문제가 발생했다.

const userId = req.user.userId; // 서비스 계층에서 불러와짐 
const {userId} = req.user.userId; // 서비스 계층으로 전달되지 않음
  • 이 코드는 req.user 객체에서 userId 속성을 참조하여, 그 값을 새로운 userId라는 이름의 변수에 할당한다.
  • 여기서는 req.user 객체의 userId 속성 값을 직접적으로 userId 변수에 할당하고 있다.
  • 두 번째 줄의 코드는 구조 분해 할당을 시도하고 있으나, 잘못 사용되었다. 구조 분해 할당은 객체나 배열로부터 속성이나 요소를 쉽게 추출할 수 있게 해주는 JavaScript의 문법인데... 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담는 표현식이다.
  • 따라서 올바르게 사용하기 위해서는 req.user.userId가 아니라 req.user에서 직접 userId를 구조 분해하는 방식으로 사용되어야 한다.

즉, 만약 req.user 객체 내에 userId 속성이 있고, 나처럼 구조 분해 할당으로 불러오고 싶다면 이렇게 코드를 짜야한다.

const { userId } = req.user;

회고

프로젝트 하나를 전부 리팩토링 하고 나니까 이제 겨우 각 계층에서 뭘 하는지 조금 이해한 느낌이다... 😥😥 그러나 아직 jest에 익숙하지 않아서 테스트 코드를 완성하지 못했다. 슬프다..

0개의 댓글