Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Published by Scroll Versions from space ML1 and version 5.3
Sv translation
languageen

Table of Contents

Introduction

Shared Disk vs. Shared Nothing

Distributed database systems fall into two major categories of data storage architectures: (1) shared disk and (2) shared nothing.

Shared Disk ArchitectureShared Nothing Architecture

Shared disk approaches suffer from several architectural limitations inherent in coordinating access to a single central resource. In such systems, as the number of nodes in the cluster increases, so does the coordination overhead. While some workloads can scale well with shared disk (e.g. small working sets dominated by heavy reads), most workloads tend to scale very poorly -- especially workloads with significant write load.

Xpand uses the shared nothing approach because it's the only known approach that allows for large-scale distributed systems.

Shared Nothing Challenges

In order to build a scalable shared-nothing database system, one must solve two fundamental problems:

  1. Split a large data set across a number of individual nodes.
  2. Create an evaluation model that can take advantage of the distributed data environment. 
Excerpt

This document explains how Xpand distributes data sets across a large number of independent nodes, as well as provides reasoning behind some of our architectural decisions. 

Shared Nothing Distribution Strategies

Within shared nothing architectures, most databases fall into the following categories:

  1. Table-level distribution. The most basic approach, where an entire table is assigned to a node. The database does not split the table. Such systems cannot handle very large tables.
  2. Single-key-per-table distribution (a.k.a index colocation, or single-key sharding). The most common approach. The preferred method for most distributed databases (e.g. MySQL Cluster, MongoDB, etc.). In this approach, the table is split into multiple chunks using a single key (user id, for example). All indexes associated with the chunk are maintained (co-located) with the primary key.
  3. Independent index distribution. The strategy used by Xpand. In this approach, each index has its own distribution. Required to support a broad range of distributed query evaluation plans. 

Xpand Basics

Xpand has a fine-grained approach to data distribution. The following table summarizes the basic concepts and terminology used by our system. Notice that unlike many other systems, Xpand uses a per-index distribution strategy.

Distribution Concepts Overview

Xpand Distribution Concepts
Anchor
Representation
Representation
Representation

Each table contains one or more indexes. Internally, Xpand refers to these indexes as representations of the table. Each representation has its own distribution key (a.k.a. a partition key or a shard key), meaning that Xpand uses multiple independent keys to slice the data in one table. This is in contrast to most other distributed database systems, which use a single key to slice the data in one table.

Each table must have a primary key. If the user does not define a primary key, Xpand will automatically create a hidden primary key. The base representation contains all of the columns within the table, ordered by the primary key. Non-base representations contain a subset of the columns within the table.

Anchor
Slice
Slice
Slice

Xpand breaks each representation into a collection of logical slices using consistent hashing.

By using consistent hashing, Xpand can split individual slices without having to rehash the entire representation.

Anchor
Replica
Replica
Replica

Xpand maintains multiple copies of data for fault tolerance and availability. There are at least two physical replicas of each logical slice, stored on separate nodes.

Xpand supports configuring the number of replicas per representation. For example, a user may require three replicas for the base representation of a table, and only two replicas for the other representations of that table.

Concepts Example

Consider the following example:                 

sql> CREATE TABLE example (
	id      bigint	primary key,
	col1	integer,
	col2	integer,
	col3    varchar(64),
	key k1  (col2),
	key k2  (col3, col1)
);

We populate our table with the following data:

Table: example
idcol1col2col3
11636january
21735february
31834march
41933april
52032may

Representation

Xpand will organize the above schema into three representations. One for the main table (the base representation, organized by the primary key), followed by two more representations, each organized by the index keys.

The yellow coloring in the diagrams below illustrates the ordering key for each representation. Note that the representations for the secondary indexes include the primary key columns. 

Table: example

base representation

k1 representationk2 representation

primary key

idcol1col2col3
11636january
21735february
31834march
41933april
52032may

index (col2)

col2id
325
334
343
352
361

index (col3, col1)

col3col1id
april194
february172
january161
march183
may205

Slice

Xpand will then split each representation into one or more logical slices. When slicing Xpand uses the following rules:

  • We apply a consistent hashing algorithm on the representation's key. 
  • We distribute each representation independently. Refer to single key vs. independent distribution below for an in-depth examination of the reasoning behind this design.
  • The number of slices can vary between representations of the same table.
  • We split slices based on size.
  • Users may configure the initial slice count of each representation. By default, each representation starts with one slice per node.
