모듈 3: Google Cloud NBS에서 Cloud Datastore로 마이그레이션

1. 개요

이 Codelab 시리즈 (자기 주도형 실습 튜토리얼)는 Google App Engine (표준 환경) 개발자가 일련의 이전을 안내하여 앱을 현대화할 수 있도록 돕는 것을 목표로 합니다. 가장 중요한 단계는 차세대 런타임이 더 유연하고 다양한 서비스 옵션을 제공하기 때문에 원래의 런타임 번들 서비스로부터 벗어나는 것입니다. 새로운 세대의 런타임으로 이동하면 Google Cloud 제품과 보다 쉽게 통합하고, 지원되는 다양한 서비스를 사용하고, 최신 출시 버전을 지원할 수 있습니다.

이 선택사항 가이드는 개발자에게 Datastore 서비스와 통신하기 위해 클라이언트 라이브러리로서 Cloud NBS에서 Cloud Datastore로 마이그레이션하는 방법을 보여줍니다. Python 3와 호환되기 때문에 이 마이그레이션이 선택사항입니다. 이 마이그레이션은 이미 Cloud Datastore를 사용 중인 다른 앱과 일관된 코드베이스 및 공유 라이브러리를 빌드하려는 사용자에게만 해당됩니다. 이 내용은 '백그라운드' 섹션으로 이동합니다.

학습 목표

  • Cloud NBS 사용 (익숙하지 않은 경우)
  • Cloud NBS에서 Cloud Datastore로 마이그레이션
  • 추가로 앱을 Python 3로 마이그레이션

필요한 항목

  • 활성 GCP 결제 계정이 있는 Google Cloud Platform 프로젝트
  • 기본 Python 기술
  • 기본 Linux 명령어에 관한 실무 지식
  • App Engine 앱 개발 및 배포에 관한 기본 지식
  • 작동하는 모듈 2 App Engine 2.x 또는 3.x

설문조사

이 Codelab을 어떻게 사용할 예정인가요?

<ph type="x-smartling-placeholder"></ph> 읽어보기만 해도 됩니다. 읽고 연습 활동을 완료하세요

2. 배경

Cloud NFS는 장기 App Engine 개발자를 위한 훌륭한 Datastore 솔루션이며 Python 3로 전환하는 데 도움이 되지만, App Engine 개발자가 Datastore에 액세스할 수 있는 유일한 방법은 아닙니다. App Engine의 Datastore가 2013년에 자체 제품으로 출시되었을 때 Google Cloud Datastore는 새로운 클라이언트 라이브러리를 제공하므로 모든 사용자가 Datastore를 사용할 수 있습니다.

Python 3 App Engine 및 App Engine을 사용하지 않는 개발자는 Cloud Dataplex가 아닌 Cloud Datastore를 사용하는 방법을 설명합니다. Python 2 App Engine 개발자는 ndb에서 Cloud NBS로 마이그레이션하고 여기에서 Python 3로 포팅하는 것이 좋지만, Cloud Datastore로 추가로 마이그레이션할 수도 있습니다. 이는 특히 방금 언급한 것과 같이 이미 Cloud Datastore를 사용 중인 코드가 있고 모든 애플리케이션에서 공유 라이브러리를 만들고자 하는 개발자에게 적합한 결정입니다. 아래에 요약된 것처럼 코드 재사용은 코드 일관성과 함께 권장사항이며 둘 다 유지관리 비용을 전반적으로 절감하는 데 기여합니다.

Cloud Dataplex에서 Cloud Datastore로 마이그레이션

  • 개발자가 Datastore 액세스를 위한 단일 코드베이스에 집중할 수 있도록 지원
  • 일부 코드는 Cloud NBS를 사용하여 유지관리하고 다른 코드는 Cloud Datastore를 사용하여 유지관리하지 않음
  • 코드베이스의 일관성 향상 및 코드 재사용 가능성 향상
  • 공통/공유 라이브러리를 사용할 수 있어 전체 유지보수 비용이 절감됩니다.

이 이전의 주요 단계는 다음과 같습니다.

  1. 설정/사전 작업
  2. Cloud Dataplex를 Cloud Datastore 클라이언트 라이브러리로 교체
  3. 애플리케이션 업데이트

