5分でわかる!Kubernetes/CloudNative Topics

入門NewSQL Kubernetes上で手軽に使えるNewSQLを動かしてみよう

こんにちは。サイバーエージェントの長谷川@makocchiです。

​​5分でわかる!Kubernetes/CloudNative Topics連載の第5回は、最近のNewSQL事情について紹介します。

この記事ではNewSQLとは何かについて説明した後、NewSQLソフトウェアであるTiDBYugabyteDBCockroachDBを実際のKubernetes環境で動かす方法について紹介します。

NewSQLとは

NewSQLとはNoSQL(Not Only SQL)の拡張性を持ちつつ、データベースソフトウェアでサポートされているACIDトランザクション処理が可能なソフトウェアです。NewSQLというワードの普及を後押ししたのが、Googleが2012年に発表したSpanner: Google’s Globally-Distributed Databaseという論文です。この発表後、Spannerのアーキテクチャを参考にいろいろなソフトウェアが世の中に出てきました。本日紹介するTiDBやYugabyteDBやCockroachDBもそのソフトウェアになります。

図1 執筆時点でのCNCF CloudNative Interactive LandscapeのDatabaseカテゴリに載っているソフトウェア達。今回紹介するTiDBやYugabyteDBやCockroachDBの名前が並んでいる(参照:CloudNative Landscape
図1

NewSQLを使う利点

筆者の私見ではありますがNewSQLを使うメリットをいくつか挙げてみます。

まずはなんと言っても拡張性です。NewSQLはSQLを処理するコンポーネントと、データを保持するコンポーネントに分かれて構成されており、例えば処理性能は必要ないけれどディスク容量だけを拡張させたい、というシナリオの場合はデータを保持するコンポーネントだけを拡張させるといったことが可能です。もちろん、ディスク容量はそのままで処理性能だけがほしいといったシナリオにも対応できます。このように、データベースのノード単位ではなく、コンポーネント単位で拡張することで必要なリソースのみを拡張することが可能で、効率よくデータベースを拡張することが可能な点が利点として挙げられます。

図2 従来のデータベースの構成例。スケール単位はノード単位になる
図2
図3 NewSQLの場合はコンポーネント毎に拡張できるため、柔軟にスケールすることが可能
図3

シャーディングが必要ないといった点もNewSQLを使う利点として挙げられます。データの肥大化に伴うシャーディングの運用は手間がかかりますし、何よりデータベースを参照するアプリケーション側にもロジックが必要になります。NewSQLではデータは自動的に分散して配置され、シャーディングしなくてもよいケースがほとんどです。また、スケールアウト/インさせた場合にも自動でリシャーディングしてくれます。これもNewSQLを使う上でのメリットでしょう。

KubernetesでNewSQLを動かしてみよう!

さて、実際にNewSQLを触ってみたくなったでしょうか? ここからはKubernetesで動かす方法をソフトウェア毎に紹介します。

TiDB編

TiDBは主にPingCAP社によって開発されているオープンソースのNewSQLソフトウェアです。TiDBはメタデータを管理するPD(Placement Driver⁠⁠、SQLを処理するTiDB、データを保存するTiKVの3つのコンポーネントによって構成されています。

図4 TiDBのアーキテクチャ(参照元:github.com/pingcap/tidb)
図4

また、TiDBはHTAP(Hybrid Transaction Analytical Processing)に対応しており、従来のリレーショナル構造に加えて列志向のデータも同時に保持できる点が特徴です。MySQLとの互換性もあります。

TiDBをKubernetesで動かす場合は、TiDBが開発しているtidb-operatorを使うことが推奨されています。実際に試してみましょう。まずはCustom Resource Definition(CRD)を登録し、その後tidb-operatorをhelmでデプロイします。

$ kubectl apply -f https://raw.githubusercontent.com/pingcap/tidb-operator/v1.3.9/manifests/crd.yaml


$ helm repo add pingcap https://charts.pingcap.org/
$ kubectl create namespace tidb-admin
$ helm install --namespace tidb-admin tidb-operator pingcap/tidb-operator --version v1.3.9

# 正常にデプロイされたか確認
$ kubectl get pods --namespace tidb-admin -l app.kubernetes.io/instance=tidb-operator
NAME                                       READY   STATUS    RESTARTS   AGE
tidb-controller-manager-5889bb85bb-lw5bf   1/1     Running   0          84s
tidb-scheduler-6dcd4bb4cc-gffrq            2/2     Running   0          84s

正常にデプロイされればtidb-schedulerとtidb-controller-managerが動いていることが確認できます。

実際にTiDBを作成するにはTidbClusterのCustom Resource(CR)で定義します。

$ cat sample-tidb-cluster.yaml
apiVersion: pingcap.com/v1alpha1
kind: TidbCluster
metadata:
  name: sample-cluster
spec:
  version: v6.1.0
  pd:
    baseImage: pingcap/pd
    replicas: 3
    requests:
      storage: "10Gi"
    config: {}
  tikv:
    baseImage: pingcap/tikv
    replicas: 3
    requests:
      storage: "10Gi"
    config: {}
  tidb:
    baseImage: pingcap/tidb
    replicas: 3
    service:
      type: LoadBalancer
    config: {}

$ kubectl create namespace sample
$ kubectl apply --namespace sample -f sample-tidb-cluster.yaml

# 正常にデプロイされると各コンポーネントが3 podずつ立ち上がる
$ kubectl get pod --namespace sample
NAME                                      READY   STATUS    RESTARTS    AGE
sample-cluster-discovery-7cc4c4b65d-wtp4j 1/1     Running   0           3m36s
sample-cluster-pd-0                       1/1     Running   0           3m36s
sample-cluster-pd-1                       1/1     Running   0           3m35s
sample-cluster-pd-2                       1/1     Running   0           3m35s
sample-cluster-tidb-0                     2/2     Running   0           116s
sample-cluster-tidb-1                     2/2     Running   0           116s
sample-cluster-tidb-2                     2/2     Running   0           115s
sample-cluster-tikv-0                     1/1     Running   0           2m46s
sample-cluster-tikv-1                     1/1     Running   0           2m46s
sample-cluster-tikv-2                     1/1     Running   0           2m46s

今回使用したsample-tidb-cluster.yaml内の定義ではspec.tidb.service.typeをLoadBalancerと指定してあります。そのためロードバランサー経由でTiDBにアクセスすることが可能になります。

払い出されたロードバランサーの4000 Portに接続してみましょう。TiDBはMySQL互換のため、mysqlコマンドを使用して接続することが可能です。

$ TIDB_IP=$(kubectl get svc --namespace sample sample-cluster-tidb \
  --output jsonpath='{.status.loadBalancer.ingress[0].ip}')

$ mysql --comments -h ${TIDB_IP} -P 4000 -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 531
Server version: 5.7.25-TiDB-v6.1.0 TiDB Server (Apache License 2.0)
Community Edition, MySQL 5.7 compatible

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SELECT version();
+--------------------+
| version()          |
+--------------------+
| 5.7.25-TiDB-v6.1.0 |
+--------------------+
1 row in set (0.15 sec)

接続した後はMySQLと同じように操作することが可能です。

なお、tidb-operatorはPrometheusおよびGrafanaもデプロイすることが可能です。また、queryをリアルタイムで分析できたりする便利なDashboardも備わっています。詳しくは次のドキュメントを参考にしてください。

YugabyteDB編

YugabyteDBは主にYugabyte社が開発しているオープンソースのNewSQLソフトウェアです。PostgreSQLおよびCassandraと互換性があるのが特徴です。YugabyteDBはメタデータを管理するYB-Master、データの保持とリクエストを処理するYB-Tserverの2つのコンポーネントから構成されています。データはTabletという単位で分割され、分散配置されます。

図5 YugabyteDBのアーキテクチャ(参照元:github.com/yugabyte/yugabyte-db
図5

YugabyteDBをKubernetesで動かす場合はyugabyte-operatorを使うのが良いでしょう。まずはyugabyte-operatorのGitHubリポジトリからCRDを取得し、Kubernetesに登録します。

ただし執筆時点でリポジトリ内に配置されているdeploy/crds/yugabyte.com_ybclusters_crd.yamlはapiextensions.k8s.io/v1beta1が使われており、最新のKubernetesではすでに削除されたAPIバージョンになるため、注意してください。

$ git clone https://github.com/yugabyte/yugabyte-operator.git
$ cd yugabyte-operator

# CRDを適用してyugabyte-operatorをデプロイ
$ kubectl create deploy/crds/yugabyte.com_ybclusters_crd.yaml
$ kubectl apply -f deploy/operator.yaml

# 正常にデプロイされたか確認
$ kubectl get pod --namespace yb-operator
NAME                                 READY   STATUS    RESTARTS   AGE
yugabyte-operator-5dd57b9f8c-wv4jf   1/1     Running   0          2m38s

YugabyteDBの定義をYBClusterのCRで行い、Kubernetesに適用します。

$ cat sample-yugabytedb.yaml
apiVersion: yugabyte.com/v1alpha1
kind: YBCluster
metadata:
  name: sample-cluster
spec:
  replicationFactor: 3
  domain: cluster.local
  master:
    replicas: 3
    storage:
      size: 1Gi
  tserver:
    replicas: 3
    storage:
      count: 1
      size: 1Gi

$ kubectl create namespace sample
$ kubectl apply --namespace sample -f sample-yugabytedb-cluster.yaml

# 正常にデプロイされると各コンポーネントが3 podずつ立ち上がる
$ kubectl get pod --namespace sample
NAME           READY   STATUS    RESTARTS   AGE
yb-master-0    1/1     Running   0          6m23s
yb-master-1    1/1     Running   0          6m23s
yb-master-2    1/1     Running   0          6m23s
yb-tserver-0   1/1     Running   0          6m23s
yb-tserver-1   1/1     Running   0          6m23s
yb-tserver-2   1/1     Running   0          6m23s

接続する際にはPostgreSQL用にysqlsh、Cassandra用にycqlshが用意されています。今回はysqlshを使って接続します。

$ kubectl exec -it --namespace sample yb-tserver-0 /home/yugabyte/bin/ysqlsh yugabyte=#

# その後の操作はpsqlと同じ
yugabyte=# \l
                                   List of databases
      Name       |  Owner   | Encoding | Collate |    Ctype    |   Access privileges
-----------------+----------+----------+---------+-------------+-----------------------
 postgres        | postgres | UTF8     | C       | en_US.UTF-8 |
 system_platform | postgres | UTF8     | C       | en_US.UTF-8 |
 template0       | postgres | UTF8     | C       | en_US.UTF-8 | =c/postgres          +
                 |          |          |         |             | postgres=CTc/postgres
 template1       | postgres | UTF8     | C       | en_US.UTF-8 | =c/postgres          +
                 |          |          |         |             | postgres=CTc/postgres
 yugabyte        | postgres | UTF8     | C       | en_US.UTF-8 |
(5 rows)

yugabyte=# SELECT version();
                                                  version

------------------------------------------------------------------------------------------------------------
 PostgreSQL 11.2-YB-2.7.0.0-b0 on x86_64-pc-linux-gnu, compiled by gcc (Homebrew gcc 5.5.0_4) 5.5.0, 64-bit
(1 row)

なおYugabyteDBは、リアルタイムにqueryを確認したり、クラスターの状況を把握したりするためのDashboardを持っています。yugabyte-operatorはyb-master-uiというServiceをKubernetesクラスター内に作成しますので、yb-master-uiのServiceに対してkubectl port-forwardをすることでDashboardにアクセスできます。詳しくは次のドキュメントを参照してください。

CockroachDB編

CockroachDBもまた、Spannerに触発されて開発されたオープンソースのNewSQLソフトウェアです。Cockroach Labsによって開発されています。

CockroachDBはTiDBやYugabyteDBのようにコンポーネントが複数存在せず、ノードだけのシンプルな構成です。つまり、クラスター内のノードは役割の差がありません。すべてのノードでRead/Writeのオペレーションが可能です。データはシャーディングされて各ノードに配置され、queryを受け付けた際に自ノードにデータを保持していない場合は他のノードにqueryをルーティングする挙動になります。

図6 CockroachDBのデータルーティング(参照元:Reads and Writes in CockroachDB
図6

また、PostgreSQLと互換性があります。

CockroachDBでもcockroach-operatorを使うことでKubernetes上にクラスターを構築することが可能です。CRDを登録した後、cockroach-operatorをデプロイします。

$ kubectl apply -f https://raw.githubusercontent.com/cockroachdb/cockroach-operator/master/install/crds.yaml

# cockroach-operatorをデプロイ(cockroach-operator-systemのnamesapceが作成される)
$ kubectl apply -f https://raw.githubusercontent.com/cockroachdb/cockroach-operator/master/install/operator.yaml

# 正常にデプロイされたか確認
$ kubectl get pod --namespace cockroach-operator-system
NAME                                          READY   STATUS    RESTARTS   AGE
cockroach-operator-manager-54575f8f9b-m6j9j   1/1     Running   0          78s

CockroachDBの定義をCrdbClusterのCRで行い、Kubernetesに適用します。

$ cat sample-cockroachdb-cluster.yaml
apiVersion: crdb.cockroachlabs.com/v1alpha1
kind: CrdbCluster
metadata:
  name: sample-cluster
spec:
  dataStore:
    pvc:
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: "10Gi"
        volumeMode: Filesystem
  resources:
    requests:
      cpu: 500m
      memory: 2Gi
    limits:
      cpu: 2
      memory: 8Gi
  tlsEnabled: true
  image:
    name: cockroachdb/cockroach:v22.1.8
  nodes: 3

$ kubectl create namespace sample
$ kubectl apply --namespace sample -f sample-cockroachdb-cluster.yaml

# 正常にデプロイされるとPodが3つ立ち上がる
$ kubectl get pod --namespace sample
NAME                        READY   STATUS    RESTARTS   AGE
sample-cluster-0            1/1     Running   0          51m
sample-cluster-1            1/1     Running   0          51m
sample-cluster-2            1/1     Running   0          51m

接続する際にはCockroachDBのコンテナイメージに含まれているcockroachクライアントを使用できます。接続用のコンテナイメージを別途デプロイして接続してみましょう。今回は接続する際にSSLを使用します。CockroachDBのクラスターが作成されると各種証明書がKubernetesクラスター内でSecretとして定義されますので、そのSecretをVolume mountして接続用Podを作成します。

# 作成したクラスター名のSecretが作成されていることを確認
$ kubectl get secret --namespace sample
NAME                            TYPE                                  DATA   AGE     LABELS
default-token-sbvv4             kubernetes.io/service-account-token   3      4h38m   <none>
sample-cluster-ca               Opaque                                1      65m     <none>
sample-cluster-node             Opaque                                3      65m     <none>
sample-cluster-root             Opaque                                3      65m     <none>
sample-cluster-sa-token-s66hz   kubernetes.io/service-account-token   3      65m     <none>

# 上記のSecretをmountしてPodを作成
$ cat cockroachdb-client-secure.yaml
apiVersion: v1
kind: Pod
metadata:
  name: cockroachdb-client-secure
spec:
  serviceAccountName: sample-cluster-sa
  containers:
  - name: cockroachdb-client-secure
    image: cockroachdb/cockroach:v22.1.8
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: client-certs
      mountPath: /cockroach/cockroach-certs/
    command:
    - sleep
    - "2147483648" # 2^31
  terminationGracePeriodSeconds: 0
  volumes:
  - name: client-certs
    projected:
        sources:
          - secret:
              name: sample-cluster-node
              items:
                - key: ca.crt
                  path: ca.crt
          - secret:
              name: sample-cluster-root
              items:
                - key: tls.crt
                  path: client.root.crt
                - key: tls.key
                  path: client.root.key
        defaultMode: 256

$ kubectl apply --namespace sample -f cockroachdb-client-secure.yaml

# Podが作成されたら接続する
$ kubectl exec -it --namespace sample cockroachdb-client-secure \
  -- ./cockroach sql --certs-dir=/cockroach/cockroach-certs --host=sample-cluster-public
#
# Welcome to the CockroachDB SQL shell.
# All statements must be terminated by a semicolon.
# To exit, type: \q.
#
# Server version: CockroachDB CCL v22.1.8 (x86_64-pc-linux-gnu, built 2022/09/29 14:21:51, go1.17.11) (same version as client)
# Cluster ID: 96b7206d-d369-4adf-ac74-9e88e909f223
#
# Enter \? for a brief introduction.
#
root@sample-cluster-public:26257/defaultdb>

接続が上手くできたら後はPostgreSQLと同じように操作できます。

root@sample-cluster-public:26257/defaultdb> \l
  database_name | owner | primary_region | regions | survival_goal
----------------+-------+----------------+---------+----------------
  defaultdb     | root  | NULL           | {}      | NULL
  postgres      | root  | NULL           | {}      | NULL
  system        | node  | NULL           | {}      | NULL
(3 rows)

root@sample-cluster-public:26257/defaultdb> SELECT version();                                                                                                                                                                                                                                                                    
                                        version
---------------------------------------------------------------------------------------
  CockroachDB CCL v22.1.8 (x86_64-pc-linux-gnu, built 2022/09/29 14:21:51, go1.17.11)
(1 row)

なおCockroachDBには、Dashboard機能を持つDB Consoleがあります。DB ConsoleではSQLのパフォーマンスやネットワークのレイテンシ情報などの様々なメトリクスをはじめ、日頃の運用に便利なノードのCPU使用率やメモリ使用率、ディスクのIOPSなどの情報を確認できます。cockroach-operatorによってクラスターが作成されると同時に<cluster名>-publicというServiceがKubernetesクラスター内に作成されていますので、こちらのServiceに対してkubectl port-forwardをするとアクセスできます。詳しくは次のドキュメントを参照してください。

まとめ

今回紹介したNewSQLをまとめると次のようになります。

TiDB YugabyteDB CockroachDB
主な開発元 PingCAP Yugabyte Cockroach Labs
GitHub Star数 32900 7300 26100
Contributorの人数 792 318 601
SQL(CQL)互換性 MySQL PostgreSQL / Cassandra PostgreSQL
ストレージレイヤー TiKV(RocksDB) DocDB(RocksDBを改良) Pebble(RocksDBを元に作成)
Kubernetes Operator tidb-operator yugabyte-operator cockroach-operator
Dashboard(GUI) あり あり あり
マネージドサービス TiDB Cloud YugabyteDB Managed CockroachDB Cloud
※GitHubのStar数、Cotributorの人数は執筆時点の値です。

お気に入りのNewSQLソフトウェアは見つかったでしょうか?

こうして比較してみるとストレージレイヤーにはRocksDBがもれなく登場しており、RocksDBの人気が伺えますね。RocksDBはMeta(旧Facebook社)が主にオープンソースで開発しているKey-Value Storeであり、LevelDBを元に多数のCPUコアを活用できるように拡張され、ストレージを効率よく利用するように最適化されています。

これからはNewSQLの時代が来ると感じています。新しいソフトウェアも今後次々と登場してくるでしょう。時代に乗り遅れないようにいろいろなNewSQLを是非触ってみてください。

自分で運用するのはちょっと……という方はマネージドサービスを使うのもおすすめです。TiDB CloudYugabyteDB ManagedCockroachDB Cloudとフルマネージドな環境でNewSQLを使うこともできます。Free Tierが用意されているマネージドサービスもあるので、まずは触ってみてはいかがでしょうか。

それでは素敵なNewSQLライフを!

おすすめ記事

記事・ニュース一覧