base representation slices
slice 1slice 2slice 3
idcol1col2col3
21735february
41933april
idcol1col2col3
11636january
52032may
idcol1col2col3
31834march
k1 representation
slice 1slice 2
col2id
325
343
352
col2id
334
361
k2 representation
slice 1slice 2slice 3slice 4
col3col2id
april194
col3col2id
february172
col3col2id
january161
march183
col3col2id
may205

Replica

To ensure fault tolerance and availability Xpand contains multiple copies of data. Xpand uses the following rules to place replicas (copies of slices) within the cluster:

  • Each logical slice is implemented by two or more physical replicas. The default protection factor is configurable at a per-representation level. 
  • Replica placement is based on balance for size, reads, and writes.
  • No two replicas for the same slice can exist on the same node.
  • Xpand can make new replicas online, without suspending or blocking writes to the slice.
Sample data distribution within a 4 node cluster
node 1node 2node 3node 4
k2 slice 1 replica A
col3col2id
april194
k2 slice 2 replica B
col3col2id
february172
base rep slice 3 replica A
idcol1col2col3
31834march
base rep slice 2 replica B
idcol1col2col3
11636january
52032may
k2 slice 3 replica A
col3col2id
january161
march183
k2 slice 1 replica B
col3col2id
april194
base rep slice 1 replica A
idcol1col2col3
21735february
41933april
k2 slice 2 replica A
col3col2id
february172
k2 slice 4 replica B
col3col2id
may205
base rep slice 2 replica A
idcol1col2col3
11636january
52032may
base rep slice 3 replica B
idcol1col2col3
31834march
k2 slice 4 replica A
col3col2id
may205
k2 slice 3 replica B
col3col2id
january161
march183
base rep slice 1 replica B
idcol1col2col3
21735february
41933april


Consistent Hashing

Xpand uses consistent hashing for data distribution. Consistent hashing allows Xpand to dynamically redistribute data without having to rehash the entire data set.

Slicing

Xpand hashes each distribution key to a 64-bit number. We then divide the space into ranges. Each range is then owned by a specific slice. The table below illustrates how consistent hashing assigns specific keys to specific slices. 

SliceHash RangeKey Values
1min-100H, Z, J
2101-200A, F
3201-maxX, K, R

Xpand then assigns slices to available nodes in the Cluster for data capacity and data access balance.

Re-Slicing For Growth

As the dataset grows, Xpand will automatically and incrementally re-slice the dataset one or more slices at a time. We currently base our re-slicing thresholds on data set size. If a slice exceeds a maximum size, the system will automatically break it up into two or more smaller slices. 

For example, imagine that one of our slices grew beyond the preset threshold:

SliceHash RangeKey ValuesSize
1min-100H, Z, J768MB
2101-200A, F, U, O, S1354MB (too large)
3201-maxX, K, R, Y800MB

Our rebalancer process will automatically detect the above condition and schedule a slice-split operation. The system will break up the hash range into two new slices:

SliceHash RangeKey ValuesSize
1min-100H, Z, J768MB
2101-200A, F, U, O, S1354MB (too large)
4101-150A, F670MB
5151-200U, O, S684MB
3201-maxX, K, R, Y800MB

Note that system does not have to modify slices 1 and 3. Our technique allows for very large data reorganizations to proceed in small chunks.

Single Key vs. Independent Index Distribution

It's easy to see why table-level distribution provides very limited scalability. Imagine a schema dominated by one or two very large tables (billions of rows). Adding nodes to the system does not help in such cases since a single node must be able to accommodate the entire table.  

Why does Xpand use independent index distribution rather than a single-key approach? The answer is two-fold:

  1. Independent index distribution allows for a much broader range of distributed query plans that scale with cluster node count.
  2. Independent index distribution requires strict support within the system to guarantee that indexes stay consistent with each other and the main table. Many systems do not provide the strict guarantees required to support index consistency.

Let's examine a specific use case to compare and contrast the two approaches. Imagine a bulletin board application where different topics are grouped by threads, and users are able to post into different topics. Our bulletin board service has become popular, and we now have billions of thread posts, hundreds of thousands of threads, and millions of users.

Let's also assume that the primary workload for our bulletin board consists of the following two access patterns:

  1. Retrieve all posts for a particular thread in post id order.
  2. For a specific user, retrieve the last 10 posts by that user.

