コードを書かずに大量のWebサイトから内容を抽出する

業務・趣味問わず発生する「Webページから値を拾ってきてExcelシートにコピペする」という仕事をなんとか省力化出来ないかを検討してみる。 自分は怠惰なので出来るのであればコードも書きたくない。

前提条件

  • 1つのECサイトの商品ページURLが50程度与えられる
  • それぞれの価格情報を取得してExcel等に出力する

Google Spreadsheet

よくネット記事でも紹介されている IMPORTXML 関数を利用する方法。 この関数は引数にURLと、抽出する対象の位置情報を指定する。

例えば以下のように入力すると、洗濯機のページから商品名を抽出できる。

=IMPORTXML("https://kakaku.com/item/K0001373907/","//*[@id=""titleBox""]/div[1]/h2")

web scraping without programming 2022 10 31 22 31 23

位置情報XPathという文字列を使う。 これはChromeのDeveloper Toolsを利用することで簡単に調査が可能。

まず、Chromeでサイトを開き、調べたい文字あたりを右クリックして「検証」をクリック。

web scraping without programming 2022 10 31 22 33 35

新しく開いたウインドウで青くハイライトされた箇所を右クリックし、「Copy」→「Copy XPath」をクリック。

web scraping without programming 2022 10 31 22 34 40

" が含まれたりするXPathをSpreadsheetに貼り付けるのは少し面倒だ。 今回は //*[@id="titleBox"]/div[1]/h2 がコピーされた。 セルに入力するときは最初に ' 文字を入れた '//*[@id="titleBox"]/div[1]/h2 と入力する必要がある。 また、関数の引数として渡すときには、以下のように " の部分を "" と書き換える必要がある。

=IMPORTXML("https://kakaku.com/item/K0001373907/","//*[@id=""titleBox""]/div[1]/h2")

"あいうえお" のように " で囲まれた箇所が文字列として認識されるけど、その中に " があったらどこが終わりか分からなくなるので、終わりじゃなくて文字の " ですよと言いたいときは "" と続けて2回タイプする必要がある。

これを応用すれば複数のページから色んな情報もすぐに取れそうだ。早速試してみよう。

web scraping without programming 2022 10 31 22 40 54

見事に日本語タイトルが文字化けしているし、4行目の商品は若干ページの構成が違って取得が出来なかった。 IMPORTXMLで日本語を取得したい場合は、文字コードが UTF-8 のサイトで有る必要がある。 まだ国内のECサイトの多くは Shift-JIS なので、対応しておらず文字化けしてしまった。 これを修正するためにはプログラミングが必要になる。

値段が変わったときにデータの再取得を行いたいときはどうすればよいか。 便利な更新ボタンはなく、関連するセルの値が変わった時にだけ再取得が行われる。 なので、URLを全部消してから Ctrl+Z で戻せばデータの再取得が行われる。

メリット

  • Googleアカウントさえあれば他に何も要らない
  • ある程度高速に実行される

デメリット

  • サイトのデザインや構成が変わると取得できなくなる
  • 日本語ページは文字化けが発生するケースも多々ある
  • 再取得させるのは少し手間
  • SPA(Twitter Webのようなリッチな作りのやつ)など凝ったサイトでは動作しない
  • 編集履歴機能にウェブページから取り込んだ内容は記録されない

Microsoft Power Automate Desktop

Windows上のいろんなソフトを自動操作してデータを取り出したりぶっこんだりするツール。 コードは書かないけど、少しプログラミング。

インストールするにはWindows 10以上が必要。 Microsoft Storeアプリで「Power Automate」と調べるとインストールできる。 途中でChromeの拡張機能も自動でインストールされるので許可しておく。

インストールが完了するとこんな感じの画面になるので、新しいフローをクリック。 自動化する手順の一連の流れを「フロー」として定義する。

web scraping without programming 2022 10 31 22 58 00

左側のアクションには色々並んでいる。 その中で選んだものをマウスでドラッグアンドドロップで真ん中に持ってくることによって使えるようになる。

web scraping without programming 2022 10 31 22 57 17

今回は↑の画像でやっているような、Chromeを起動して洗濯機のページにアクセスして、内容を拾ってきてメッセージを表示するというフローを作ってみる。

