Strong Consistency를 위한 데이터 구조화

Cloud Datastore는 여러 머신에 데이터를 배포하고 광범위한 지리적 영역에 걸쳐 마스터 없는 동기 복제를 사용하는 방법으로 높은 가용성, 확장성, 내구성을 제공합니다. 그러나 이 설계에서 감수해야 할 부분은 단일 항목 그룹의 쓰기 처리량이 초당 약 1회의 커밋으로 제한된다는 점입니다. 여러 항목 그룹을 포괄하는 쿼리 또는 트랜잭션에도 제한이 있습니다. 이 페이지에서는 이러한 제한 사항을 자세히 알아보고 애플리케이션의 쓰기 처리량 요건을 충족하면서도 강력한 일관성을 지원하도록 데이터를 구조화하기 위한 권장사항을 설명합니다.

일관성 레벨

Datastore 쿼리는 두 가지 일관성 레벨 중 하나로 결과를 제공합니다.

  • Strong consistency를 가지는 쿼리는 최신 결과를 보장하지만 일부 경우에는 완료되는 데 오랜 시간이 걸리거나 지원되지 않을 수도 있습니다.
  • Eventual Consistency를 가진 쿼리는 일반적으로 더 빠르게 실행되지만 간혹 최신이 아닌 결과를 반환할 수 있습니다.

Eventual consistency를 가지는 쿼리에서는 결과를 수집하는 데 사용되는 색인에 대한 액세스도 eventual consistency를 가집니다. 결과적으로 이러한 쿼리는 쿼리 기준에 더 이상 일치하지 않는 항목을 반환하는 경우가 있으며 쿼리 기준과 일치하는 항목이 생략되는 경우도 있습니다. 강력한 일관성을 지닌 쿼리는 트랜잭션에서 일관성을 유지하므로 데이터의 일관된 단일 스냅샷을 기반으로 한 결과가 반환됩니다.

일관성 보장

쿼리는 쿼리 특성에 따라 다양한 수준의 일관성을 보장하는 결과를 반환합니다.

  • 상위 쿼리(항목 그룹에 대해 실행되는 쿼리)는 기본적으로 strong consistency를 가지지만 Datastore 읽기 정책(아래 설명 참조)을 설정하여 eventual consistency를 가지도록 할 수 있습니다.
  • 전역 쿼리(항목 그룹에 대해 실행되지 않는 쿼리)는 항상 eventual consistency를 가집니다.

많은 애플리케이션에서 서로 관련이 없는 광범위한 데이터를 볼 때는 eventual consistency(즉, 여러 항목 그룹을 포괄하는 전역 쿼리로 다소 오래된 데이터를 반환하는 경우가 있음)을 사용하다가 관련성이 매우 높은 단일 집합의 데이터를 보거나 편집할 때는 strong consistency(상위 쿼리 또는 단일 항목 조회)를 사용할 수 있습니다. 이러한 애플리케이션에서는 일반적으로 관련성이 높은 데이터를 별도의 항목 그룹에 배치하는 방식이 바람직합니다. 항목 그룹 수가 늘어나면 처리량이 높아지고, 항목 그룹 수가 줄면 단일 상위 항목에서 읽을 수 있는 항목 수량이 많아집니다. 애플리케이션은 처리량과 일관성의 균형을 적절히 유지하기 위해 이러한 점을 고려해야 합니다.

Datastore 읽기 정책

성능을 향상시키기 위해 최종 일관성을 지닌 결과가 반환되도록 쿼리의 읽기 정책을 설정할 수 있습니다. (Datastore API에서 명시적으로 강력한 일관성 정책을 설정할 수도 있지만 전역 쿼리는 정책과 상관없이 항상 최종 일관성을 지니므로 이 설정이 실제적으로 영향을 미치지는 않습니다.)

쿼리 객체의 읽기 옵션을 통해 eventual consistency를 가지는 읽기를 사용 설정할 수 있습니다.

C#

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore C# API 참조 문서를 참조하세요.

Query query = new Query("Task")
{
    Filter = Filter.HasAncestor(_db.CreateKeyFactory("TaskList")
        .CreateKey(keyName))
};
var results = _db.RunQuery(query,
    ReadOptions.Types.ReadConsistency.Eventual);