We could imagine a single large table that contains all of the posts in our application with the following simplified schema:                      

-- Example schema for the posts table.
sql> CREATE TABLE thread_posts (
	post_id         bigint,
	thread_id	bigint,
        user_id 	bigint,
	posted_on	timestamp,
	contents	text,
	primary key     (thread_id, post_id),
	key             (user_id, posted_on)
);
 
-- Use case 1: Retrieve all posts for a particular thread in post id order.
-- desired access path: primary key (thread_id, post_id)
sql> SELECT * 
     FROM  thread_posts 
     WHERE thread_id = 314
     ORDER BY post_id;
 
-- Use case 2: For a specific user, retrieve the last 10 posts by that user.
-- desired access path: key (user_id, posted_on)
sql> SELECT *
     FROM thread_posts
     WHERE user_id = 546
     ORDER BY posted_on desc
     LIMIT 10;

Single Key Approach

With the single key approach, we are faced with a dilemma: Which key do we choose to distribute the posts table? As you can see with the table below, we cannot choose a single key that will result in good scalability across both use cases. 

Distribution KeyUse case 1: posts in a threadUse case 2: top 10 posts by user
thread_idQueries that include the thread_id will perform well. Requests for a specific thread get routed to a single node within the cluster. When the number of threads and posts increases, we simply add more nodes to the cluster to add capacity.Queries that do not include the thread_id, like the query for last 10 posts by a specific user, must evaluate on all nodes that contain the thread_posts table. In other words, the system must broadcast the query request because the relevant post can reside on any node.
user_idQueries that do not include the user_id result in a broadcast. As with the thread_id key sample (use case 2), we lose system scalability when we have to broadcast.Queries that include a user_id get routed to a single node. Each node will contain an ordered set of posts for a user. The system can scale by avoiding broadcasts.

One possibility with such a system could be to maintain a separate table that includes the user_id and posted_on columns. We can then have the application manually maintain this index table.

However, that means that the application must now issue multiple writes, and accept responsibility for data consistency between the two tables. And imagine if we need to add more indexes? The approach simply doesn't scale. One of the advantages of a database is automatic index management. 

Independent Index Key Approach

Xpand will automatically create independent distributions that satisfy both use cases. The DBA can specify to distribute the base representation (primary key) by thread_id, and the secondary key by user_id. The system will automatically manage both the table and secondary indexes with full ACID guarantees. 

For more detailed explanation consult our Evaluation Model section. 

Anchor
Cache_Efficiency
Cache_Efficiency
Cache Efficiency

Unlike other systems that use master-slave pairs for data fault tolerance, Xpand distributes the data in a more fine-grained manner as explained in the above sections. Our approach allows Xpand to increase cache efficiency by not sending reads to secondary replicas.

Consider the following example. Assume a cluster of 2 nodes and 2 slices A and B, with secondary copies A' and B'. 

Read from both copiesRead from primary copy only
Node 1Node 2
AB
B'A'
Node 1Node 2
AB
B'A'

If we allow reads from both primary and secondary replicas, then each node will have to cache contents of both A and B. Assuming 32GB of cache per node, the total effective cache of the system becomes 32GB.

By limiting the reads to primary replica only, we make node 1 responsible for A only, and node 2 responsible for B only. Assuming 32GB cache per node, the total effective cache footprint becomes 64GB, or double of the opposing model.
Sv translation
languageko

Table of Contents

소개

공유 디스크 대 비공유(Shared Nothing)

분산 데이터베이스 시스템은 다음과 같은 두 가지 데이터 스토리지 아키텍처 카테고리로 분류됩니다: (1) 공유 디스크 및 (2) 비공유.

공유 디스크 아키텍처비공유 아키텍처

공유 디스크 접근 방식은 단일 중앙 리소스에 대한 액세스를 조정할 때 존재하는 여러 가지 아키텍처 제한 사항으로 인해 어려움을 겪게 됩니다. 이러한 시스템에서 클러스터의 노드 수가 증가하면 조정 오버헤드도 증가합니다. 일부 워크로드는 공유 디스크(예: 읽기 부하가 주를 이루는 소형 작업 세트)에 맞게 확장할 수 있지만, 대부분의 워크로드는 제대로 확장되지 않습니다 -- 특히 쓰기 부하가 큰 워크로드가 그렇습니다.

ClustrixDB는 비공유 방식이 대규모 분산 시스템을 허용하는 유일하게 알려진 방법이기 때문에 이 방식을 사용합니다.