お試し作成

まぁまぁ手間がかかるので、まずは単純な例から。

アクションの一覧から「ブラウザ自動化」→「新しいChromeを起動」をドラッグアンドドロップで真ん中に持ってくる。

web scraping without programming 2022 10 31 23 05 47

「初期URL」を入れないと怒られるので、適当に https://google.com/ と入れておく。 次に「ブラウザ自動化」→「Webページに移動」を追加する。 URLには洗濯機のページURL https://kakaku.com/item/K0001373907/ を入れておく。

そして次に実際にページから値を抽出する。 「ブラウザ自動化」→「Webデータ抽出」→「Webページからデータを抽出する」を追加する。

web scraping without programming 2022 10 31 23 09 59

そしてこの画面を表示させたらChromeで https://kakaku.com/item/K0001373907/ にアクセスする。 そうすると、こんな画面が出てくるので、目的の値段の部分を「右クリック」して「要素の値を抽出」→「テキスト: ('¥191,000')」をクリック。

web scraping without programming 2022 10 31 23 11 27

そうすると、こんな感じ抽出プレビューに値段が出てくる。 これを確認して「終了ボタン」をクリック。

web scraping without programming 2022 10 31 23 12 51

元の画面に戻ってきたら「生成された変数」を適当に何回かクリックして %kakaku% と入力。 そして保存をクリック。 さっき抽出した ¥191,000 という値は %kakaku% という変数(箱)にぶっこまれる。

web scraping without programming 2022 10 31 23 13 50

次にさっき保存した %kakaku% を表示してみよう。 「メッセージ ボックス」→「メッセージを表示」アクションを追加する。 「表示するメッセージ」に 価格は %kakaku% でした! と入力する。 そして保存。 ちなみに、使える変数は入力欄右側の {x} のアイコンをクリックすると出てくるので、ミスが怖い場合はこれを使うと良い。

web scraping without programming 2022 10 31 23 15 45

そして最後は「ブラウザ自動化」→「Webブラウザーを閉じる」アクションを追加。 特に何もせずに保存。

web scraping without programming 2022 10 31 23 17 49

完成したので上の再生ボタンをクリックして実行。

web scraping without programming 2022 10 31 23 18 33

ブラウザが勝手に開いてガチャガチャやって最終的に値段が出てきたら成功。

web scraping without programming 2022 10 31 23 19 06

1つのURLにアクセスして1つの値だけ持ってくるフローが完成した。 次はこれを複数項目使える形に変形していく。

複数のウェブページをループさせる

こんな感じのテキストファイルをメモ帳で作ってみる。

web scraping without programming 2022 11 01 00 07 21

https://kakaku.com/item/K0001373907/
https://kakaku.com/item/K0001378682/
https://kakaku.com/item/J0000036676/
https://kakaku.com/item/K0001110328/
https://kakaku.com/item/K0001388197/

そして作ったファイルを読み取るために、「ファイルからテキストを読み取る」アクションを先頭に追加してみる。 ファイルパスでさっき保存したファイルを選択し、「内容の保存方法」を「リスト」に変更し、「生成された変数」は %UrlList% としておく。リストに指定することによって、ファイルの一行毎にバラされた文字として扱われる。

web scraping without programming 2022 11 01 00 09 43

そして次に「ループ」→「For each」を選択。 これでさっき作った %UrlList% を指定する。 保存先は何でも良いけど %url% としておく。

web scraping without programming 2022 11 01 00 12 53

そしてループがどう動いているかを確かめるために、「メッセージ ボックス」→「メッセージを表示」アクションを追加する。 「表示するメッセージ」は 今のURL: %url% としておく。

ここまでやると、こんな感じになる。

web scraping without programming 2022 11 01 00 13 47

実行ボタンを押してみると、こんな感じでメッセージボックスが5回表示される。

web scraping without programming 2022 11 01 00 14 20

このメッセージボックスを出す代わりに「Webページに移動」「Webページからデータを抽出する」を実行すれば良くね?ということでやってみる。

以下のような形になる。 ループさせたい処理をドラッグアンドドロップで移動させる。 「Webページに移動」をダブルクリックしてURLを https://kakaku.com/item/K0001373907/ から、ループ変数の %url% に書き換える。

