ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 서버리스 카카오톡 챗봇 만들기: 4. DynamoDB Table 만들기
    주제탐구/튜토리얼 2020. 8. 16. 21:32

    이전 글에서는 카카오톡 오픈빌더를 활용해서 일기 작성에 필요한 정보를 사용자에게 받아내는 플로우를 완성했었다.

    이번 글부터는 이 플로우를 적절한 백엔드와 연결해서 실제로 일기가 저장될 수 있도록 하려고 한다.

     

    첫 번째 글에서 미리 말했었지만 AWS를 사용해서 서버리스 백엔드를 만들 예정이기 때문에...

    AWS 계정이 필요하다. 계정이 없다면 이런 글을 참고해서 계정을 하나 만들고 오자.

    계정을 만들었고, AWS 콘솔에 로그인을 해서 이런 화면이 떴다면 준비가 끝난 것이다.

     

    이 콘솔을 사용해서 필요한 리소스를 차근차근 만들어 보고, 서로 연결해서 백엔드를 만들 것이다.

     

    주의사항

     

    모든 리소스는 사용량에 따라서 과금되는 것으로 준비했고, 혼자서 테스트로 사용하는 정도면 0원이 찍힐 가능성이 높지만,

    혹시 모를 위험을 방지하기 위해서 비용을 자주 확인하고, 실습이 끝나면 생성한 리소스는 바로바로 삭제하는 것이 좋다.

     

    오른쪽 상단 계정 이름을 클릭 -> My Billing Dashboard를 클릭하면 현재까지의 비용을 확인할 수 있다.

     

    DynamoDB 테이블 만들기

     

    가장 먼저 일기를 저장할 DB를 만들어야 한다.

    여기서는 서버리스 DB로 활용할 수 있고 가장 간단하게 생성할 수 있는 DynamoDB를 사용해 보자.

     

    DynamoDB는 AWS의 관리형 NoSQL 데이터베이스 서비스로, 비정형 데이터를 저장하기 쉽고

    On-Demand 옵션을 선택하면 읽기·쓰기 요청에 따라 컴퓨팅 자원의 사용량을 줄어들고 늘어나게 할 수 있다.

    즉, 요청이 없으면 컴퓨팅 자원도 사용되지 않고, 요금도 나오지 않는다. 👍

     

    단점이라면 (서버리스에 공통으로 적용되는 얘기지만) 느릴 수 있다는 것이다.

    요청이 장시간 들어오지 않았을 때는 AWS에 컴퓨팅 자원을 뺏기게 되고,

    그후 요청이 들어오면 컴퓨팅 자원을 부랴부랴 할당받으면서 지연이 생기게 된다. Cold Start라고 하는 현상이다.

     

    이 글에서는 0원짜리 챗봇 백엔드를 지향하기 때문에 지연 정도는 좀 봐줄 수 있다는 기조로 구성하고자 한다.

     

    어쨌든 콘솔로 돌아가서 DynamoDB 테이블을 만들어 보자. 상단 Services에서 DynamoDB를 찾아 들어간다.

     

    테이블 만들기를 클릭한다.

    (만약 UI가 바뀌었으면 좌측 테이블 탭을 찾아 들어가면 보일 것이다.)

     

    테이블명은 코드상에서 식별할 수 있도록 적절한 이름으로 정한다. 여기서는 Diaries라고 정했다.

     

     

    그리고 나면 기본 키를 입력해야 한다. 이건 뭘까?

    이것을 이해하기 위해서는 먼저 파티션이 무엇인지 설명할 필요가 있다.

     

    DynamoDB는 10밀리초 미만의 높은 성능을 제공하기 위해 내부적으로 데이터를 여러 개의 물리적 공간에 나눠 저장한다.

     

    왜 데이터를 나눠서 저장하는 게 성능에 도움이 될까? 이는 국어사전과 비슷한 원리다.

    국어사전을 보면 반달 모양으로 움푹 파여 'ㄱ', 'ㄴ', 'ㄷ', 처럼 앞 글자가 쓰여 있는 사전이 있다.

    (이 반달 모양을 반달색인이라고 한다.)

     

     

    만약 이 반달색인이 없다면 '나뭇가지'라는 단어를 찾기 위해서 온 사전을 훑어 보아야 하지만,

    반달색인이 있다면 'ㄱ'을 건너뛰고 'ㄴ'과 'ㄷ' 사이만 찾아볼 수 있어 시간을 절약할 수 있다.

     

    이런 반달색인 역할을 하는 것이 파티션이다.

    DynamoDB는 우리가 제공한 파티션 키를 토대로 데이터를 나누어 저장하고,

    나중에 특정 파티션 키의 데이터를 찾아야 하면 그 파티션만 훑어보면서 데이터를 제공한다.

     

    그렇기 때문에 규모에 상관없이 10밀리초 미만의 성능을 제공한다고 말할 수 있는 것이다.

     

    AWS가 그렇게 얘기했다!

    그렇다면 어떤 데이터를 파티션 키로 지정할 수 있을까? 우리가 저장해야 하는 데이터를 생각해 보자.

    지금까지 챗봇을 통해서 받기로 했던 데이터는 다음과 같다.

     

    1. 날짜
    2. 날씨
    3. 제목
    4. 내용

    그런데 생각해 보면, 남이 저장한 일기를 내가 보는 일이 있어서는 안 된다.

    지금까지 내가 저장한 일기는 해당 챗봇과 대화하고 있는 나만이 볼 수 있어야 한다.

    그러기 위해서는 유저의 고유 식별자가 필요하다. 여기서는 유저ID라고 하자.

    (이 값은 오픈빌더가 백엔드로 요청을 보낼 때 알아서 만들어서 제공해 준다. 지금은 걱정하지 말자)

     

    즉 우리가 유저에게 받은 데이터 + 유저ID를 DynamoDB에 저장하면,

    나중에 일기를 조회하는 기능을 만들 때 해당 유저의 일기만 골라서 보여줄 수 있다.

     

    1. 유저ID
    2. 날짜
    3. 날씨
    4. 제목
    5. 내용

    이 중 파티션 키는 무엇으로 정해야 할까?

    하나 생각해야 할 점은, 물리적 위치가 동일한 데이터를 가져오는 것이 분산된 데이터를 가져올 때보다 더 빠르다는 점이다.

    사전에서 'ㄴ'으로 시작하는 단어 10개를 찾는 것과, 'ㄱ' 단어 4개, 'ㄴ' 단어 4개, 'ㄷ' 단어 2개를 찾는 경우를 생각해 보자.

    아무래도 전자가 빠를 것이다.

     

    즉 데이터를 조회할 때, 가능한 적은 수의 파티션을 접근하도록 파티션 키를 지정하면 성능 측면에서 이득을 볼 수 있을 것이다.

    그렇다면 우리가 만든 챗봇에서 어떤 조건을 통해 일기를 필터링할지 생각해 본 뒤,

    읽어낼 데이터에서 가장 단일한 값을 가질 만한 것으로 파티션 키를 정하는 게 좋을 것이다.

     

    거기에 하나 더 욕심을 부리자면, 파티션이 균등하게 나뉠 만한 필드로 파티션 키를 정하는 게 좋을 것이다.

    가령 테이블에 (ID, 닉네임, 성별, 생년월일, 메일주소) 등이 담긴 유저 데이터를 저장해야 하는데,

    가장 단일할 것 같다는 이유로 성별을 파티션 키로 지정하면 어떻게 될까?

    유저가 십만, 백만이 되어도 파티션은 3~4개로밖에 나뉘지 않을 것이다. 파티션을 나누는 의미가 없어진다.

     

    즉 조회할 때 가능한 적은 수의 파티션에 접근하게 하면서, 그 값이 다양성을 가졌다면

    가장 적절한 파티션 키가 될 것이다.

     

    앞서 언급했는지 모르겠지만, 우리는 챗봇을 통해 해당 유저가 남긴 최대 일주일간의 일기를 조회할 수 있도록 하려고 한다.

    즉 유저ID와 날짜를 기준으로 일기를 조회하는 것이다. 이때 해당 유저가 남긴 일기만을 읽어야 하기 때문에,

    읽어야 하는 일기의 유저ID는 모두 동일하다.

     

    거기에 유저ID는 접속한 사용자에 따라 모두 다르기 때문에 다양성 또한 가지고 있다.

    따라서 유저ID를 파티션 키로 지정하는 게 적절할 것이다.

     

    필드 하나 입력하는데 설명이 너무 길어졌다. 큰일났다

    아무튼 파티션 키를 입력해 주자.

     

    그런데 하나 함정이 있다.

    기본 키에 파티션 키 하나만 지정한 경우에는, 테이블에 있는 각각의 아이템이 서로 다른 파티션 키 값을 가져야 한다.

    무슨 말인고 하니 UserId 하나당 한 개의 일기만 저장할 수 있게 된다는 말이다.

    일기를 하나밖에 못 쓰는 일기 챗봇이라니...

     

    적어도 날짜별로 하나씩은 일기를 저장할 수 있어야 한다.

    따라서 '정렬 키 추가'를 체크하고, 정렬 키로 '날짜'를 지정해 주자. 여기서는 WriteDate라고 적어준다.

     

    (그냥 Date라고 써도 사용은 가능하지만, DynamoDB에서 Date는 예약어이기 때문에 나중에 질의할 때 별도의 처리를 해 주어야 한다.

    튜토리얼을 복잡하게 만들 것 같아 여기서는 우회하려고 한다.)

     

     

    이렇게 파티션 키와 정렬 키를 조합하면, 동일한 파티션 키를 가지더라도 정렬 키가 다른 아이템들을 저장할 수 있다.

    즉 UserId가 같더라도 날짜가 다른 일기들을 저장할 수 있게 된다.

     

    나머지 설정들을 마저 하자.

    하단의 '기본 설정 사용' 체크박스를 해제하면 '읽기/쓰기 용량 모드' 섹션이 보인다.

    우리는 사용한 만큼만 비용을 지불하고 싶으므로 '온디맨드'를 선택한다.

     

    (온디맨드는 프리 티어에서 커버해 주지 않는다. 만약 이게 불안하면 '할당됨'을 선택해도 된다.

    다만 온디맨드는 적어도 백만 건 이상의 쓰기·읽기 요청이 들어와야 비용이 청구되기 시작해서 테스트용으로는 충분하다.)

     

    마지막으로 '생성' 버튼을 클릭하면, 약 10~20초 안으로 테이블이 생성된다. 🎉

     

    이 테이블과 챗봇을 이어주는 작업은 다음 글에서 진행하려고 한다.

Designed by Tistory.