비공유(Shared Nothing) 문제

확장 가능한 비공유 데이터베이스 시스템을 구축하려면 두 가지 근본적인 문제를 해결해야 합니다.

  1. 다수의 개별 노드로 큰 데이터 세트를 분할합니다.
  2. 분산 데이터 환경을 활용할 수 있는 평가 모델을 만듭니다. 
Excerpt

이 문서에서는 ClustrixDB가 대규모의 독립 노드에 데이터 세트를 분산하는 방법을 설명하고 이런 아키텍처를 결정하게 된 몇 가지 이유를 제공합니다. 

비공유(Shared Nothing) 분산 전략

비공유 아키텍처 내에서 대부분의 데이터베이스는 다음 카테고리로 분류됩니다.

  1. 테이블 수준 분산. 가장 기본적인 접근 방식으로 전체 테이블이 한 개의 노드에 할당됩니다. 데이터베이스는 테이블을 분할하지 않습니다. 이러한 시스템은 매우 큰 테이블은 처리할 수 없습니다.
  2. 테이블당 단일 키 분산 (색인 코로케이션(colocation) 또는 단일 키 샤딩). 가장 일반적인 접근법. 대부분의 분산 데이터베이스(예: MySQL Cluster, MongoDB 등)에 선호되는 방법입니다. 이 접근 방식에서 테이블은 단일 키(예: 사용자 ID)를 사용하여 여러 청크로 분할됩니다. 청크와 관련된 모든 인덱스는 기본 키와 함께 유지 관리됩니다.
  3. 독립적 인덱스 분산. ClustrixDB에서 사용하는 전략입니다. 이 접근법에서 각 인덱스는 고유하게 분산됩니다. 광범위한 분산 쿼리 평가 계획을 지원하는 데 필요합니다. 

ClustrixDB 기본 사항

ClustrixDB는 데이터 분산에 대한 세분화된 접근 방식을 사용합니다. 다음 표에는 시스템에서 사용되는 기본 개념과 용어가 요약되어 있습니다. 다른 많은 시스템과 달리 ClustrixDB는 인덱스별 분산 전략을 사용합니다.

분산 개념 개요

ClustrixDB 분산 개념
Anchor
Representation
Representation
Representation

각 테이블에는 하나 이상의 인덱스가 있습니다. 내부적으로 ClustrixDB는 이러한 인덱스를 테이블의 representation으로 부릅니다. 각 representation에는 고유한 분산 키 (파티션 키 또는 샤드 키)가 있습니다. 즉, ClustrixDB는 여러 독립 키를 사용하여 하나의 테이블에서 데이터를 슬라이싱합니다. 이는 하나의 키를 사용하여 하나의 테이블에서 데이터를 슬라이싱하는 대부분의 다른 분산 데이터베이스 시스템과는 대조적입니다.

각 테이블에는 기본 키가 있어야 합니다. 사용자가 기본 키를 정의하지 않으면 ClustrixDB가 자동으로 숨겨진 기본 키를 만듭니다. Base representation은 기본 키순으로 정렬된 테이블 내의 모든 열을 포함합니다. Base representation이 아닌 representation은 테이블 내에 열의 하위 세트를 포함합니다.

Anchor
Slice
Slice
슬라이스(Slice)

ClustrixDB는 일관된 해싱(consistent hashing)을 사용하여 각 representation을 논리적 슬라이스(Slice) 모음으로 나눕니다.

일관된 해싱을 사용하여 ClustrixDB는 전체 representation을 다시 해시할 필요 없이 개별 슬라이스를 분할할 수 있습니다.

Anchor
Replica
Replica
복제본(Replica)

ClustrixDB는 내결함성 및 가용성을 위해 여러 데이터 복제본(Replica)을 유지 관리합니다. 각 논리적 슬라이스의 두 개 이상의 물리적 복제본이 별도의 노드에 저장되어 있습니다.

ClustrixDB는 representation 당 복제본 수를 설정할 수 있도록 지원합니다. 예를 들어, 사용자는 테이블의 base representation에 대해 3개의 복제본이 필요하고 해당 테이블의 다른 representation에 대해서는 2개의 복제본만 필요할 수 있습니다.

개념 예제

다음 예제를 고려하십시오.

Code Block
languagesql
create table example (
	id		bigint	primary key,
	col1	integer,
	col2	integer,
	col3 	varchar(64),
	key k1 (col2),
	key k2 (col3, col1)
);