web scraping without programming 2022 11 01 00 16 12

そして再生ボタンを押してみると、値段が書かれたメッセージボックスが5回出る。 いい感じじゃん。

web scraping without programming 2022 11 01 00 18 07

結果をファイルに出力する

メッセージボックスに出ているだけだと、使い勝手が悪い。 代わりにファイルに書き出してみよう。

いくつかやり方があると思うけど、まずは「変数」→「新しいリストの作成」アクションを追加してみる。 名前は %Results% みたいな感じで。

web scraping without programming 2022 11 01 00 21 50

「メッセージを表示」が5回表示されるのは鬱陶しいので、一旦右クリックして「アクションを無効化する」をクリックしておこう。

web scraping without programming 2022 11 01 00 23 19

そして、「変数」→「項目をリストに追加」アクションをその下に追加する。 項目の追加が %url% の価格は %kakaku% でした 、追加先リストを %Results% としておく。

web scraping without programming 2022 11 01 00 24 55

そして最後に「ファイル」→「テキストをファイルに書き込む」アクションを追加。 「ファイルパス」保存してほしいファイル名を指定して、「書き込むテキスト」は %Results% を指定する。

web scraping without programming 2022 11 01 00 28 50

そして実行すると、こんなファイルが生成された。

うーん惜しい…! 多分価格の %kakaku% に余計な改行が入っているから変なテキストになっている。

web scraping without programming 2022 11 01 00 30 22

%kakaku% の前後の改行とかを削除するちょうど良さそうなアクションがありそうなので、「テキスト」→「テキストのトリミング」を追加。同じ名前のやつが2つあってややこしいけど、編集画面が↓とおなじになるやつで。 「トリミンするテキスト」と「生成された変数」の両方を %kakaku% にする。 これで前後の改行が消された文字で上書きされる。

web scraping without programming 2022 11 01 00 34 46

完成形

最終的にこんな感じになりました。

web scraping without programming 2022 11 01 00 36 49

実行してみると、無事に意図した内容になっています。

web scraping without programming 2022 11 01 00 37 15

今回は1つの価格だけを抽出しましたが、変数の名前を変えれば複数の値を抽出することも出来ますし、アクションの種類も多いので応用が効きそうです。

また、宗教上の理由でPCにExcelを入れていないので試せなかったですが、Excelの読み書きや、CSVファイルの読み書きも出来るようです。

やっていることは完全にプログラミングですが、簡単なマウス操作でパズル感覚で遊べるのでExcelのマクロ(VBA)等と比べると難易度は低めかなと思います。

メリット

  • Windows 10以上であれば無料で使える
  • 複雑なウェブサイトや日本語のウェブサイトでも正常に実行できる
  • 今回のケース以外にも自動化出来る処理は非常に多い
  • プログラミングをゲーム感覚で学べる

デメリット

  • サイトのデザインや構成が変わると取得できなくなる
  • 新しめのWindowsのマシンが必要
  • コードは書いてないけどプログラミング

デスクトップ版とクラウド版があって、後者は有料のものしかないのでインストール時には要注意。

まとめ

  • Webページの情報取得はGoogle Spreadsheetを使うのが手軽だが、利用できるケースは少ない
  • Power Automateは複雑な処理やSpreadsheetで取得できない内容の取得・ファイル操作なども行えて汎用的だが複雑で少し難しい
続きを読む

NewSQL TiDBを支える分散KVS "TiKV"入門

TiDBはMySQL互換のスケーラブルなNewSQLです。 2015年に創立されたPingCAP社により開発されており、2021年には日本法人も立ち上げられました。 2022年7月に開催された TiDB User Day 2022 では、スマレジ・@cosme・カプコン等の事例も紹介されており、日本国内での利用も進んでいるようです。

ノードを増やすことでのスケーリング・HA構成の構築も非常に容易です。 さらに、MySQL互換なので既存のアプリケーションの改修は最低限に抑えられ、エコシステムも最大限活用することができます。 マネージドサービスTiDB Cloudの提供も開始され、導入は手軽になっています。 こういった魅力がTiDBが広く使われる理由かと感じています。