Go

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Go API 참조 문서를 참조하세요.

ancestor := datastore.NameKey("TaskList", "default", nil)
query := datastore.NewQuery("Task").Ancestor(ancestor).EventualConsistency()

자바

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore 자바 API 참조 문서를 참조하세요.

Query<Entity> query = Query.newEntityQueryBuilder()
    .setKind("Task")
    .setFilter(PropertyFilter.hasAncestor(
        datastore.newKeyFactory().setKind("TaskList").newKey("default")))
    .build();
datastore.run(query, ReadOption.eventualConsistency());

Node.js

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Node.js API 참조 문서를 참조하세요.

const ancestorKey = datastore.key(['TaskList', 'default']);
const query = datastore.createQuery('Task').hasAncestor(ancestorKey);

query.run({consistency: 'eventual'});

PHP

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore PHP API 참조 문서를 참조하세요.

$query = $datastore->query()
    ->kind('Task')
    ->hasAncestor($datastore->key('TaskList', 'default'));
$result = $datastore->runQuery($query, ['readConsistency' => 'EVENTUAL']);

Python

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Python API 참조 문서를 참조하세요.

# Read consistency cannot be specified in google-cloud-python.

Ruby

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Ruby API 참조 문서를 참조하세요.

ancestor_key = datastore.key "TaskList", "default"

query = datastore.query("Task")
                 .ancestor(ancestor_key)

tasks = datastore.run query, consistency: :eventual

트랜잭션 및 일관성 고려 사항

Datastore 커밋은 트랜잭션 방식이나 비트랜잭션 방식으로 이루어집니다. 트랜잭션 방식트랜잭션 상황에서 발생하며 트랜잭션의 변이 집합이 모두 적용되거나 전혀 적용되지 않습니다. 반면 비트랜잭션 방식에서는 변이 집합이 모두 적용되거나 전혀 적용되지 않는 방식으로 적용되지 않을 수도 있습니다.

단일 트랜잭션에는 수에 상관없이 생성, 업데이트, 삭제 변이 작업이 포함될 수 있습니다. 데이터 일관성을 유지하기 위해 트랜잭션은 포함된 모든 변이가 하나의 단위로 Datastore에 적용되도록 보장하거나 변이가 실패하면 아무것도 적용되지 않도록 보장할 수 있습니다. 또한 동일 트랜잭션 내에서 수행되는 모든 strong consistency를 가지는 읽기(상위 쿼리 또는 lookup 작업)는 데이터의 일관된 단일 스냅샷을 사용합니다. Strong consistency를 가지는 쿼리는 상위 필터를 지정해야 합니다. 트랜잭션에 참여하는 쿼리는 항상 강력한 일관성을 지닙니다. 트랜잭션은 최대 25개 항목 그룹과 연관될 수 있습니다. 최종 일관성을 지닌 읽기에는 이러한 제한이 적용되지 않으며 많은 경우에 적합합니다. 최종 일관성을 지닌 읽기를 사용하면 많은 항목 그룹에 데이터를 배포할 수 있고 서로 다른 항목 그룹에 커밋을 병렬적으로 실행하여 쓰기 처리량을 더 높일 수 있습니다. 하지만 애플리케이션에 적합한지 여부를 결정하려면 eventual consistency를 가지는 읽기의 특성을 이해해야 합니다.

  • 이러한 읽기에 따른 결과는 최신 트랜잭션을 반영하지 않을 수도 있습니다. 이러한 읽기는 실행 중인 복제본이 최신인지 여부를 보장하지 않기 때문입니다. 그 대신 쿼리 실행 시점에 복제본에 사용 가능한 데이터를 무조건 사용합니다.
  • 여러 항목 그룹을 포괄하는 커밋된 트랜잭션은 일부 항목에만 적용되고 다른 항목에는 적용되지 않는 것처럼 보일 수 있습니다. 하지만 단일 항목 내에서 하나의 트랜잭션이 부분적으로 적용된 것처럼 보이는 일은 절대 없습니다.
  • 쿼리 결과에 필터 기준상으로는 포함되지 말았어야 하는 항목이 포함될 수도 있고 포함되었어야 하는 항목이 배제될 수도 있습니다. 색인을 읽는 데 사용되는 스냅샷 버전이 항목을 읽는 데 사용되는 스냅샷 버전과 다를 수 있기 때문입니다.