3. 설정/사전 작업

이 가이드의 주요 부분을 진행하기 전에 프로젝트를 설정하고 코드를 가져온 후 기본 앱을 배포하여 작동하는 코드로 시작할 수 있도록 준비합니다.

1. 프로젝트 설정

모듈 2 Codelab을 완료했다면 동일한 프로젝트 및 코드를 재사용하는 것이 좋습니다. 또는 완전히 새로운 프로젝트를 만들거나 다른 기존 프로젝트를 다시 사용할 수도 있습니다. 프로젝트에 활성 결제 계정이 있고 App Engine(앱)이 사용 설정되어 있는지 확인합니다.

2. 기준 샘플 앱 가져오기

기본 요건 중 하나는 작동하는 모듈 2 샘플 앱이 있어야 합니다. 해당 튜토리얼을 완료했다면 솔루션을 사용하세요. 지금 완료해도 됩니다 (위의 링크 참고) 건너뛰려면 모듈 2 저장소 (아래 링크)를 복사하세요.

여러분의 것이든 우리의 것이든, 모듈 2 코드에서 시작합니다. 이 모듈 3 Codelab에서는 각 단계를 진행하며 완료되면 FINISH 지점의 코드와 유사해야 합니다. 이 튜토리얼에는 Python 2 및 3 버전이 있으므로 아래에서 올바른 코드 저장소를 확인하세요.

Python 2

Python 2 모듈 2 시작 파일(사용자 또는 Google의 파일)의 디렉터리는 다음과 같습니다.

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

모듈 2 튜토리얼을 완료했다면 Flask와 종속 항목이 포함된 lib 폴더도 생성됩니다. lib 폴더가 없으면 다음 단계에서 이 기준 앱을 배포할 수 있도록 pip install -t lib -r requirements.txt 명령어로 만듭니다. Python 2 및 3가 모두 설치된 경우 Python 3와 충돌을 방지하기 위해 pip 대신 pip2를 사용하는 것이 좋습니다.

Python 3

Python 3 Module 2 시작 파일 (사용자 또는 Google의 파일)의 디렉터리는 다음과 같습니다.

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

Python 3에서는 libappengine_config.py 모두 사용되지 않습니다.

3. 모듈 2 앱 (재)배포

이제 남은 사전 작업 실행 단계는 다음과 같습니다.

  1. gcloud 명령줄 도구 사용 방법을 다시 숙지합니다(필요한 경우).
  2. 모듈 1 코드를 App Engine에 (재)배포합니다(필요한 경우).

이러한 단계를 성공적으로 실행하고, 작동하는지 확인한 후에는 이 가이드로 이동하여, 구성 파일 작업을 시작합니다.

4. Cloud Dataplex를 Cloud Datastore 클라이언트 라이브러리로 교체

유일한 구성 변경사항은 requirements.txt 파일의 사소한 패키지 스왑입니다.

1. requirements.txt 업데이트

모듈 2를 완료한 후의 requirements.txt 파일은 다음과 같습니다.

  • 전 (Python 2 및 3):
Flask==1.1.2
google-cloud-ndb==1.7.1

Python 2와 호환되는 Cloud Datastore의 최종 버전은 1.15.3이라는 점을 염두에 두고 Cloud NBS 라이브러리 (google-cloud-ndb)를 최신 버전의 Cloud Datastore 라이브러리 (google-cloud-datastore)로 바꿔서 requirements.txt을 업데이트합니다. 이때 Flask 항목은 그대로 유지됩니다.

  • After (Python 2):
Flask==1.1.2
google-cloud-datastore==1.15.3
  • After (Python 3):
Flask==1.1.2
google-cloud-datastore==2.1.0

저장소는 이 튜토리얼보다 더 정기적으로 유지관리되므로 requirements.txt 파일에 최신 버전이 반영될 수 있습니다. 각 라이브러리의 최신 버전을 사용하는 것이 좋지만 작동하지 않는 경우 이전 버전으로 롤백할 수 있습니다. 위의 버전 번호는 이 Codelab이 마지막으로 업데이트된 시점의 최신 번호입니다.

