App Engine Datastore에서 Datastore 모드의 Firestore로 마이그레이션

이 가이드에서는 App Engine Datastore에서 Datastore 모드의 Firestore(Datastore라고도 함)로 마이그레이션하는 방법을 설명합니다.

Datastore 모드의 Firestore는 동일한 기본 Datastore 서비스를 참조한다는 점에서 App Engine Datastore와 유사합니다. App Engine Datastore는 App Engine 레거시 번들 서비스를 통해서만 액세스할 수 있지만 Datastore 모드의 Firestore는 Cloud 클라이언트 라이브러리를 통해 액세스되는 독립형 Google Cloud 제품입니다.

Datastore 모드의 Firestore에서는 또한 무료 등급이 제공되며 사용자가 확장성이 높은 NoSQL 문서 데이터베이스를 관리하고 이후에 Cloud Run 또는 다른 Google Cloud 앱 호스팅 플랫폼으로 마이그레이션할 수 있는 유연성이 있습니다.

시작하기 전에

  1. 여러 다른 Firestore 데이터베이스 모드를 검토하여 앱의 최적 사용 사례를 확인해야 합니다. 이 가이드에서는 Datastore 모드로 마이그레이션하는 방법을 설명합니다.

  2. Datastore 모드의 Firestore 가격 책정할당량을 검토하고 이해합니다.

    Datastore 모드의 Firestore는 결제 계정에 일일 한도가 있는 무료 사용량, 무제한 저장용량, 읽기, 쓰기 작업을 제공합니다. App Engine 앱이 사용 중지되면 비용이 발생하는 트래픽이 수행되지 않지만, 무료 할당량 한도를 초과하는 경우 Datastore 사용량에 대한 요금이 청구될 수 있습니다.

  3. 앱이 포함된 프로젝트에서 다음 API를 사용 설정합니다.

    • 빌드 아티팩트를 저장 및 관리하는 Artifact Registry API
    • 지속적인 애플리케이션 빌드, 테스트, 배포를 위한 Cloud Build API
    • App Engine 번들 Datastore에서 Datastore 모드의 Firestore로 마이그레이션하는 Cloud Datastore API

      API 사용 설정

  4. App Engine Datastore 서비스에 연결된 Java 8 또는 11을 실행하는 기존 App Engine 앱이 있어야 합니다.

프로세스 개요

대략적으로 App Engine Datastore에서 Datastore 모드의 Firestore로 마이그레이션하는 프로세스는 다음 단계로 구성됩니다.

  1. 구성 파일 업데이트
  2. Java 앱 업데이트
    1. 가져오기 문 업데이트
    2. 앱의 Datastore 서비스 액세스 방법 수정
    3. Datastore 생성 키 가져오기
    4. 항목 만들기 수정
  3. 트랜잭션 커밋
  4. 쿼리 결과

구성 파일 업데이트

Datastore 모드 클라이언트 라이브러리를 사용하도록 구성 파일을 업데이트합니다.

기준 Java 앱의 pom.xml 파일을 업데이트합니다.

  1. 다음과 같이 App Engine SDK appengine-api-1.0-sdk 가져오기를 삭제합니다.

    <dependency>
      <groupId>com.google.appengine</groupId>
      <artifactId>appengine-api-1.0-sdk</artifactId>
      <version>2.0.4</version>
    </dependency>
    
  2. 다음과 같이 Datastore 클라이언트를 추가합니다.

    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>google-cloud-datastore</artifactId>
      <!-- Use latest version -->
      <version>2.2.9</version>
    </dependency>
    

Java 앱 업데이트

가져오기 문 업데이트

가져오기 및 초기화 줄을 업데이트하여 애플리케이션 파일을 수정합니다.

  1. App Engine Datastore com.google.appengine.api.datastore.*의 다음 App Engine 가져오기 문을 삭제합니다.

      import com.google.appengine.api.datastore.DatastoreService;
      import com.google.appengine.api.datastore.DatastoreServiceFactory;
      import com.google.appengine.api.datastore.Entity;
      import com.google.appengine.api.datastore.FetchOptions;
      import com.google.appengine.api.datastore.Query;
    
  2. 다음 Datastore 모드의 Firestore com.google.cloud.datastore.* 가져오기를 추가합니다.

      import com.google.cloud.Timestamp;
      import com.google.cloud.datastore.Datastore;
      import com.google.cloud.datastore.DatastoreOptions;
      import com.google.cloud.datastore.Entity;
      import com.google.cloud.datastore.Key;
      import com.google.cloud.datastore.FullEntity;
      import com.google.cloud.datastore.KeyFactory;
      import com.google.cloud.datastore.Query;
      import com.google.cloud.datastore.QueryResults;
      import com.google.cloud.datastore.StructuredQuery;
    

앱의 Datastore 서비스 액세스 방법 수정

Datastore 모드의 Firestore는 DatastoreService 대신 Datastore 클래스를 사용합니다. 앱의 Datastore 서비스 액세스 방법을 수정하려면 다음 안내를 따르세요.

  1. 다음과 같이 DatastoreServiceFactory.getDatastoreService() 메서드를 사용하는 줄을 찾습니다.

    // Initialize a client
    DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    
  2. 다음과 같이 DatastoreServiceFactory.getDatastoreService()DatastoreOptions.getDefaultInstance().getService() 메서드로 바꿉니다.

    // Initialize a client
    Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
    