테이블을 다음 데이터로 채웁니다.

Table: example
idcol1col2col3
11636january
21735february
31834march
41933april
52032may

Representation

ClustrixDB는 위의 스키마를 세 개의 representation으로 구성합니다. 하나는 기본 테이블(기본 키로 구성된 base representation)용이고 그 다음은 각각 인덱스 키로 구성된 두 개의 추가 representation입니다.

아래 다이어그램의 노란색은 각 representation의 순서 키를 나타냅니다. 보조 인덱스의 representation에는 기본 키 열이 포함됩니다. 

Table: example

base representation

k1 representationk2 representation

primary key

idcol1col2col3
11636january
21735february
31834march
41933april
52032may

index (col2)

col2id
325
334
343
352
361

index (col3, col1)

col3col1id
april194
february172
january161
march183
may205

슬라이스

그런 다음 ClustrixDB는 각 representation을 하나 이상의 논리적 슬라이스로 분할합니다. 슬라이싱할 때 ClustrixDB는 다음 규칙을 사용합니다.

  • representation의 키에 일관된 해싱 알고리즘(consistent hashing algorithm)을 적용합니다. 
  • 각각의 representation을 독립적으로 분산합니다. 이렇게 설계한 상세한 이유는 아래의 단일 키 대 독립적 분산을 참조하십시오.
  • 슬라이스 수는 동일 테이블의 representation 간에 다를 수 있습니다.
  • 크기에 따라 슬라이스를 분할합니다.
  • 사용자는 각 representation의 초기 슬라이스 수를 설정할 수 있습니다. 기본적으로 각 representation은 노드 당 하나의 슬라이스로 시작합니다.
base representation 슬라이스
slice 1slice 2slice 3
idcol1col2col3
21735february
41933april
idcol1col2col3
11636january
52032may
idcol1col2col3
31834march
k1 representation
slice 1slice 2
col2id
325
343
352
col2id
334
361
k2 representation
slice 1slice 2slice 3slice 4
col3col2id
april194
col3col2id
february172
col3col2id
january161
march183
col3col2id
may205

복제본

내결함성 및 가용성 보장을 위해 ClustrixDB에는 여러 데이터 복사본이 포함되어 있습니다. ClustrixDB는 다음 규칙을 사용하여 클러스터 내에 복제본(슬라이스 복사본)을 배치합니다.

  • 각 논리 슬라이스는 둘 이상의 물리적 복제본에 의해 구현됩니다. 기본 보호 요소(복제본 수)는 각 representation 수준에서 구성할 수 있습니다. 
  • 복제본 배치는 크기, 읽기 및 쓰기의 균형을 기반으로 합니다.
  • 동일한 슬라이스에 대해 두 개의 복제본이 동일한 노드에 존재할 수 없습니다.
  • ClustrixDB는 슬라이스에 대한 쓰기를 일시 중단하거나 차단하지 않고 새로운 복제본을 온라인 상태로 만들 수 있습니다.
4 노드 클러스터 내의 샘플 데이터 분산
node 1node 2node 3node 4
k2 slice 1 replica A
col3col2id
april194
k2 slice 2 replica B
col3col2id
february172
base rep slice 3 replica A
idcol1col2col3
31834march
base rep slice 2 replica B
idcol1col2col3
11636january
52032may
k2 slice 3 replica A
col3col2id
january161
march183
k2 slice 1 replica B
col3col2id
april194
base rep slice 1 replica A
idcol1col2col3
21735february
41933april
k2 slice 2 replica A
col3col2id
february172
k2 slice 4 replica B
col3col2id
may205
base rep slice 2 replica A
idcol1col2col3
11636january
52032may
base rep slice 3 replica B
idcol1col2col3
31834march
k2 slice 4 replica A
col3col2id
may205
k2 slice 3 replica B
col3col2id
january161
march183
base rep slice 1 replica B
idcol1col2col3
21735february
41933april

 

일관된 해싱(Consistent Hashing)

ClustrixDB는 데이터 분산에 일관된 해싱을 사용합니다. 일관된 해싱을 통해 ClustrixDB는 전체 데이터 세트를 다시 해시할 필요 없이 데이터를 다이내믹하게 재분산할 수 있습니다.

슬라이싱