2. 기타 구성 파일

다른 구성 파일 app.yamlappengine_config.py는 이전 이전 단계에서와 같이 변경되지 않은 상태로 유지됩니다.

  • app.yaml는 서드 파티 번들 패키지 grpciosetuptools를 (여전히) 참조해야 합니다.
  • appengine_config.pypkg_resourcesgoogle.appengine.ext.vendorlib의 서드 파티 리소스를 가리켜야 합니다 (여전히).

이제 애플리케이션 파일로 이동하겠습니다.

5. 애플리케이션 파일 업데이트

template/index.html에 대한 변경사항은 없지만 main.py에 대한 몇 가지 업데이트가 있습니다.

1. 가져오기

가져오기 섹션의 시작 코드는 다음과 같습니다.

  • 이전:
from flask import Flask, render_template, request
from google.cloud import ndb

google.cloud.ndb 가져오기를 Cloud Datastore용 가져오기 항목(google.cloud.datastore)으로 바꿉니다. Datastore 클라이언트 라이브러리는 항목의 타임스탬프 필드 자동 생성을 지원하지 않으므로 표준 라이브러리 datetime 모듈도 가져와 수동으로 만듭니다. 규칙에 따라 표준 라이브러리 가져오기는 서드 파티 패키지 가져오기보다 우선합니다. 변경을 완료하면 다음과 같이 표시됩니다.

  • 이후:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore

2. 초기화 및 데이터 모델

Flask를 초기화한 후 모듈 2 샘플 앱은 NBS 데이터 모델 클래스와 필드를 다음과 같이 생성합니다.

  • 이전:
app = Flask(__name__)
ds_client = ndb.Client()

class Visit(ndb.Model):
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

Cloud Datastore 라이브러리에는 이러한 클래스가 없으므로 Visit 클래스 선언을 삭제합니다. Datastore와 통신하려면 여전히 클라이언트가 필요하므로 ndb.Client()datastore.Client()로 변경합니다. Datastore 라이브러리는 '유연'하기 때문에 이를 통해 '사전 선언' 없이 항목을 만들 수 있습니다. 그 구조를 볼 수 있습니다 이 업데이트 후 main.py의 이 부분은 다음과 같이 표시됩니다.

  • 이후:
app = Flask(__name__)
ds_client = datastore.Client()

3. Datastore 액세스

Cloud Datastore로 이전하려면 사용자 수준에서 Datastore 항목을 생성, 저장, 쿼리하는 방법을 변경해야 합니다. 애플리케이션의 경우 이 마이그레이션의 난이도는 Datastore 코드의 복잡도에 따라 달라집니다. 샘플 앱에서는 업데이트를 최대한 간단하게 만들려고 했습니다. 시작 코드는 다음과 같습니다.

  • 이전:
def store_visit(remote_addr, user_agent):
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    with ds_client.context():
        return (v.to_dict() for v in Visit.query().order(
                -Visit.timestamp).fetch_page(limit)[0])

Cloud Datastore를 통해 '키'로 항목에서 그룹화된 객체를 식별하는 일반 항목을 만듭니다. 키-값 쌍의 JSON 객체 (Python dict)로 데이터 레코드를 만든 다음 예상되는 put()을 사용하여 Datastore에 기록합니다. 쿼리는 Datastore에서 비슷하지만 더 간단합니다. 동등한 Datastore 코드의 차이점은 다음과 같습니다.

  • 이후:
def store_visit(remote_addr, user_agent):
    entity = datastore.Entity(key=ds_client.key('Visit'))
    entity.update({
        'timestamp': datetime.now(),
        'visitor': '{}: {}'.format(remote_addr, user_agent),
    })
    ds_client.put(entity)

def fetch_visits(limit):
    query = ds_client.query(kind='Visit')
    query.order = ['-timestamp']
    return query.fetch(limit=limit)

위와 같이 store_visit()fetch_visits()의 함수 본문을 업데이트하여 서명을 이전 버전과 동일하게 유지합니다. 기본 핸들러 root()에는 전혀 변경사항이 없습니다. 이 변경을 완료했으니 이제 앱이 Cloud Datastore를 사용할 준비를 마쳤으며 테스트할 준비가 되었습니다.

