フューチャー技術ブログ

TiKVに触れる

TIG DXグループの伊藤真彦です。
CNCF連載最終回として、TiKVについて調査してみました。

TiKVとは

TiKVは分散型、トランザクション型key-valueデータベースです。最近Graduatedになったので他の記事と比べると有名どころを触っているかもしれません。

Tiは金属元素のチタンを意味します、KVはそのままkey-valueですね。チタンのように強固なkey-valueストアといったところでしょうか。

TiKVはGoogle SpannerとApache HBaseの影響を受けて開発されています、特に外部整合性のある分散トランザクションという意味での影響を受けています。

TiKVの立ち位置

TiKVはあくまでもkey-valueストアであり、NewSQLなデータベース層として使われるものではありません。
そのような用途はTiDBが相当します。TiDBはTiKVをストレージレイヤーとして用いて、MySQLの互換性等の機能を備えたインタフェース層を搭載した分散DBです。

しかし、TiKV単体でもトランザクションや楽観的ロックをサポートしており、TiKVで実現可能なユースケースの範囲は広いです。歴史的な背景としては、元々TiDBのコンポーネントとして開発されていたものがTiKVです。別プロダクトとして切り出されるだけあって、競合するNewSQLにカテゴライズされるプロダクトと比較すると、TiDB、TiKV間の疎結合性が極めて高いところが特徴です。

TiKV自体はアーキテクチャ的にはFoundationDB等と、ユースケース的な観点でRedis等のプロダクトと比較対象にされることがあります。また、etcdがKubernetesの内部key-valueストアコンポーネントとして採用されている事を考慮に入れた上で何故TiKVを採用するのか、という側面でも説明ができます。

etcdは少量のメタデータストレージとして適したプロダクトである一方、TiKV は、ペタバイト規模の展開を視野に入れ他のCNCFプロダクトを補完するような存在として開発されています。

TiKVのユースケース

TiKVはビッグデータの分散処理など大掛かりなシステムの他、ユーザーからのアップロードデータを保管するバケットや、キャッシュ、アプリケーションのメタデータの保存といったユースケースで採用されているようです。

残念ながらフューチャーでの採用事例は執筆時点ではありませんでした、触ってみたいですね。

TiKVのインストール

TiKVをkubernetesクラスタとして展開するためにはGetting Started with TiKV Operatorが参考になります。

サーバー、コンテナへの直接のインストールはBinary Deploymentを参照してください。
また公式dockerイメージの使用Ansibleでの構成管理も可能です。

なおTiKV公式はAnsibleでの構築を強く推奨しています。触ってみた印象としては、Ansible以外の手段はドキュメントの充実度にも大きな差がありました。安定動作や何かあった時の原因追及の難易度を考えると、Ansibleでのインストールを行ったほうが良いでしょう。

TiKVの使用方法

TiKVへのアクセスはAPIを通じて行われます。実態として各種言語でのクライアントライブラリを用いて使用することになるでしょう。

GoRustのクライアントが提供されているあたりがモダンな印象を強めますが、JavaCのクライアントも用意されています。一番コミットが活発なのはRustでしょうか…フロンティア精神を感じます。

Goのclientで動かしてみましたが、contextからの値の取得等でgrpcとの組み合わせを前提としたような挙動が見受けられ、フルスクラッチな独自アーキテクチャへの導入よりは、マイクロサービスのお作法に従って組み込むようなユースケースに向いている印象を受けました。元々TiDBのコンポーネントとして開発された背景からそのような作りになっていると思われます。

実際に触ってみた

今回はドキュメントを基にdocker stackを構築します。

以下の環境で検証しました。

OS: ubuntu18.04
Docker: 19.03.13

Docker imageはlatestですが執筆時点では下記が最新のイメージでした。

pingcap/pd: f2c79ee1a034aab77351ee2efee99d053868a6423684d8a3f37269b7d9a03d13
pingcap/tikv: 40f2484b613e17c2bfc61fd4fe7996a82e96eb7437a930f859761756788ceea5

まずは必要なファイル3種を用意します。

stack.yml
version: "3.7"

x-defaults: &defaults
init: true
volumes:
- ./entrypoints:/entrypoints
environment:
SLOT: "{{.Task.Slot}}"
NAME: "{{.Task.Name}}"
entrypoint: /bin/sh
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s

services:
pd:
<<: *defaults
image: pingcap/pd
hostname: "{{.Task.Name}}.tikv"
init: true
networks:
tikv:
aliases:
- pd.tikv
ports:
- "2379:2379"
- "2380:2380"
command: /entrypoints/pd.sh
tikv:
<<: *defaults
image: pingcap/tikv
hostname: "{{.Task.Name}}.tikv"

networks:
tikv:
aliases:
- tikv.tikv
ports:
- "20160:20160"
command: /entrypoints/tikv.sh

networks:
tikv:
name: "tikv"
driver: "overlay"
attachable: true
entrypoints/pd.sh
#! /bin/sh
set -e

if [ $SLOT = 1 ]; then
exec ./pd-server \
--name $NAME \
--client-urls http://0.0.0.0:2379 \
--peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://`cat /etc/hostname`:2379 \
--advertise-peer-urls http://`cat /etc/hostname`:2380
else
exec ./pd-server \
--name $NAME \
--client-urls http://0.0.0.0:2379 \
--peer-urls http://0.0.0.0:2380 \
--advertise-client-urls http://`cat /etc/hostname`:2379 \
--advertise-peer-urls http://`cat /etc/hostname`:2380 \
--join http://pd.tikv:2379
fi
entrypoints/tikv.sh
#!/bin/sh
set -e

exec ./tikv-server \
--addr 0.0.0.0:20160 \
--status-addr 0.0.0.0:20180 \
--advertise-addr `cat /etc/hostname`:20160 \
--pd-endpoints pd.tikv:2379

ファイルを設置したら構築コマンド、起動コマンドを実行します。

docker stack deploy --compose-file stack.yml tikv
docker service scale tikv_pd=1 tikv_tikv=1

curlで挙動を確認すると、立ち上がっていることが確認できました。

curl 127.0.0.1:2379/pd/api/v1/stores

dockerコマンドで簡単にスケーリングすることが可能です。

docker service scale tikv_pd=3 tikv_tikv=3

上記コマンドを実行するとコンテナがビルドされ、apiで確認できるインスタンスの数(count)が3になりました。

まとめ

TiKVの選定の参考となる資料、基本的なユースケース、導入方法をまとめてみました。

強いて欠点を上げると非常に低いレイテンシでの読み書きへの対応ができていない点が公式FAQにも書いてありますが、アーキテクチャがクリーンである点、完成度の高さでGraduatedに昇格するだけの魅力を持っているのかなと感じられました。

しかしながら公式ドキュメントやその他情報の充実度などの都合で使用難易度は高めな印象でした、この辺りはGuraduatedから日が浅い事を考えると仕方がないかなと感じる所です、個人的には今後ハウツー系記事が増えていくなど盛り上がっていくことを期待しています。