このTiDBは、主にPingCAP社によって開発されているTiKVによって支えられています。 TiKVはトランザクション可能なKVSストレージで、TiDBはステートレスなクエリエンジン等という構成です。 TiKVは単体でRedis,memcachedのように手軽に利用が可能ですが、非常に高機能で使いやすいです。

今回はTiDBを支えているTiKVを単体で構築・利用し、TiDBを支える技術要素に対しての理解を深めましょう。


この記事は、TiDB,TiKV開発元のPingCAPが提供するTiDB User Day 2022 インフルエンサープログラムの支援をいただいたブログ記事です。 https://pingcap.co.jp/tidb-user-day-2022-thank-you/

TiKV概要

TiKVはRustで構築された分散KVSで、永続化にはRocksDBを利用しています。 ざっくりとした特徴は以下のようになっています。

  • トランザクション対応
  • HBaseの設計に近いレンジパーティショニング
  • 構築やクライアントライブラリの利用が容易
  • HA構成が構築可能
  • メンテナンスが容易
  • 安定したレイテンシ

https://tikv.org/

CNCFプロジェクトへ登録されており、成熟度はGraduatedとされています。 https://www.cncf.io/projects/tikv/

なお、本記事では以下の製品バージョンを利用しています。

  • tiup: v1.10.3
  • TiKV: v6.2.0

TiKVクラスタ

この記事では、TiUPを利用したローカル環境でのセットアップを行います。 ざっくりとTiKVのクラスタの性質を紹介します。

TiKVは複数ノード用意することで、可用性の向上・パフォーマンスの向上が可能です。

TiKVを利用するためには、TiKVの他にPD(Placement Driver)コンポーネントを動作させる必要があります。 PDは主にスケジューリングとトランザクションの管理を行っています。 PDはetcdを組み込んでおり、こちらも複数ノード用意することで可用性を上げることが可能です。

データは一定の容量ごとにリージョンという単位で分割され、各ノードのストアに格納されます。 データをどのTiKVノードに保存するかはPDが管理しており、常に指定されたレプリケーション係数を維持するようにレプリカ数を調整したり、クライアントへデータ・ノードの対応付けに必要な情報を伝えます。 クライアントはデータの取得を行う際に、PDの情報を元に格納ノードを特定して、該当のTiKVへ直接通信を行います。 この性質から、TiKVクライアントからはすべてのTiKVノードに加えてPDノードへの通信を行えるように設定する必要があります。

TiKV, PDは主なx86,ARM CPUを搭載するLinuxサーバであれば動作可能ですが、 最適なパフォーマンスを得るためのマシンスペックの目安が公式ドキュメントで案内されています。

https://tikv.org/docs/6.1/deploy/install/prerequisites/

TiKVクラスタ 構築方法

公式で提供されているPD/TiKV/TiDBクラスタの展開方法は以下のとおりです。

今回は開発環境・本番環境共に構築を行うことができる推奨ツールTiUPで構築を行います。

本番環境の構築を行う際には、最初にTerraform等のツールでLinuxインスタンスを構築します。 ホストリスト等の情報をTiUPへ渡すことで、PD/TiKV等の必要なコンポーネントの展開が自動的に行われます。 普段Ansible等で行っているオペレーション等を、巻き取ってくれるものとして認識して良いと思います。

また、公式で推奨されてはいませんが、いずれのコンポーネントもGitHub等でコンパイル済み実行ファイルの配布が行われています。 依存関係も少ないので、手動でバイナリダウンロード・配置を行うことでデプロイを行うことも可能です。 クラスタの理解を深めるために、こういった手動でのデプロイも経験すると良いように感じます。

TiUPを利用した開発環境構築

TiUPは本番環境の構築に推奨されたデプロイツールですが、ローカルマシンの開発環境の構築も非常に簡単に行うことができます。 主な手順がこちらのドキュメントで紹介されています。

https://tikv.org/docs/6.1/concepts/tikv-in-5-minutes/

まずTiUPコマンドのインストールを行います。 シェルを実行することで自動的にインストールされます。 公式ドキュメントではインストール後に source ~/.bash_profile を行うよう指示がありますが、TiUP上では source ~/.bashrc を行うように指示がありましたので、自分は ~/.bashrc の読み込みを行いました。

$ curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
$ . ~/.bashrc
$ tiup --version

次に下のコマンドで開発環境のTiKVの構築を行います。 TiUPのplaygroundサブコマンドは、ローカル環境でのテスト環境立ち上げを行うためのものです。

$ tiup playground --mode tikv-slim

起動が完了すると、コンソール上に以下のようなエンドポイント情報が表示されます。 PDの情報は、TiKVクライアントへ接続情報として渡す必要があります。 TiKVとPDに加えて、TiKV,PDを監視するためのPrometheusとダッシュボードを閲覧するためのGrafanaも立ち上がります。

PD client endpoints: [127.0.0.1:2379]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000

また、TiUP playgroundに渡す引数を変更することにより、異なる構成でのクラスタ構築も可能です。 以下の例ではPD,TiKVそれぞれ3台の構成としています。

$ tiup playground --mode tikv-slim --pd 3 --kv 3

PD client endpoints: [127.0.0.1:2379 127.0.0.1:2382 127.0.0.1:2384]
To view the Prometheus: http://127.0.0.1:9090
To view the Grafana: http://127.0.0.1:3000

ちなみに、PDのポート番号を変更するためのオプションは、次期バージョンのTiUPにて実装される予定のようです。

https://github.com/pingcap/tiup/pull/1931

GrafanaのURLにアクセスして、ユーザ名・パスワードを admin admin としてログインすると、以下のように詳細なメトリクスを閲覧することができます。 パフォーマンステストやトラブルシューティングの際に役に立つダッシュボードが公式で提供されています。 非常に網羅性が高く使い勝手も良いので、実務においてもこれだけあれば問題になることは無いように感じます。 tikv get started 2022 09 06 15 12 41

TiKV, PDの管理

それぞれTiKVは tikv-ctl 、PDは pd-ctl コマンドで管理を行うことができます。 主にクラスタやスケジューラに対しての操作・設定・参照は pd-ctl で行い、TiKVノードの様々なデバッグ情報の参照・操作は tikv-ctl で行います。 CLIは非常に機能が豊富で紹介しきれませんが、TiKV,PDは安定性が高く、個人開発等の小さな規模であれば日常的に触ることは無いように感じます。

今回はTiUP経由での pd-ctl を実行し、今回構築したクラスタ情報を表示します。

$ tiup ctl:v6.2.0 pd -u http://127.0.0.1:2379 cluster
{
  "id": 7139831296082586572,
  "max_peer_count": 3
}

詳細は以下のリファレンスを参照してください。

https://docs.pingcap.com/tidb/v6.2/pd-control https://docs.pingcap.com/tidb/v6.2/tikv-control

TiKVのクライアントライブラリ

TiKVを利用するためのクライアントライブラリは、特に tikv/client-go tikv/client-java tikv/client-rust が活発にメンテナンスされているようです。

各クライアントのリポジトリにサンプルコードも含まれています。 今回はGoでTiKVクラスタに接続して値の読み書きを行ってみましょう。

TiKVが提供するAPIは大まかに2種類存在しています。

  • RawKV

    • 非トランザクションAPI
    • CAS(CompareAndSwap)操作向けのAPIが存在しており、データ競合を防ぐ事ができる
  • TxnKV

    • トランザクションを利用するAPI
    • RawKVに比べると、負荷やレイテンシが高くなることが多い

なお現在のTiKVバージョンにおいては、1つのクラスタへのアクセス方法はRawKV,TxnKVどちらか片方を利用する必要があります。 将来的にRawKV,TxnKVが読み書きできる領域を内部的に分割することで、両方のアクセスをサポートすることも検討されているようです。 https://github.com/tikv/tikv/issues/3922

GoからTiKVクラスタへ接続

今回利用するサンプルコードはこちらに用意しています。 https://github.com/kamijin-fanta/tikv-sandbox

まずはRawKVを利用してみます。 最初に以下のような形でRawKV向けのクライアントを生成します。 指定するアドレスは、TiKVではなくPDのアドレスです。 クライアント内では、PDからノード情報・データの配置情報を取得して、データアクセスを行っています。