6. 요약/삭제

애플리케이션 배포

gcloud app deploy로 앱을 다시 배포하고 앱이 작동하는지 확인합니다. 이제 코드가 모듈 3 저장소 폴더에 있는 코드와 일치해야 합니다.

앞의 Codelab을 수행하지 않고 이 시리즈를 바로 시작한 경우에는 앱 자체가 변경되지 않습니다. 모든 방문을 기본 웹페이지(/)에 등록하고 사이트를 충분히 방문한 후 다음과 같이 표시됩니다.

visitme 앱

축하합니다. 모듈 3 Codelab을 완료했습니다. 이제 Cloud Dataplex Cloud Datastore 클라이언트 라이브러리를 모두 사용하여 Datastore에 액세스할 수 있다는 것을 배웠습니다. 후자로 마이그레이션하면 공유 라이브러리, 일관성을 위한 공통 코드 및 코드 재사용, 유지보수 비용 절감 등의 이점을 얻을 수 있습니다.

선택사항: 삭제

다음 마이그레이션 Codelab으로 이동할 준비가 될 때까지 비용이 결제되지 않도록 하려면 삭제를 수행해야 합니다. 기존 개발자라면 App Engine 가격 책정 정보를 이미 잘 알고 계실 것입니다.

선택사항: 앱 사용 중지

다음 가이드로 이동할 준비가 되지 않았으면 비용 발생을 방지하기 위해 앱을 사용 중지하세요. 다음 Codelab으로 이동할 준비가 되었으면 이를 다시 사용 설정하면 됩니다. 앱이 사용 중지되면 비용을 일으키는 트래픽이 수행되지 않습니다. 하지만 무료 할당량을 초과할 경우 해당 Datastore 사용량에 대한 비용이 결제될 수 있습니다. 따라서 제한에 걸리지 않도록 충분히 삭제해야 합니다.

반면에 마이그레이션을 계속하지 않고 모든 것을 완전히 삭제하려면 프로젝트를 종료하면 됩니다.

다음 단계

여기에서 다음 이전 모듈을 살펴보세요.

  • 모듈 3 보너스: 보너스 섹션으로 이동하여 Python 3 및 차세대 App Engine 런타임으로 포팅하는 방법을 알아봅니다.
  • 모듈 7: App Engine push 태스크 큐([push] 태스크 큐를 사용하는 경우 필요)
    • App Engine taskqueue push 태스크를 모듈 1 앱에 추가합니다.
    • 모듈 8에서 Cloud Tasks로 마이그레이션하기 위해 사용자를 준비합니다.
  • 모듈 4: Docker를 사용하여 Cloud Run으로 마이그레이션합니다.
    • Docker를 사용하여 Cloud Run에서 실행하기 위해 앱을 컨테이너화합니다.
    • Python 2로 계속 유지합니다.
  • 모듈 5: Cloud 빌드팩을 사용하여 Cloud Run으로 마이그레이션
    • Cloud Buildpacks를 사용하여 Cloud Run에서 실행할 앱 컨테이너화
    • Docker, 컨테이너 또는 Dockerfile에 대해 전혀 몰라도
    • 앱이 이미 Python 3로 마이그레이션되어 있어야 합니다.
  • 모듈 6: Cloud Firestore로 마이그레이션
    • Cloud Firestore로 마이그레이션하여 Firebase 기능에 액세스
    • Cloud Firestore는 Python 2를 지원하지만 이 Codelab은 Python 3에서만 사용할 수 있습니다.

7. 보너스: Python 3로 마이그레이션

최신 App Engine 런타임 및 기능에 액세스하기 위해서는 Python 3로 마이그레이션하는 것이 좋습니다. 샘플 앱에서 Datastore는 사용된 유일한 기본 제공 서비스였습니다. ndb에서 Cloud NDB로 마이그레이션했기 때문에 이제는 App Engine의 Python 3 런타임으로 포팅할 수 있습니다.

개요