ClustrixDB는 각 분산 키를 64비트 숫자 공간으로 해시 합니다. 그런 다음 공간을 범위로 나눕니다. 특정 슬라이스가 각 범위를 소유합니다. 아래 표는 일관된 해싱이 특정 키를 특정 슬라이스에 할당하는 방법을 보여줍니다. 

슬라이스해시 범위키 값
1min-100H, Z, J
2101-200A, F
3201-maxX, K, R

그런 다음 ClustrixDB는 데이터 용량 및 데이터 액세스 균형을 위해 클러스터의 사용 가능한 노드에 슬라이스를 할당합니다.

데이터 증가에 대비한 재슬라이싱

데이터 집합이 커짐에 따라 ClustrixDB는 한 번에 하나 이상의 슬라이스를 점진적으로 자동 재슬라이스합니다. 현재 재슬라이싱 임계값은 데이터 집합 크기를 기반으로 합니다. 슬라이스가 최대 크기를 초과하면 시스템은 자동으로 둘 이상의 작은 슬라이스로 분할합니다.

예를 들어, 슬라이스 중 하나가 사전 설정된 임계값을 초과했다고 가정해 보겠습니다.

슬라이스해시 범위키 값크기
1min-100H, Z, J768MB
2101-200A, F, U, O, S1354MB (too large)
3201-maxX, K, R, Y800MB

Data Distribution 프로세스는 위의 조건을 자동으로 감지하고 슬라이스 분할 작업을 예약합니다. 시스템은 해시 범위를 두 개의 새로운 슬라이스로 나눕니다.

슬라이스해시 범위키 값크기
1min-100H, Z, J768MB
2101-200A, F, U, O, S1354MB (too large)
4101-150A, F670MB
5151-200U, O, S684MB
3201-maxX, K, R, Y800MB

시스템은 슬라이스 1과 3을 수정할 필요가 없습니다. 이 방법을 사용하면 매우 큰 데이터 재구성 작업을 작은 청크로 진행할 수 있습니다.

단일 키 대 독립적 인덱스 분산

테이블 수준 분산이 왜 제한된 확장성을 제공하는지 쉽게 알 수 있습니다. 하나 또는 두 개의 매우 큰 테이블(수십억 개의 행)이 대부분을 차지하는 스키마를 상상해 보십시오. 단일 노드가 전체 테이블을 수용할 수 있어야 하므로 시스템에 노드를 추가하는 것이 이 경우에 도움이 되지 않습니다.  

ClustrixDB가 단일 키 방식이 아닌 독립적 인덱스 분산 방식을 사용하는 이유는 두 가지입니다.
  1. 독립적 인덱스 분산은 클러스터 노드 수와 함께 확장되는 훨씬 더 광범위한 분산 쿼리 플랜을 허용합니다.
  2. 독립적 인덱스 분산은 인덱스가 서로 그리고 주요 테이블과 일관되게 유지되도록 시스템 내에서 엄격한 지원이 필요합니다. 많은 시스템이 인덱스 일관성을 지원하는데 필요한 확실한 보증을 제공하지 않습니다.

두 가지 접근 방식을 비교하기 위해 구체적인 사용 사례를 살펴보겠습니다. 다른 주제가 스레드 별로 그룹화되고 사용자는 다른 주제에 게시할 수 있는 게시판 응용 프로그램을 상상해 보십시오. 게시판 서비스가 인기가 있어 현재 수십억 개의 스레드 게시물, 수십만 개의 스레드 및 수백만 명의 사용자가 있습니다.

게시판의 기본 워크로드가 다음과 같은 두 가지 액세스 패턴을 가진다고 가정해 봅시다.

  1. 게시물 ID 순으로 특정 스레드에 대한 모든 게시물을 검색합니다.
  2. 특정 사용자의 경우 해당 사용자가 올린 최근 게시물 10개를 검색합니다.

다음의 간단한 스키마로 애플리케이션에 모든 게시물을 포함하는 하나의 큰 테이블을 상상할 수 있습니다.

Code Block
languagesql
-- Example schema for the posts table.
 
create table thread_posts (
	post_id     bigint,
	thread_id	bigint,
    user_id 	bigint,
	posted_on	timestamp,
	contents	text,
	primary key (thread_id, post_id),
	key (user_id, posted_on)
);
 
-- Use case 1: Retrieve all posts for a particular thread in post id order.
-- desired access path: primary key (thread_id, post_id)
 
select * 
 from thread_posts 
where thread_id = 314
order by post_id
;
 
