Slide 1

Slide 1 text

IoT向けストレージに TiKVを採用したときの話 2024-10-25 TiUG Meetup #3 Tadahisa Kamijo

Slide 2

Slide 2 text

上條 忠久 ● さくらインターネット 2016年 新卒入社 ● ずっと大阪勤務 ● クラウド事業本部 所属 ● 今は監視基盤を開発中 ○ Go, Kotlin, React, TypeScript, TiDB, Trino, Iceberg… ※今日の話は多分当時はこうだったという適当な話です

Slide 3

Slide 3 text

入社直後 ● sakura.ioというIoTサービスの開発を行うことに ○ 通信モジュール・LTE回線・バックエンドサービスを提供

Slide 4

Slide 4 text

無限にスケールする IoTストレージを作って えっ? ワイ えらい人

Slide 5

Slide 5 text

第一世代 ● 当時DBはMySQL, Postgresql, Elasticsearchくらいしか知らなかった ● Elasticsearch良さそう ○ クラスタリング対応 スケーラビリティ・耐障害性高そう! ○ レプリカ・シャードを割と自由に設定できるらしい! ○ 自由にJSONでクエリ書ける! ● 社内でも何台か動いているらしい ● とりあえず作ってみよう ○ Elasticsearchにデータを入れるところは JavaSDK + Scala + Akka http ○ ユーザがアクセスする REST APIをPython + flask ● 2016年6月から開発・同年12月にリリース

Slide 6

Slide 6 text

第一世代 つらかった ● 実際にあった問題 ○ メモリ使用量が異様に多い・開くファイルの数が多すぎて止まる ○ データを投入する時にたまに止まる ○ クラスタリングしているのに、サーバ 1台止まるだけで止まる ○ クラスタにサーバを1台足すと止まる 調べると全部Elasticsearchが悪いんじゃなくて使い方が悪かった

Slide 7

Slide 7 text

なんで辛かったか ● ElasticsearchにはIndexという保存領域が存在 ● 毎日デバイス毎にIndexを作っていた ○ 1000デバイスが3ヶ月間保存すると9万Index ● どうやIndexあたり数MBのメモリが必要らしい ○ 9万Indexに必要なメモリ総量は 900GB…? ○ 当時1台に割り当て可能なメモリは 32GBが最大 ○ サーバ1台で30デバイスくらいしか収容できない … 1日1通のデバイスも居るんですが … ● Index毎にPrimary/Secondaryの選出等が行われる ○ ノードが追加・削除されたタイミングで全て選出し直される ● ノード間のデータの容量に偏りが少なくなるようにリバランスが入る ○ Indexあたり数十秒掛かる 並列でも数時間~数日単位で性能劣化 …

Slide 8

Slide 8 text

直した 毎日デバイス毎にIndexを作っていた ↓ 毎日全デバイスのメッセージを受け入れるIndexを作成

Slide 9

Slide 9 text

教訓 ● パフォーマンステストやったほうが良い ● ちゃんと仕組みを理解したほうが良い

Slide 10

Slide 10 text

どうしよう… ● ElasticsearchのIndex毎にWriteのスケール限界がある ● ”無限にスケール”からは遠ざかってしまった… ● 運用性も改善はされたが課題は残る ○ ノード追加・削除時にサービス断時間が減ったが …

Slide 11

Slide 11 text

第二世代の開発を開始 ● 主な要件 ○ デバイスから送信される JSONを保存・ユーザがHTTP APIでクエリできる事 ○ 1日に1メッセージのデバイス・ 1秒に1メッセージのデバイス 数万倍の差を吸収できる事 ● 色々なDBを調査 ○ Cassandra, HBase, Hypertable, Kudu, MapR, Druid, InfluxDB, TimescaleDB ○ 要件に合う・DB自体の運用が楽・アプリケーション側の実装が楽 なDBは意外と少ない ● 色々試した結果TiKVが一番向いていそうだ

Slide 12

Slide 12 text

TiKV ● TiDBの永続層として開発 ● Google BigTable(恐らくHBaseも)を参考に作られている ● 当時(2018年)日本で使っている人ぜんぜん居ない ● 何か問題が有ったらRust(TiKV開発言語)を書くという決意で導入 https://docs.pingcap.com/ja/tidb/stable/tidb-architecture

Slide 13

Slide 13 text

