20240422

귤금·2024년 4월 19일

Node.js 4기 TIL

목록 보기
82/86

Elastic Search

Amazon OpenSearch

Amazon OpenSearch Service 클러스터를 AWS Database Migration Service의 대상으로 사용

OpenSearch를 사용하기로 결정.
MySQL db의 데이터를 OpenSearch로 마이그레이션 하는 함수를 만들었다.

데이터 이전

Lambda에서 함수를 생성할 때 콘솔에서 직접 입력하여 사용할 수도 있긴 하지만... 나는 image 업로드 방식을 선택했다. AWS RDS에서 OpenSearch로 데이터를 이전하는 람다 함수를 개발하는 경우, 여러 기술적 의존성을 관리해야 한다. Docker 이미지로 람다 함수를 배포하면 의존성 관리도 편하고 추후 자동화까지 원활하게 진행될 수 있을 것 같았음.

Lambda 이미지 빌드용 dockerfile

위치 : ./data-migration

FROM public.ecr.aws/lambda/nodejs:latest

# 작업 디렉토리 설정
WORKDIR /var/task

# 의존성 파일 복사 및 설치
COPY package*.json ./
RUN npm install

# Lambda 함수 코드 복사
COPY . .

# 컨테이너 실행 시 호출될 핸들러 정보
CMD ["index.handler"]


마이그레이션에 사용할 파라미터는 파라미터 스토어에서 관리하기로 했다. 데이터 옮길 때마다 마지막 함수 실행 시간을 불러오고, 이후 수정되거나 추가된 데이터만 새로 입력해준다.

이렇게 정상적으로 데이터가 들어간다.

그런데... updated_at과 파라미터를 비교하는 조건을 걸었더니 새로 추가된 데이터는 정상적으로 이전되지만... 수정을 한 데이터는 새로 추가됨과 동시에 이전의 데이터는 opensearch에 그대로 남아있는 문제가 발생한다. 그래서... 색인 처리를 고려해 봄.

색인 처리

색인 처리 성능

성능 문제: 대량의 데이터를 자주 업데이트하거나 색인할 때는 성능 저하가 발생할 수 있다. 특히, goods ID를 사용하여 데이터를 덮어쓰는 작업은 추가적인 I/O를 발생시키며, 이는 네트워크 지연 및 데이터 처리 시간 증가를 초래할 수 있다.
배치 처리: 데이터를 개별적으로 색인하는 대신, 배치(batch) 형태로 데이터를 그룹화하여 한 번에 색인 처리하는 방법을 고려할 수 있다. 네트워크 호출 횟수를 줄이고 전체적인 처리 속도를 향상시킬 수 있는 방법.

LastMigrationTime은... 버려야 하나...?

굳이 안 버려도 될 듯.
LastMigrationTime 파라미터를 사용하면 마지막 마이그레이션 이후에 변경된 데이터만을 대상으로 하므로 처리해야 할 데이터 양을 줄일 수 있다. 색인 작업을 일단 최소화 하는 게 중요하다.

데이터 일관성과 성능 향상

  1. OpenSearch는 문서의 일부만을 업데이트하는 기능을 제공한다구 함.
  2. 병렬 처리 고려: 데이터를 여러 파티션으로 나누고 병렬로 처리하여 처리 속도를 향상... 그런데 goods 테이블 데이터를 병렬로 나눌 수 있나?
  3. Lambda 함수의 메모리와 타임아웃 설정을 조정
    지금은 최소 메모리/30초 타임아웃을 설정해 둠.

대수님 아이디어

굿즈 정보가 사실 재고 때문에 가장 많이 변경이 되니까... stocks와 연결해서 데이터를 이전하지 말고, 그냥 goods 데이터만 이전시켜서 사용하자. goods와 stocks를 외래키로 묶어둔 걸 풀고, 나중에 데이터 정합성 검사를 잃어버릴 수 있으므로 api상에서 철저히 검사/관리 하기로 함. 그러면 재고가 변경될 때마다 데이터 마이그레이션이 일어날 필요가 없고, 따로 관리를 하기 때문에 굳이 색인을 넣을 필요가 없고, 속도를 개선할 수 있다.
-> 외래키 연결을 끊을 필요가 있다는 걸 알게 됨.

프론트 구현

모노레포(monorepo) 파일구조

POTATO_SHOPPING_MALL/
├── .github/
├── .husky/
├── data-migration/
├── dist/
├── load-test/
├── log-history/
├── node_modules/
├── src/
├── test/
├── client/                <-- React 프론트엔드를 위한 새 폴더

기존 백엔드 프로젝트 안에 클라이언트 폴더를 만들었다. 사실 같은 모노레포 방식이라도 이 안에서 크게 server와 client로 분리하고 싶었지만... 프론트를 고려하지 않고 파일구조를 짰었기 때문에 이제 와서 나머지를 server로 빼려면 코드 정리가 어려워질 것 같았음.

0개의 댓글