Datastore 생성 키 가져오기

클라이언트를 초기화한 후 적절한 Kind의 새 KeyFactory를 만들어서 키를 가져오면 Datastore에서 키가 자동으로 생성됩니다. Datastore 생성 키를 가져오려면 다음 안내를 따르세요.

  1. newKeyFactory를 만듭니다.

  2. setKind() 메서드를 호출하여 쿼리 분류에 사용되는 항목의 kind를 확인합니다.

  3. Datastore 키를 생성하도록 newKey() 메서드를 추가합니다.

    //Prepare a new entity
    String kind = "visit";
    Key key = datastore.allocateId(datastore.newKeyFactory().setKind(kind).newKey());
    

항목 만들기 수정

Datastore 키를 가져온 후 다음 메서드를 사용하여 항목을 만듭니다.

  1. Entity.newBuilder를 사용하고 Datastore에서 생성된 키를 전달합니다.

    다음과 같이 Entity 생성자 호출을 사용하는 줄을 찾습니다.

    Entity visit = new Entity(kind);
    

    다음과 같이 Entity 생성자 호출을 Entity.newBuilder 생성자 호출로 바꿉니다.

    Entity visit = Entity.newBuilder(key);
    
  2. set 메서드를 사용하여 항목에 대한 속성을 설정합니다.

    첫 번째 매개변수는 의도된 속성이고 두 번째 매개변수는 값입니다. timestamp 속성의 경우 값이 Instant.toString() 대신 Timestamp입니다.

    다음과 같이 setProperty 메서드를 사용하는 줄을 찾습니다.

    visit.setProperty("user_ip", userIp);
    visit.setProperty("timestamp", Instant.now().toString());
    

    다음과 같이 setProperty 메서드를 set 메서드로 바꿉니다.

    Entity visit = Entity.newBuilder(key).set("user_ip", userIp).set("timestamp", Timestamp.now()).build();
    

트랜잭션 커밋

Datastore 모드의 Firestore 클라이언트 라이브러리는 add() 메서드를 사용하여 트랜잭션을 커밋합니다. 트랜잭션을 커밋하려면 다음 안내를 따르세요.

  1. 다음과 같이 put() 메서드를 사용하는 줄을 찾습니다.

    // Save the entity
    datastore.put(visit);
    
  2. 다음과 같이 put() 메서드를 add() 메서드로 바꿉니다.

    // Save the entity
    datastore.add(visit);
    

쿼리 결과

쿼리는 지정한 조건 집합을 충족하는 entities를 검색합니다. 다음 메서드를 사용하여 결과를 표시할 수 있습니다.

  • OrderBy 메서드는 결과를 오름차순 또는 내림차순으로 표시합니다.

  • Limit 메서드는 동일한 빌더를 사용하여 가져오는 결과의 최대 개수를 제한합니다.

쿼리 시에는 kind 변수가 있는 빌더 패턴 메서드를 사용합니다. kind 변수는 Datastore 생성 키 가져오기 단계에서 Visit로 설정됩니다.

처음 10개의 결과를 검색하려면 다음 안내를 따르세요.

  1. 다음과 같이 addSort() 메서드를 사용하는 줄을 찾습니다.

      // Retrieve the last 10 visits from the datastore, ordered by timestamp.
      Query query = new Query(kind).addSort("timestamp", Query.SortDirection.DESCENDING);
      List<Entity> results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(10));
    
  2. 다음과 같이 addSort() 메서드를 setOrderBy() 메서드로 바꾸고 setLimit() 메서드를 추가합니다.

    // Retrieve the last 10 visits from the datastore, ordered by timestamp.
    Query<Entity> query = Query.newEntityQueryBuilder()
                            .setKind(kind)
                            .setOrderBy(StructuredQuery.OrderBy.desc("timestamp"))
                            .setLimit(10)
                            .build();
    
  3. 쿼리가 준비되면 datastore.run()을 사용하여 코드를 실행하고 QueryResultsEntity 컬렉션에 결과를 수집합니다.

    결과 QueryResults 객체는 hasNext() 함수가 있는 반복자입니다.

  4. 결과 목록을 반복하는 대신 결과 집합에 처리할 next 객체가 포함되었는지 확인합니다. 예를 들면 다음과 같습니다.

    QueryResults<Entity> results = datastore.run(query);
    
          resp.setContentType("text/plain");
          PrintWriter out = resp.getWriter();
          out.print("Last 10 visits:\n");
          while (results.hasNext()) {
              Entity entity = results.next();
              out.format(
                      "Time: %s Addr: %s\n", entity.getTimestamp("timestamp"), entity.getString("user_ip"));
          }
    

예시

Java 8 앱을 Datastore 모드의 Firestore로 마이그레이션하는 방법의 예시를 보려면 GitHub에서 Java 8용 App Engine Datastore 코드 샘플Datastore 모드의 Firestore 코드 샘플을 비교하세요.

다음 단계