第二世代 ● ストレージはTiKV ● 開発言語はGo ○ TiKVのクライアントはGo向けが一番ちゃんとしていた ● TiKVは便利なクエリ/Indexがない ○ 基本的に↓だけでアプリケーションを作る ○ Get(key []byte) => []byte ○ Put(key []byte, value []byte) ○ Delete(key []byte) ○ Scan(keyStart []byte, keyEnd []byte) => [][]byte ● シンプルなので運用が比較的楽・コントロールしやすい

Slide 14

Slide 14 text

TiKVの扱い方 ● TiKVはデカい「Sorted Map」 ○ Keyの順番でソートされた Map(辞書) ● 容量等に応じて透過的に分割・クラスタ内で分担 ○ この要件にマッチする →1日に1メッセージのデバイス・ 1秒に1メッセージのデバイス ○ 分割によって書き込みスループットがスケール https://blog.kamijin-fanta.info/2022/09/tikv-get-started/

Slide 15

Slide 15 text

TiKVでのキー設計 IoTストレージでの利用例 ● Key: iotmsg_{deviceId}_{time}_{insertId} ● Value: JSON Payload Scanの仕方 ● 開始キー・終了キーを指定する 例: デバイス”aaa”の12:00:00~12:20:00 ● 開始: iotmsg_aaa_2024-10-25_12-00-00_ ● 終了: iotmsg_aaa_2024-10-25_12-20-00_   Key Value iotmsg_aaa_2024-10-25_12-10-00_AAAA {“paylaod”: … iotmsg_aaa_2024-10-25_12-20-00_BBBB {“paylaod”: … iotmsg_aaa_2024-10-25_12-30-00_CCCC {“paylaod”: … iotmsg_bbb_2024-10-25_12-05-00_DDDD {“paylaod”: … iotmsg_bbb_2024-10-25_12-15-00_EEEE {“paylaod”: … iotmsg_ccc_2024-10-25_12-08-00_FFFF {“paylaod”: … iotmsg_ddd_2024-10-25_12-09-00_GGGG {“paylaod”: …

Slide 16

Slide 16 text

第二世代リリース ● 2020年5月にTiKVバックエンドとした第二世代ストレージをリリース ● 運用性も非常に良かった ○ ノードの追加・削除で停止することも無くなった ○ スケーリングはTiKVが勝手にやってくれるので、サイジングの負荷軽減 ○ 消費リソース量は数十~数百分の 1 ○ ユーザへのレスポンス時間は数十分の 1 ● TiKVにPR送ったりもした https://github.com/tikv/tikv/pull/3724

Slide 17

Slide 17 text

さくらインターネットのIoTサービス 頑張って作ったが… ● 2016年4月1日 sakura.io パブリックα提供開始 ● 2017年4月18日 sakura.io 正式サービス提供開始 ● 2022年3月24日 後継サービス モノプラットフォーム提供開始 ● 2024年5月30日 モノプラットフォーム 新規申し込み停止 SIM 1枚月額13円から利用可能なセキュアモバイルコネクトは継続して提供中

Slide 18

Slide 18 text

なぜTiDBを使わなかった? ● TiDBはTiKV上に保存する際のキーを自由に指定できない ○ Key: table{tableId}_record{rowId} ○ tableIdはテーブルを分けることで変更できる・ rowIdはPKのint64 ● 1テーブルに書き込む場合はスケールに限界がある ○ 基本的にテーブルの末尾に追記する形になるので Prefixが分散しない(調整可能) ○ WriteよりReadが非常に多いサービスは特に問題にならない ● Key Prefixを分けるためにはTableを分ける必要がある ○ 今回のケースだと、1デバイス毎に1テーブル ○ スキーマ管理などのオペレーションが煩雑になりそう ※性能検証した上で受け入れられるならTiDBを使いましょう

Slide 19

Slide 19 text

IoT向けストレージにTiKVを採用したときの話 まとめ ● TiDBで利用されるTiKVの性質 ○ 大きいSorted Map ○ 便利クエリは存在しないが安定性・スケーラビリティに優れる ● アーキテクチャを理解・パフォーマンステストした上でリリースしよう ● GoからTiKVを触る話ブログで詳しく書いているので興味あれば ○ NewSQL TiDBを支える分散KVS "TiKV"入門 https://blog.kamijin-fanta.info/2022/09/tikv-get-started/ さくらインターネットでは“こういう”ストレージの話が出来る人も募集中です