cli, err := rawkv.NewClient(
  ctx,
  []string{"127.0.0.1:2379"},
  config.DefaultConfig().Security,
)

次に、キーに対してのいくつかの操作方法を紹介します。

// クライアントで扱うKey,Valueは共に[]byte型
key := []byte("key-example")
val := []byte("bytes-value")

// キーに値をセット
err = cli.Put(ctx, key, val)

// キーの値を取得
val, err = cli.Get(ctx, key)

// キーの値を削除
err = cli.Delete(ctx, key)

サンプルコードのリポジトリ内で go run ./cmd/rawkv-basic/. とすることで、一連の操作を試すことができます。 https://github.com/kamijin-fanta/tikv-sandbox/blob/master/cmd/rawkv-basic/rawkv-basic.go

スキャン

TiKVは、キーを辞書順にソートした大きなSorted Mapのような仕組みになっています。 こちらは、 BigTable, HBase 等に近いデザインです。 キー範囲は自動的に一定の大きさで分割されますが、クライアントはPDからの情報を元に透過的にアクセスを行います。

こういった性質を持っていることから、TiKVでは一定のキー範囲に対してのスキャンを行うことが可能です。 リスト構造や時系列データのように連続したアクセスを行うことが多いデータを扱う際に非常に便利です。

Goのクライアントライブラリで試してみましょう。

// 事前に range-test_0 ~ range-test_9 をPUTしておく
for i := 0; i < 10; i++ {
  key := fmt.Sprintf("range-test_%d", i)
  value := fmt.Sprintf("value-%d", i)
  _ = cli.Put(ctx, []byte(key), []byte(value))
}

// スキャン対象のキー下限・上限
getLowerKey := []byte("range-test_2")
getUpperKey := []byte("range-test_7")

// 10件を上限にスキャンを行う
// 戻り値は、key,value共に[][]byte型
keysRes, valuesRes, err := cli.Scan(ctx, getLowerKey, getUpperKey, 10)

// キーとその内容を表示
for i, key := range keysRes {
  log.Printf("'%s'->'%s'", key, valuesRes[i])
}

こちらの出力結果は以下のようになります。

# Scan出力結果

'range-test_2'->'value-2'
'range-test_3'->'value-3'
'range-test_4'->'value-4'
'range-test_5'->'value-5'
'range-test_6'->'value-6'

下限に指定した range-test_2 は結果に含まれており、上限に指定した range-test_7 は含まれません。 TiKVではスキャンを行う際に、下限キー自体を含み(Inclusive)、上限キー自体は含まない(Exclusive)という仕様になっています。

また、 cli.Scan() は昇順のスキャンを行っていましたが、降順のスキャンを行う cli.ReverseScan() もサポートされています。

// スキャン対象のキー下限・上限
getLowerKey := []byte("range-test_2")
getUpperKey := []byte("range-test_7")

// 10件を上限に降順のスキャンを行う
// 戻り値は、key,value共に[][]byte型
keysRes, valuesRes, err = cli.ReverseScan(ctx, getUpperKey, getLowerKey, 10)

// キーとその内容を表示
for i, key := range keysRes {
  log.Printf("'%s'->'%s'", key, valuesRes[i])
}

結果はこちらのようになります。 Scanの場合と同様に、下限キーはInclusive、上限キーはExclusiveの関係となっています。

# ReverseScan出力結果

'range-test_6'->'value-6'
'range-test_5'->'value-5'
'range-test_4'->'value-4'
'range-test_3'->'value-3'
'range-test_2'->'value-2'

こちらも、サンプルコードのリポジトリ内で go run ./cmd/rawkv-range/. とすることで、一連の操作を試すことができます。 https://github.com/kamijin-fanta/tikv-sandbox/blob/master/cmd/rawkv-range/rawkv-range.go

スキャンのInclusive, Exclusive指定

キーの最後に 0x00 を付与することで、それぞれ下限キー自体を含まず(Exclusive)、上限キー自体を含む(Inclusive)アクセスを行うことも可能です。

getLowerKey := []byte("range-test_2")
getUpperKey := []byte("range-test_7")