Python 3로 포팅이 Google Cloud 가이드의 범위를 벗어나지만, 이 Codelab 부분을 통해 개발자는 Python 3 App Engine 런타임의 차이점을 이해할 수 있습니다. 차세대 런타임의 한 가지 뛰어난 기능은 서드 파티 패키지에 대한 간편한 액세스를 제공한다는 것입니다. app.yaml에 내장 패키지를 지정할 필요가 없고 비내장 라이브러리를 복사하거나 업로드할 필요도 없습니다. requirements.txt에 나열되는 목록에서 암시적으로 설치됩니다.

이 샘플은 매우 기본적인 동시에 Cloud Datastore가 Python 2-3과 호환되므로 애플리케이션 코드를 명시적으로 3.x로 포팅할 필요가 없습니다. 앱은 수정되지 않은 상태로 2.x 및 3.x에서 실행됩니다. 즉, 이 경우 구성에만 필요한 변경사항만 있습니다.

  1. app.yaml를 간소화하여 Python 3를 참조하고 번들 서드 파티 라이브러리에 대한 참조를 삭제합니다.
  2. 더 이상 필수가 아니므로 appengine_config.pylib 폴더를 삭제합니다.

main.pytemplates/index.html 애플리케이션 파일은 변경되지 않습니다.

requirements.txt 업데이트

Python 2를 지원하는 Cloud Datastore의 최종 버전은 1.15.3입니다. Python 3의 최신 버전으로 requirements.txt를 업데이트합니다 (지금은 최신 버전일 수 있음). 이 튜토리얼을 작성할 당시의 최신 버전은 2.1.0이므로 다음과 같이 (또는 최신 버전) 해당 줄을 수정합니다.

google-cloud-datastore==2.1.0

app.yaml 단순화

이전:

이 샘플 앱의 유일한 실제 변경은 app.yaml을 상당히 단축시키는 것입니다. 참고로 모듈 3의 마지막 app.yaml에서 다룬 내용은 다음과 같습니다.

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

이후:

Python 3에서 threadsafe, api_version, libraries 지시문은 모두 지원 중단되었으며 모든 앱이 스레드에 안전한 것으로 가정됩니다. api_version은 Python 3에서 사용되지 않습니다. App Engine 서비스에 사전 설치된 기본 제공 타사 패키지가 더 이상 없으므로 libraries도 지원 중단됩니다. 이러한 변경사항에 대한 자세한 내용은 app.yaml 변경사항에 대한 문서를 참조하세요. 따라서 app.yaml의 3개 항목을 모두 삭제하고 지원되는 Python 3 버전(아래 참조)으로 업데이트해야 합니다.

선택사항: handlers 지시어 사용

또한 App Engine 애플리케이션에서 트래픽을 전달하는 handlers 지시문도 지원 중단되었습니다. 차세대 런타임에서는 웹 프레임워크가 앱 라우팅을 관리하므로, 모든 '핸들러 스크립트'를 'auto'로 변경해야 합니다. 위 변경사항을 조합하면 다음 app.yaml에 도달합니다.

runtime: python38

handlers:
- url: /.*
  script: auto

app.yaml 참조 페이지에서 script: auto에 대해 자세히 알아보세요.

handlers 지시문 삭제

handlers가 지원 중단되었기 때문에 전체 섹션을 삭제하고 한 줄 app.yaml만 남겨둘 수 있습니다.

runtime: python38

기본적으로 이렇게 하면 모든 애플리케이션에 사용할 수 있는 Gunicorn WSGI 웹 서버가 시작됩니다. gunicorn에 익숙할 경우 이것은 기본적으로 베어본 app.yaml로 시작될 때 실행되는 명령어입니다.

gunicorn main:app --workers 2 -c /config/gunicorn.py

선택사항: entrypoint 지시어 사용

그러나 애플리케이션에 특정 시작 명령어가 필요한 경우 entrypoint 지시어로 지정할 수 있고 그 결과 다음과 같은 app.yaml이 발생합니다.

runtime: python38
entrypoint: python main.py

이 예시는 특히 gunicorn 대신 Flask 개발 서버를 사용하도록 요청합니다. 이 작은 섹션을 main.py 하단에 추가하여 포트 8080으로 0.0.0.0 인터페이스에서 시작하도록 개발 서버를 시작하는 코드도 앱에 추가해야 합니다.

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