일관성을 위한 데이터 구조화

강력한 일관성을 위해 데이터를 구조화하는 방법을 이해하려면 단순한 작업 목록 애플리케이션에 두 가지 다른 접근 방식을 적용한 결과를 비교해 보세요. 첫 번째 접근 방식은 각 항목을 새로운 자체 항목 그룹에 만드는 방식입니다. 즉, 각 항목이 루트 항목이 됩니다.

C#

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore C# API 참조 문서를 참조하세요.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["category"] = "Personal",
    ["done"] = false,
    ["priority"] = 4,
    ["description"] = "Learn Cloud Datastore"
};

Go

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Go API 참조 문서를 참조하세요.

type Task struct {
	Category        string
	Done            bool
	Priority        float64
	Description     string `datastore:",noindex"`
	PercentComplete float64
	Created         time.Time
}
task := &Task{
	Category:        "Personal",
	Done:            false,
	Priority:        4,
	Description:     "Learn Cloud Datastore",
	PercentComplete: 10.0,
	Created:         time.Now(),
}

자바

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore 자바 API 참조 문서를 참조하세요.

Key taskKey = datastore.newKeyFactory()
    .setKind("Task")
    .newKey("sampleTask");
Entity task = Entity.newBuilder(taskKey)
    .set("category", "Personal")
    .set("done", false)
    .set("priority", 4)
    .set("description", "Learn Cloud Datastore")
    .build();

Node.js

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Node.js API 참조 문서를 참조하세요.

const task = {
  category: 'Personal',
  done: false,
  priority: 4,
  description: 'Learn Cloud Datastore',
};

PHP

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore PHP API 참조 문서를 참조하세요.

$task = $datastore->entity('Task', [
    'category' => 'Personal',
    'done' => false,
    'priority' => 4,
    'description' => 'Learn Cloud Datastore'
]);

Python

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Python API 참조 문서를 참조하세요.

task = datastore.Entity(client.key('Task'))
task.update({
    'category': 'Personal',
    'done': False,
    'priority': 4,
    'description': 'Learn Cloud Datastore'
})

Ruby

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Ruby API 참조 문서를 참조하세요.