// キーの最後に0x00を付与
getLowerKey = append(getLowerKey, 0)
getUpperKey = append(getUpperKey, 0)

keysRes, valuesRes, err := cli.Scan(ctx, getLowerKey, getUpperKey, 10)

// 以下、出力処理は省略
# Lower=Exclusive, Upper=Inclusive 出力結果

'range-test_3'->'value-3'
'range-test_4'->'value-4'
'range-test_5'->'value-5'
'range-test_6'->'value-6'
'range-test_7'->'value-7'

範囲の削除

先程用意したテストデータの削除を行います。 TiKVではキー範囲を指定することで、個別にキーを指定するよりも負荷を掛けずにキー削除を行うことができます。

今回は range-test_0 から range-test_9range-test_ プレフィックスを持つ値を削除したいので、 range-test_ から range-test_\xFF を削除対象としました。

delStartKey := []byte("range-test_")
delStopKey := []byte("range-test_\xFF")
err = cli.DeleteRange(ctx, delStartKey, delStopKey)

トランザクションの利用

今までRawKVを利用してTiKVへアクセスしていましたが、次はTxnAPIを利用してTiKVへアクセスを行ってみます。 クライアントの作成方法や、APIが一部異なりますが、基本的なアクセス方法に変わりは有りません。

まずは、トランザクションを開始した上でキーに値をセットします。

// PDを指定してクライアントの作成
client, err := txnkv.NewClient(addresses)
defer client.Close()

// トランザクションを開始
tx, err := client.Begin()

// キーのセット
err = tx.Set([]byte("key-1"), []byte("value-1"))
err = tx.Set([]byte("key-2"), []byte("value-2"))

// コミット
err = tx.Commit(ctx)

次に、今回セットした値を読み出してみましょう。

// トランザクションを開始
tx, err = client.Begin()

// キーの取得
v, err := tx.Get(ctx, []byte("key-1"))
log.Printf("Get key from TiKV '%s'", v)

他にもトランザクションの性質等の関係上、多少APIデザインが異なりますが、削除・スキャン等も同様に行うことができます。

こちらも、サンプルコードのリポジトリ内で go run ./cmd/txnkv-basic/. とすることで、一連の操作を試すことができます。 https://github.com/kamijin-fanta/tikv-sandbox/blob/master/cmd/txnkv-basic/txnkv-basic.go

さいごに

TiDBを支えているストレージシステムTiKVを駆け足で紹介させていただきました。

TiKVは単体でも利用することが可能なスケーラブルな分散KVSで、最近ではTiDB以外にも juicedata/juicefs 等のコミュニティで開発されるOSSでも利用可能になっています。 今回、構築も簡単でクライアントライブラリの利用も非常に手軽があることが分かっていただけたかと思われます。 ミドルウェアやアプリケーションへの組み込みも行いやすいと思いますので、今後さらにTiKVの利用が進むことを楽しみにしています。

また、こういった素晴らしいストレージシステムの上に構築されているTiDBも、非常に使いやすく魅力的なNewSQLです。 TiUPではTiDBの構築も可能ですし、 フルマネージドTiDBサービスのTiDB Cloud もトライアル頂くと魅力が伝わるのでは無いかと思います。

自分とTiKVの関わり

2018年頃に業務で開発していたプロダクトに導入できないかということで、TiKVへPRの提出等を行いました。 今回紹介したスキャンは当時昇順のスキャンのみが行える状況でした。 アクセスの性質上ReverseScanをサポートする必要があり、HBase等でも利用可能なAPIということもあったので実装を行いました。

https://github.com/tikv/tikv/pull/3724 https://github.com/tikv/client-go/pull/13

tikv get started 2022 09 06 17 35 25

その後TiKVを利用した製品は、さくらインターネットの"sakura.io"サービスの"データストア(V2)"としてサービスリリースを行っています。これをきっかけに社内でTiDBを利用したサービスもいくつかリリースされています。 参考記事: https://knowledge.sakura.ad.jp/29695/

また、個人的にTiKVが好きで同人誌も書きました。 こちらは2019年に開催された技術書典7にて頒布を行いました。

https://kinyoubenkyokai.github.io/book/techbook07/ tikv get started 2022 09 06 17 37 34

資料等

続きを読む