フォーム読み込み中
2022年12月25日掲載
この記事は、ソフトバンク Advent Calendar 2022 の 25日目の記事です。
Alibaba CloudのサーバレスKubernetes(ASK)を使って、TiDBをデプロイしてみたので、その手法をご紹介します。
私の部署では日頃からAlibaba、AWS、Azure、Google Cloudによるソリューションや開発手法、展開に取り組んでおり、日々全世界から最先端の技術取得に励んでいます。そうした活動をもっと外部へと発信していこうとはじめたのがこのAdventCalendarです。社員 一人一人が書いた記事を通して、少しでも多くの方にSoftBankのクラウド事業に興味を持って頂ければ幸いです。
さて、現在日本国内ではPingCAPのTiDBが非常にHotです。この記事でも出ている通り、TiDBは日本国内で「今後利用したいデータベースでNo.1」となっているオープンソースのデータベースです。そんなTiDBをAlibaba CloudのサーバレスKubernetes(Alibaba Cloud Serverless Kubernetes:ASK)上でデプロイしてみたので、本記事ではその手法をご紹介します。
※本記事ではClusterIP、PublicIPなどを表示していますが、すでにリソースをリリースしていることや、構築説明用に表示していますので参考程度に留めてください。
TiDBはGoogle F1やGoogle Spannerのアーキテクチャをベースとした、HTAP(Hybrid Transactional/Analytical Processing)データベースです。TiDBはSpannerアーキテクチャで使われているPaxosの代わりにRaftを改良したMulti-Raft プロトコルを介してトランザクションログを同期、分散ファイルシステムの代わりにRocksDBストレージを使用した構成、水平方向へのスケーラビリティ、往来のリレーショナルデータベースと同様に整合性制約(一貫性制約)、自動フェイルオーバーによる高可用性、処理を停止せずにスキーマの強制変更、異なるストレージエンジンのサポートなどが搭載されています。その甲斐もあり、AWS Auroraの数倍のパフォーマンスを発揮することができます。
しかもMySQLプロトコルを持ちながらMySQLベースで接続やSQL操作ができるため、MySQLに明るい人にとっては学習コストはほぼゼロです。より詳しいアーキテクチャはさまざまな記事が出ていますが、こちらの記事が一番詳しいので、よかったら参考にしてみてください。
TiDBはApache 2.0ライセンスのオープンソースとしてGoおよびRust言語で開発され、現在Lenovoや北京銀行、Githubなどさまざまな企業にて使用されています。
Alibaba CloudのサーバレスKubernetes(Alibaba Cloud Serverless Kubernetes:ASK)におけるTIDBの構築構成としては次の図の通りになります。
TiDBはAlibaba Cloud ACK(フルマネージド型Kubernetes)でも構築できますが、ASKはノードを購入せずにコンテナ化されたアプリケーションをデプロイできるので、その分費用をかなり節約できます。もちろん、ASKクラスタで大規模なTiDB運用構成に向けた構築をすることもできます。
TiDB自体のアーキテクチャ図は次の図通りになります。
TiDB-PD用のPVC(PersistentVolumeClaim)と、TIKV用のPVCそれぞれが必要なので、ストレージを2つ用意します。
コンポーネントの役割:
TiDB Server | SQL処理基盤 |
---|---|
PD Server | メタデータを保存するクラスタ管理機能 |
TiKV Server | データ保存基盤 |
TiSpark | OLAP処理基盤 |
また、本記事では Get Started with TiDB Operator on Kubernetes を参考に構築します。
今回の構築バージョンおよびスペックは次の通りです。
なお、TiDB本番運用向けに構築する場合は、公式サイトに記載されてる仕様およびバージョンに沿って構築する必要があります。HWはどれでも問題ないですが、公式サイトではKubernetesが推奨されていることもあり、検証用で使い捨てを前提とした、Alibaba CloudのKubernetesベースで構築します。
Library | Version |
Helm | v3.5.0 |
aliyun-cli | 3.0.140 |
kubectl Client | v1.23.2 |
kubectl Server | v1.24.6-aliyun.1 |
tidb | v6.1.0 |
構成 | Spec |
サーバレスKubernetes(ASK) | 2 CPU / 4GB |
Disk | 20GB × 2台 |
SLB(Load Balancer) |
そもそも、「なぜAlibaba Cloudで構築?」という疑問が生じると思いますが、最大の理由はAlibaba Cloudは『専用のKubernetes』、『Full ManagementのKubernetes』、『サーバレスKubernetes』などが揃っており、Kubernetesによるサービスやアプリケーションが構築がしやすいことと、Alibaba、AWS、Azure、Google Cloudの中でコストが最も安いことが理由です。今回は検証用環境で構築していますが、もしこの構成で毎秒おきに実施するとして、月額合計で209.81USD、1日あたり6.99USD、1時間おきに0.29USDになり、かなりコストを抑えられます。TiDB Specに合わせた本番環境構成でも、1ドル130円と見積もっても月30万円前後は大きいですね。
同じく、中国やインドネシア、シンガポールを含め、海外ではAlibaba Cloud上でTiDBをデプロイ、大規模運用している実績が多数あり、またKubernetes基盤として安定性が高く、導入運用面でもエンジニア労力がかなり少ないというのも、これもまた理由に当たります。
この章からTiDB構築の説明に入ります。次のStepをStep-by-Stepで構築します。
Step1: VPCとVSwitchの作成
Step2: Alibaba Cloud Serverless Kubernetes(ASK)のCluster作成
Step3: PVC用ストレージ作成
Step4: TiDBデプロイ
Alibaba CloudのサーバレスKubernetes(Alibaba Cloud Serverless Kubernetes:以降は「ASK」と称します)にて、TiDBをデプロイするためのクラスタを作成するにあたり、最初にAlibaba Cloudのコンソール上から、VPCとVSwitchを作成します。
ここでポイントとなるのが、TiDBはPROXY protocolを使用してTiDBへの接続および内部コンポーネント相互へのアクセスを実施するため、RFC1918ベースでプライベートIPアドレス範囲を設定する必要があります。そうでない場合、Document通りに `-proxy-protocol` を併用する必要があることや、後述するDNS周辺にもTiDB内部処理に合わせた対応をする必要があります。
今回はテスト用に小規模サーバなので、192.168.0.0 - 192.168.255.255の範囲としてVPCのCIDR:192.168.0.0/16、VSwitch:192.168.1.0/24、192.168.2.0/24、192.168.3.0/24でそれぞれ作成します。もしTiDBで本番用の大規模サーバ構成を狙うなら、セキュリティ担保だけでなくレイテンシ・スループット向上のためにプライベートIPアドレスの範囲をRFC1918ベースおよびTiDBドキュメントに記載されている範囲で対応をしてください。
VPCとVSwitchの作成が完了したので、ASKのClusterを作成します。コンソールの「Container Service - Kubernetes」ページへ遷移し、「Serverless Kubernetes」タブから、 Serverless Kubernetes Clusterを新規作成します。ASKの情報は次の通りに設定しています。
詳細は本記事の補足事項にて後述しますが、このServiceDiscoveryの設定でCoreDNSを設定する必要があります。PingCAPの公式ドキュメントには載っていないインストール情報(あくまでも自己解決を推奨する程度)なので、このあたりはKubernetesクラスタ上でTiDBを構築するうえで参考程度に留めてください。
ASKインスタンスが無事作成できました。
このASKにて、ECSコンソール画面からDiskを2台作成します。先述通りTiDBはTiDB-PD用のPVC(PersistentVolumeClaim)と、TIKV用のPVCそれぞれが必要です。
ECSコンソール画面にて、Diskタブから、新規でDiskを作成します。
今回は検証用として20GBのストレージを2台用意します。
ASK等 環境の準備ができたら、今度はTiDBをデプロイします。この手順は非常に簡単です。
ASKのコンソール画面にて、インスタンス一覧リストからCloudShellを開きます。
CloudShellが表示されたら、次のコマンドでクラスタ情報を確認します。
kubectl cluster-info
CloudShellを通じて、ASKの操作に問題がなければ、次の15StepをStep-by-stepで実施します。全部で15Stepありますが、ほとんどはTiDB公式サイトによる構築方法となります。
Step1:Helmバージョンを確認します。
helm version
Step2:kubectl のバージョンを確認します。
kubectl version
Step3:aliyun-cliバージョンを確認します。
aliyun help
Step4:crd.yamlをダウンロードします。
wget https://raw.githubusercontent.com/pingcap/tidb-operator/v1.3.9/manifests/crd.yaml
Step5:crdをインストールします。
kubectl create -f crd.yaml
Step6:PingCAP レポジトリを追加します。
helm repo add pingcap https://charts.pingcap.org/
Step7:tidb-admin名前空間を作成します。
kubectl create namespace tidb-admin
Step8:tidb-operator を作成します。
helm install --namespace tidb-admin tidb-operator pingcap/tidb-operator --version v1.3.9
Step9:tidb-operatorのPodを確認します。
kubectl get pods --namespace tidb-admin -l app.kubernetes.io/instance=tidb-operator
Step10:tidb-cluster.yamlをダウンロードします。
wget https://raw.githubusercontent.com/pingcap/tidb-operator/master/examples/basic/tidb-cluster.yaml
Step11:tidb-cluster名前空間を作成します。
kubectl create namespace tidb-cluster
Step12:tidb-clusterをインストールします。
kubectl -n tidb-cluster apply -f tidb-cluster.yaml
Step13:tidb-monitor.yamlファイルをダウンロードします。
wget https://raw.githubusercontent.com/pingcap/tidb-operator/master/examples/basic/tidb-monitor.yaml
Step14:tidb-monitor.yamlをインストールします。
kubectl -n tidb-cluster apply -f tidb-monitor.yaml
Step15:Podを確認します。
watch kubectl get po -n tidb-cluster
ここまで出来たら、tidb-clusterデプロイ直後は上記画面通り basic-pd-0 の STATUS が Pending 状態になります。この事象は、TiDB側からAlibaba Cloud Kubernetes側へPVCが正しくアタッチされていないため、TiDB側でPV(Persistent Volumes)が識別できず、このようにPending 状態になります。解決方法はAlibaba Cloud Kubernetes側のPodsにある basic-pd-0 用のPV(Persistent Volumes)の作成およびPVC(Persistent Volume Claim)を再作成し、再デプロイします。
basic-pd-0 用のPVを作成します。コンソール画面にて、左側メニューバーの「Persistent Volumes」タブを選定し、Createボタンをクリックします。
PV ポップアップにて、 CSIのプラグインを選択します。
ディスクを選択します。
PV作成画面はこのような構成で、PVを新規作成します。
basic-pd-0 用のPVが新たに作成されていることを確認します。
次は上記Step1-15による構築手順にてデプロイされたPVC(Persistent Volume Claim)の pd-basic-pd-0 を再アタッチするために作り直します。これはすでにTiDB側とAlibaba Cloud Kubernetesが紐づいていないためです。コンソールの左側メニューバーの「Persistent Volume Claims」タブを選定し、既存のpd-basic-pd-0 を削除します。
続いて、Persistent Volume Claims画面にて、削除した pd-basic-pd-0 に代わり tidb_pd用のPVCを作成します。Createボタンをクリックし、ポップアップウィンドウにて必要情報を入力します。
ここでPVCの名前は上記削除したものと同様に「pd-basic-pd-0」に設定します。PVCを再作成するとき、PVC名はTiDB側にとって必要なPVC名と同じようにする必要があります。
PVC「pd-basic-pd-0」が無事作成されたら、コンソールの左側メニューバーの「Deployments」タブを選定し、Deployments画面から basic-discovery を再デプロイします。
再デプロイの結果、basic-pd-0 が正しく実行することを確認します。
basic-pd-0 が正しく動いていることが確認できたら、basic-tikv をデプロイします。basic-tikvはbasic-pd-0が正常起動したら順次生成されるものです。
先述通り、次のコマンドで確認するところ basic-tikvも STATUS が Pending 状態になります。この事象は、basic-pd-0 と同じく、TiDB側からAlibaba Cloud Kubernetes側へPVCが正しくアタッチされていないため、TiDB側でPV(Persistent Volumes)が識別できず、このようにPending 状態になります。解決方法はbasic-pd-0 と同じく、basic-tikv 用のPV(Persistent Volumes)とPVC(Persistent Volume Claim)を再作成し、再デプロイします。
Pod の状態を確認してみます。
get po -n tidb-cluster
こちらも、basic-pd-0の下にbasic-tikv-0が生成され、これも Pending 状態です。
basic-tikv 用のPVを作成します。コンソール画面にて、左側メニューバーの「Persistent Volumes」タブを選定し、Createボタンをクリックします。そのあとPV ポップアップにて、 CSIのプラグインを選択します。
次は上記Step1-15による構築手順にてデプロイされたPVC(Persistent Volume Claim)の tikv-basic-tikv-0 を再アタッチするためにtikv-basic-tikv-0を作り直します。コンソールの左側メニューバーの「Persistent Volume Claims」タブを選定し、tikv-basic-tikv-0 を削除します。
その直後に、同じくPersistent Volume Claims画面にて、tikv-basic-tikv-0 のPVCを作成します。Createボタンをクリックし、ポップアップウィンドウにて必要情報を入力します。
PVC「tikv-basic-tikv-0」が無事作成されたら、コンソールの左側メニューバーの「Deployments」タブを選定し、basic-discoveryを再デプロイします。
その結果、Pods一覧で、basic-tikv-0 が無事起動出来ていることが確認できます。
Pod の状態を確認してみます。
watch kubectl get po -n tidb-cluster
basic-tidb-0、basic-tikv-0がちゃんとRunning になっていることが確認できます。
kubectlコマンド側でも確認してみます。tidb-clusterの名前空間内のサービス一覧情報を次のコマンドで取得します。
watch kubectl get po -n tidb-cluster
Podを含め、TiDBクラスタ全体的には問題なさそうです。これにより、ASKにてTiDBの基本的なインストールは完了となります。コンテナベースだと導入構築が非常に楽で便利ですね。
ASK上にてTiDBの構築が完了したら、TiDBサービスへ接続します。
TiDBへ接続するためには、kubectlがインストールされているHostに、MySQLクライアントがインストールされている必要があります。
ドキュメントに記載されてる通り、TiDBサービスはbasic-tidbと称しているので、TiDBと接続する際はbasic-tidbを中心にハンドリングする必要があります。
まずはtidb-clusterの名前空間内のサービス一覧情報を取得します。TiDBサービスことbasic-tidbはデフォルトでPort 4000で開くため、Port 4000が準備できているか確認します。
kubectl get svc -n tidb-cluster
basic-tidbは4000/TCP, 10080/TCPのPortで開いていることが確認できます。
このbasic-tidbへアクセスするためには Port 14000をListenしながら、Portフォワードを使用してbasic-tidbのPort4000へアクセスします。Port4000はpingcap/tidb:v6.1.0イメージファイルのYAMLファイルおよびconfigでデフォルトの公開Portが4000と定義されています。
kubectl port-forward -n tidb-cluster svc/basic-tidb 14000:4000 > pf14000.out &
Listen結果は `netstat -tpln` で確認できます。
続いて、MySQLクライアントを使ってTiDB(basic-tidb)へ接続します。
今回はローカルポートを設定しているため、127.0.0.1、Port 14000を使います。
mysql --comments -h 127.0.0.1 -P 14000 -u root
これで無事TiDB接続ができました。
サーバレスKubernetes(ASK)上で構築したこのTiDBで無事動いているか、軽く試します。
※本記事はAlibaba CloudのサーバレスKubernetes(ASK)にTiDBをデプロイすることがゴールなので、DDL操作(Data Definition Language、データベースやテーブルなどを定義するコマンド)、DCL操作(Data Control Language、権限などでデータを制御するコマンド)、DML操作(Data Manipulation Language、データを操作するコマンド)は実施せず、軽く状況確認のみとなります。
*TiDBバージョンの確認
select tidb_version()\G
*TiKV store ステータス確認
select * from information_schema.tikv_store_status\G
*TiDB cluster 情報の確認
select * from information_schema.cluster_info\G
*ステータス確認
status
*データベース作成
create database sbdb;
*データベース確認
show Databases;
*データベース選定
use sbdb;
*テーブル作成
create table sbtest(id int unsigned not null auto_increment primary key, v varchar(32));
*テーブル確認
show tables;
*データ追加
INSERT INTO sbtest VALUES(1,'test1');
*Selectでクエリ
select * from sbtest;
ここまでMySQLベースでひと通り操作出来ていることが確認できます。
TiDBをMySQLベースで操作できるのは非常に大きいですね。
TiDBの負荷監視のために、Grafanaを作成し、TiDBクラスタと接続連携してみます。
引き続き、Alibaba CloudのASKコンソール画面にて、左側メニューバーの「Services」を選定し、basic-grafanaサービスを確認します。
画面通り、このbasic-grafanaサービスはCluster IPタイプなので、外部ネットワークから接続することができません。これでは、エンドユーザーからGrafanaにアクセスできず、TiDBの負荷監視ができません。
そのため、Alibaba Cloud SLB(Server Load Balancer)を使って、Grafanaサービスを外部向けに公開します。
SLBコンソール画面にて、SLBを新規作成します。
SLBが作成できたら、先ほどのASKコンソール画面のServicesにて、CreateボタンをクリックしGrafanaの外部公開用サービスを作成します。
Grafanaの外部公開用サービスとして、先述のSLBインスタンスと紐づけるように設定します。Port Mapping は GrafanaのPortを設定します。設定が出来たら、そのままCreateボタンをクリックし作成します。
Grafanaの外部公開用サービスが出来たら、ASKコンソール画面のServicesにてそのサービスを確認します。
外部ネットワークから接続するためのIPアドレスおよびPortが表示されていますね。これでGrafanaへアクセスすることができます。このIPアドレスおよびPortをブラウザタブに入力し、Grafanaを開きます。
Grafanaへログインします。デフォルト設定としてアカウント名およびパスワードは次の通りです。
アカウント:admin
パスワード:admin(初回ログイン)
あとはGrafanaとして往来通りの操作になります。
GrafanaでTiDBの負荷監視をチャート形式で可視化するために、モニタリンググラフを作成してみます。これはすぐ実現できます。
Grafanaの左側の Dashboards > Manage をクリックし、Cluster-Overviewをクリックします。
Cluster-Overview画面にて、TiDBを選定します。
TiDBのbasic-pd-0インスタンスのモニタリンググラフが表示されます。
一方、TiDBのPD(PVC)を選定すると、このようなモニタリンググラフが表示されます。
上述にも記載していますが、PingCAPの公式ドキュメントには載っていないインストール情報(あくまでも自己解決を推奨する程度)が数点あったため、まとめて共有します。このあたりはTiDBをKubernetesでデプロイする上でトラブルシューティング対策としても、参考程度に留まってください。
TiDB側からすると必要なストレージクラスがデフォルトで設定されていないためなので、必要なPVとPVCを手動で再作成し、Podを再デプロイすることで解決します。上述していますが、再作成する際のPVC名はTiDB側にとって必要なPVCと同じである必要があります。
basic-pd-0がCrashLoopBackOffになっている場合、ヘルスチェックのURLにアクセスできないことが原因です。これは、coreDNSがないとURLを認識できないためです。クラスタにcoreDNS コンポーネントをインストールすることで、この問題を解決することができます。無論、coreDNS以外の解決方法もありますが、内部DNSサーバとして手っ取り早い解決方法なので著者はcoreDNSを使用しています。
basic-pd pod が Running 状態であることを確認します。この2つのPodは、basic-pdが準備できた後に、tidb-controllerによって作成されます。
このスクリーンショットにあるように、tidb-controllerのログを確認すると、詳細な理由がみえてきます。
参考として、PingCAP TiDBは素晴らしいBest Practicesが色々出回っていますので、構築や運用におけるさまざまなトラブルシューティングとしても、ぜひ参考にしてみてください。
TiDBはKubernetesでも構築できる次世代データベースです。MySQLとの高い互換性があるのは非常に大きいポイントだと思います。
このTiDBを自己構築するにあたり、TiDB公式サイトのドキュメントには載ってない情報も混じっているため、TiDBやKubernetes初心者の方には一部躓きやすいと思います。そのため、Alibaba CloudのサーバレスKubernetes(ASK)の力を借りて構築することにより、TiDB公式サイトのドキュメントには載ってない潜在的なトラブルが潜んでも、サーバレスKubernetes(サーバレスコンテナ)として構築をフォローしてくれるためシームレスに構築ができます。
同時にPodなど各種トラブルの際には、Alibaba Cloudのコンソール画面にてログやエラー情報が表示されるため、Kubectlコマンドによる深堀調査の前に素早く解決できること、coreDNSによるフォローアップ、そしてサーバレスKubernetesなのでコストも非常に安く運用できるというのは、Alibaba Cloudによる恩恵として十分享受できます。
もちろん、KNativeでTiDBをデプロイすることもできます。
さらに言えば、Alibaba CloudのACK Oneを使って Alibaba Cloud KubernetesとAzure Kubernetes(AKS)やGoogle Cloud Kubernetes(GKE)などパブリッククラウドの KubernetesによるマルチクラウドDBとしてTiDBを配置することもできます。全てのK8sクラスタを相互接続しながらデプロイできるのも強力な部分です。(こちらは近日公開予定です)
ソフトバンク Advent Calendar 2022 の最終日の投稿でした。25日間ありがとうございました。
条件に該当するページがございません