task = datastore.entity "Task" do |t|
  t["category"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

이 예시에서는 우선순위에 따라 내림차순으로 정렬했을 때 우선순위가 4 이상이며 아직 수행되지 않은 태스크의 Task 항목 종류를 쿼리합니다.

C#

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore C# API 참조 문서를 참조하세요.

Query query = new Query("Task")
{
    Filter = Filter.And(Filter.Equal("done", false),
        Filter.GreaterThanOrEqual("priority", 4)),
    Order = { { "priority", PropertyOrder.Types.Direction.Descending } }
};

Go

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Go API 참조 문서를 참조하세요.

query := datastore.NewQuery("Task").
	Filter("Done =", false).
	Filter("Priority >=", 4).
	Order("-Priority")

자바

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore 자바 API 참조 문서를 참조하세요.

Query<Entity> query = Query.newEntityQueryBuilder()
    .setKind("Task")
    .setFilter(CompositeFilter.and(
        PropertyFilter.eq("done", false), PropertyFilter.ge("priority", 4)))
    .setOrderBy(OrderBy.desc("priority"))
    .build();

Node.js

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Node.js API 참조 문서를 참조하세요.

const query = datastore
  .createQuery('Task')
  .filter('done', '=', false)
  .filter('priority', '>=', 4)
  .order('priority', {
    descending: true,
  });

PHP

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore PHP API 참조 문서를 참조하세요.

$query = $datastore->query()
    ->kind('Task')
    ->filter('done', '=', false)
    ->filter('priority', '>=', 4)
    ->order('priority', Query::ORDER_DESCENDING);

Python

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Python API 참조 문서를 참조하세요.

query = client.query(kind='Task')
query.add_filter('done', '=', False)
query.add_filter('priority', '>=', 4)
query.order = ['-priority']

Ruby

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Ruby API 참조 문서를 참조하세요.

query = datastore.query("Task")
                 .where("done", "=", false)
                 .where("priority", ">=", 4)
                 .order("priority", :desc)

그러나 상위 쿼리가 아닌 eventual consistency를 가지는 쿼리를 사용하므로 쿼리 결과에 신규 항목이 포함되지 않을 수도 있습니다. 그럼에도 불구하고 커밋 직후 최종 일관성을 지닌 쿼리에 거의 모든 읽기를 수행할 수 있습니다. 많은 애플리케이션의 경우에서, 사용자의 최신 변경사항 맥락에서 최종 일관성을 지닌 쿼리 결과를 제공하는 솔루션을 활용하면 이에 따른 지연 시간을 충분히 허용 가능한 수준으로 유지할 수 있습니다.

강력한 일관성을 달성하기 위한 바람직한 접근방식은 상위 경로를 포함한 항목을 생성하는 것입니다. 상위 경로는 생성된 항목을 그룹화하는 공통 루트 항목을 식별합니다. 이 예시에서는 이름이 default이고 종류가 TaskList인 상위 경로를 사용합니다.

C#

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore C# API 참조 문서를 참조하세요.

Key taskListKey = _db.CreateKeyFactory("TaskList").CreateKey(TestUtil.RandomName());
Key taskKey = new KeyFactory(taskListKey, "Task").CreateKey("sampleTask");
Entity task = new Entity()
{
    Key = taskKey,
    ["category"] = "Personal",
    ["done"] = false,
    ["priority"] = 4,
    ["description"] = "Learn Cloud Datastore"
};

Go

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Go API 참조 문서를 참조하세요.

parentKey := datastore.NameKey("TaskList", "default", nil)
key := datastore.IncompleteKey("Task", parentKey)

task := Task{
	Category:    "Personal",
	Done:        false,
	Priority:    4,
	Description: "Learn Cloud Datastore",
}

// A complete key is assigned to the entity when it is Put.
var err error
key, err = client.Put(ctx, key, &task)

자바

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore 자바 API 참조 문서를 참조하세요.

Key taskKey = datastore.newKeyFactory()
    .addAncestors(PathElement.of("TaskList", "default"))
    .setKind("Task")
    .newKey("sampleTask");
Entity task = Entity.newBuilder(taskKey)
    .set("category", "Personal")
    .set("done", false)
    .set("priority", 4)
    .set("description", "Learn Cloud Datastore")
    .build();

Node.js

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Node.js API 참조 문서를 참조하세요.

const task = {
  key: taskKey,
  data: {
    category: 'Personal',
    done: false,
    priority: 4,
    description: 'Learn Cloud Datastore',
  },
};

PHP

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore PHP API 참조 문서를 참조하세요.

$parentKey = $datastore->key('TaskList', 'default');
$key = $datastore->key('Task')->ancestorKey($parentKey);
$task = $datastore->entity(
    $key,
    [
        'Category' => 'Personal',
        'Done' => false,
        'Priority' => 4,
        'Description' => 'Learn Cloud Datastore'
    ]
);

Python

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Python API 참조 문서를 참조하세요.

key_with_parent = client.key(
    'TaskList', 'default', 'Task', 'sample_task')

task = datastore.Entity(key=key_with_parent)

task.update({
    'category': 'Personal',
    'done': False,
    'priority': 4,
    'description': 'Learn Cloud Datastore'
})

Ruby

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Ruby API 참조 문서를 참조하세요.

task_key = datastore.key [["TaskList", "default"], ["Task", "sampleTask"]]

task = datastore.entity task_key do |t|
  t["category"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

이제 공통된 루트 항목으로 식별된 항목 그룹 내에서 strong consistency를 가지는 상위 쿼리를 실행할 수 있습니다.

C#

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore C# API 참조 문서를 참조하세요.

Query query = new Query("Task")
{
    Filter = Filter.HasAncestor(_db.CreateKeyFactory("TaskList")
        .CreateKey(keyName))
};

Go

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Go API 참조 문서를 참조하세요.

ancestor := datastore.NameKey("TaskList", "default", nil)
query := datastore.NewQuery("Task").Ancestor(ancestor)

자바

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore 자바 API 참조 문서를 참조하세요.

Query<Entity> query = Query.newEntityQueryBuilder()
    .setKind("Task")
    .setFilter(PropertyFilter.hasAncestor(
        datastore.newKeyFactory().setKind("TaskList").newKey("default")))
    .build();

Node.js

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Node.js API 참조 문서를 참조하세요.

const ancestorKey = datastore.key(['TaskList', 'default']);

const query = datastore.createQuery('Task').hasAncestor(ancestorKey);

PHP

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore PHP API 참조 문서를 참조하세요.

$ancestorKey = $datastore->key('TaskList', 'default');
$query = $datastore->query()
    ->kind('Task')
    ->hasAncestor($ancestorKey);

Python

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Python API 참조 문서를 참조하세요.

# Query filters are omitted in this example as any ancestor queries with a
# non-key filter require a composite index.
ancestor = client.key('TaskList', 'default')
query = client.query(kind='Task', ancestor=ancestor)

Ruby

Cloud Datastore용 클라이언트 라이브러리를 설치하고 사용하는 방법은 Cloud Datastore 클라이언트 라이브러리를 참조하세요. 자세한 내용은 Cloud Datastore Ruby API 참조 문서를 참조하세요.

ancestor_key = datastore.key "TaskList", "default"

query = datastore.query("Task")
                 .ancestor(ancestor_key)

이 접근 방식은 태스크 목록당 항목 그룹 한 개에 쓰기를 수행하여 strong consistency를 달성하지만 태스크 목록에 대한 변경은 초당 쓰기 1회(항목 그룹에 지원되는 한도) 이하로 제한됩니다. 애플리케이션의 쓰기 사용량이 과중해질 확률이 높아지면 다른 수단의 사용을 고려할 수도 있습니다. 예를 들어 애플리케이션이 사용자가 공개된 게시판에 메시지를 남기는 방명록인 경우, Memcache에 만료 시간이 있는 최신 게시물을 넣고 Memcache와 Datastore의 최신 게시물을 혼합하여 표시하거나 쿠키로 캐시하거나 URL에 상태를 설정하거나 전혀 다른 방식을 사용할 수 있습니다. 목표는 사용자가 애플리케이션에 게시하는 시간 동안 현재 사용자에게 데이터를 제공하는 캐싱 솔루션을 찾는 것입니다. lookup, 상위 쿼리(읽기 정책이 eventual consistency를 가지도록 설정되지 않았다고 가정함) 또는 트랜잭션 내 모든 작업을 수행하면 항상 최근에 기록된 데이터가 표시됩니다.

트랜잭션을 사용하는 방법의 추가 예시를 확인하려면 여기로 이동하세요.

항목 그룹의 트랜잭션 제한 사항

데이터를 항목 그룹으로 구성하면 수행 가능한 트랜잭션을 제한할 수 있습니다.

  • 트랜잭션에서 액세스하는 모든 데이터는 항목 그룹 25개까지에만 포함될 수 있습니다.
  • 트랜잭션 내에서 쿼리를 사용하려면 올바른 데이터에 일치하는 상위 필터를 지정할 수 있는 방식으로 데이터가 항목 그룹으로 구성되어 있어야 합니다.
  • 단일 항목 그룹 내에서는 쓰기 처리량 한도가 초당 약 1개의 트랜잭션으로 제한되어 있습니다. 이 한도가 존재하는 이유는 Datastore가 높은 안정성과 내결함성을 제공하기 위해 광범위한 지리적 영역에 걸쳐 각 항목 그룹의 마스터 없는 동기 복제 작업을 수행하기 때문입니다.

항목과 색인을 업데이트하는 방법에 대한 자세한 내용은 트랜잭션 격리 문서를 참조하세요.

이 페이지가 도움이 되었나요? 평가를 부탁드립니다.

다음에 대한 의견 보내기...

Cloud Datastore 문서