-- Use case 2: For a specific user, retrieve the last 10 posts by that user.
-- desired access path: key (user_id, posted_on)
 
select *
  from thread_posts
 where user_id = 546
 order by posted_on desc
 limit 10
;

단일 키 방식

단일 키 방식을 사용하면 다음과 같은 딜레마에 직면하게 됩니다. 게시 테이블을 분산하기 위해 어떤 키를 선택할 것인가? 아래의 테이블에서 볼 수 있듯이 두 개의 사용 사례 모두에서 좋은 확장성을 제공하는 단일 키를 선택할 수 없습니다.

분산 키사용 사례 1: 스레드의 게시물사용 사례 2: 사용자에 의한 최근 게시물 10개
thread_idthread_id를 포함하는 쿼리는 잘 수행됩니다. 특정 스레드에 대한 요청은 클러스터 내의 단일 노드로 라우팅 됩니다. 스레드와 게시물의 수가 증가하면 용량을 추가하기 위해 더 많은 노드를 클러스터에 추가하기만 하면 됩니다.특정 사용자의 최근 10개의 게시물에 대한 쿼리와 같이 thread_id를 포함하지 않는 쿼리는 thread_posts 테이블을 포함하는 모든 노드에서 평가해야 합니다. 다시 말해, 관련 게시물이 모든 노드에 존재할 수 있으므로 시스템은 쿼리 요청을 브로드캐스트해야 합니다.
user_iduser_id를 포함하지 않는 쿼리는 브로드캐스트를 발생시킵니다. thread_id 키가 사용된 사용 사례 2와 같이 브로드캐스트해야 할 때 시스템 확장성을 상실합니다.user_id를 포함하는 쿼리는 단일 노드로 라우팅 됩니다. 각 노드에는 사용자에 대한 정렬된 게시물 집합이 포함됩니다. 시스템은 브로드캐스트를 피함으로써 확장될 수 있습니다.

이러한 시스템에서 한 가지 가능한 것은 user_id 및 posted_on 열을 포함하는 별도의 테이블을 유지하는 것입니다. 그러면 응용 프로그램이 이 인덱스 테이블을 수동으로 유지하게 할 수 있습니다.

그러나, 이는 응용 프로그램이 쓰기를 여러 번 실행해야 하며 그 두 테이블 간의 데이터 일관성에 대한 책임을 져야 한다는 것을 의미합니다. 인덱스를 추가해야 하는 경우를 상상해 보십시오. 이 방식으로는 절대 확장되지 않습니다. 데이터베이스의 장점 중 하나는 자동 인덱스 관리입니다. 

독립적 인덱스 키 접근법

ClustrixDB는 두 가지 사용 사례를 모두 만족하는 독립적 분산을 자동으로 생성합니다. DBA는 base representation(기본 키)을 thread_id로, 보조 키를 user_id로 분산하도록 지정할 수 있습니다. 시스템은 완전한 ACID 보증을 사용하여 테이블 및 보조 인덱스를 자동으로 관리합니다.

자세한 내용은 Data Distribution 섹션을 참조하십시오. 

캐시 효율성

데이터 내결함성을 위해 마스터 - 슬레이브 쌍을 사용하는 다른 시스템과 달리 ClustrixDB는 위 섹션에서 설명한 것처럼 보다 세분화된 방식으로 데이터를 분산합니다. 우리의 접근 방식은 ClustrixDB가 보조 복제본에 읽기를 보내지 않음으로써 캐시 효율성을 높일 수 있도록 합니다.

다음 예제를 고려하십시오. 2 노드 클러스터에 복사본 A'와 B'가 있는 2개의 A와 B 슬라이스가 있다고 가정합니다. 

두 복사본 모두 읽기1차 복사본만 읽기
노드 1노드 2
AB
B'A'
노드 1노드 2
AB
B'A'

기본 복제본과 보조 복제본 모두에서 읽기를 허용하면 각 노드는 A와 B의 내용을 모두 캐시 해야 합니다. 노드 당 32GB의 캐시를 가정하면 시스템의 총 유효 캐시는 32GB가 됩니다.

읽기를 기본 복제본으로만 제한함으로써 노드 1은 A만 담당하고 노드 2는 B만 담당합니다. 노드 당 32GB 캐시를 가정하면 총 유효 캐시 풋프린트(footprint)는 64GB가 되거나 반대 모델의 두 배가 됩니다.