app.yaml 참조 페이지에서 entrypoint에 대해 자세히 알아보세요. App Engine 표준 환경 시작 문서App Engine 가변형 환경 시작 문서에서 더 많은 예시와 권장사항을 확인할 수 있습니다.

appengine_config.pylib 삭제

appengine_config.py 파일 및 lib 폴더를 삭제합니다. Python 3로 마이그레이션하는 경우 App Engine이 requirements.txt에 나열된 패키지를 획득하고 설치합니다.

직접 복사했거나 App Engine 서버에서 이미 제공되는 항목(기본 제공)을 사용하는지 여부에 관계없이 appengine_config.py 구성 파일은 타사 라이브러리/패키지를 인식하는 데 사용됩니다. Python 3로 이동할 때 중요한 변경사항에 대한 요약은 다음과 같습니다.

  1. 복사된 타사 라이브러리를 번들로 묶지 않음(requirements.txt에 나열됨)
  2. lib 폴더로 pip install을 수행하지 않음, lib 폴더 기간 없음
  3. app.yaml에 기본 제공 타사 라이브러리 목록 없음
  4. 타사 라이브러리에 앱 참조 필요 없음, 따라서 appengine_config.py 파일 없음

requirements.txt에서 모든 필수 타사 라이브러리만 나열하면 됩니다.

애플리케이션 배포

앱이 작동하는지 확인하기 위해 앱을 다시 배포합니다. 또한 솔루션이 모듈 3 샘플 Python 3 코드에 얼마나 근접한지도 확인할 수 있습니다. Python 2와의 차이를 시각화하려면 코드를 해당 Python 2 버전과 비교합니다.

모듈 3의 보너스 단계를 완료하신 것을 축하합니다. Python 3 런타임을 위한 구성 파일 준비 문서를 참조하세요. 마지막으로, 다음 단계와 정리를 위해 위의 이전 요약을 검토합니다.

개발자의 애플리케이션 준비

개발자의 애플리케이션을 마이그레이션할 시간이 되었으면 main.py 및 기타 애플리케이션 파일을 3.x로 포팅해야 합니다. 따라서 권장사항은 2.x 애플리케이션을 가능한 한 '이후 버전과 호환'되도록 만들기 위해 최선을 다하는 것입니다.

이를 위해 정말 많은 온라인 리소스가 존재하지만, 이들 중 몇 가지 중요한 팁은 다음과 같습니다.

  1. 모든 애플리케이션 종속 항목이 3.x와 완전히 호환되도록 합니다.
  2. 애플리케이션이 최소 2.6(2.7 추천) 이상으로 실행되도록 합니다.
  3. 애플리케이션이 전체 테스트 모음을 통과하도록 합니다(최소 80% 지원).
  4. six, Future 또는 Modernize와 같은 호환성 라이브러리를 사용합니다.
  5. 이전 버전과 호환되는 주요 2.x와 3.x 사이의 차이점을 확인합니다.
  6. 모든 I/O는 유니코드 및 바이트 문자열 간의 비호환성으로 이어질 수 있습니다.

이 샘플 앱은 이 모든 것을 염두에 두고 설계되었습니다. 따라서 차세대 플랫폼을 사용하기 위해 변경해야 하는 것들을 집중적으로 보여줄 수 있도록 앱이 2.x 및 3.x에서 바로 실행됩니다.

8. 추가 리소스

App Engine 마이그레이션 모듈 Codelab 문제/의견

이 Codelab에 문제가 발견된 경우 문제를 기록하기 전에 먼저 비슷한 기록이 있는지 검색해보세요. 검색 및 새 문제 만들기 링크:

마이그레이션 리소스

모듈 2 (START)와 모듈 3 (FINISH)의 저장소 폴더 링크는 아래 표에서 찾을 수 있습니다. 또한 클론 또는 ZIP 파일로 다운로드할 수 있는 모든 App Engine 마이그레이션 저장소에서 액세스할 수도 있습니다.

Codelab

Python 2

Python 3

모듈 2

코드

코드

모듈 3

코드

코드

App Engine 리소스

다음은 이 특정 마이그레이션과 관련된 추가적인 리소스입니다.