Slide 1

Slide 1 text

秋の夜⻑にAmazon Timestreamとゆっくりと 向き合ってみた Satoshi Kaneyasu 2023.10.25

Slide 2

Slide 2 text

2 ⾃⼰紹介 ⽒名︓兼安 聡 所属︓株式会社サーバーワークス 最近興味あるもの︓DevOps、CI/CDパイプライン 趣味︓サックス、筋トレ、CS ゲーム 資格︓ X(Twitter)︓@satoshi256kbyte など

Slide 3

Slide 3 text

3 [アイスブレイク]ご存知ですか︖ 最新作ではタイムがないんですよ

Slide 4

Slide 4 text

⽬次 1. トーク内容の⽬的 2. Amazon Timestreamを使う理由 3. 単⼀メジャーとマルチメジャー 4. メモリストアとマグネティックストア 5. パーティションキー 6. スケジュールクエリ 7. まとめ

Slide 5

Slide 5 text

5 トーク内容の⽬的 IoTを使⽤したシステムで、Amazon Timestreamのテーブル設計をす るにあたり、個⼈的に難解と感じた部分の調査結果を共有します。 皆様の設計作業のヒントになれば幸いです。 [検証環境] • Amazon Timestream(東京リージョン) • AWS Lambda(データ作成⽤、東京リージョン) • Grafana(Docker+Timestream⽤プラグイン)

Slide 6

Slide 6 text

Amazon Timestreamを使う理由

Slide 7

Slide 7 text

7 Amazon Timestreamとは • Amazon Timestreamは時系列データに特化したDB • スケーラブルであり、データライフサイクル管理を備える

Slide 8

Slide 8 text

8 Amazon Timestreamと他のDBとの⽐較 • ⼤量の書込みに耐えれて、SQLも使⽤可能 • RDBMSでも時系列データを扱うことは可能だが、 ⼤量の書込みに耐えれるよう構築するのは容易ではない • 専⽤に設計されているAmazon Timestreamは有⼒ • 書込み性能ならAmazon DynamoDBも有⼒だが、 SQLが弱いため集計・分析するのに⼯夫が必要

Slide 9

Slide 9 text

9 なまじSQLが使える分、⼾惑うことも • トランザクションがない • ALTER、UPDATE(*)、DELETE⽂はない • VIEW、プロシージャはない • 上記の伝統的なRDBMSの機能が使えないのは問題とは感じないが、 なまじSQLが使えてしまう故にRDBMSの知識に引っ張られることも (*)versionという特殊な機能で更新のようなことは可能

Slide 10

Slide 10 text

10 Amazon Timestreamの基本⽤語 • ディメンション • データのメタデータ/特徴 • ディメンション+timeで⼀意となる • メジャー • 測定値、キーバリュー形式 • キーに対するバリューが⼀つの単体メジャー、複数のマルチメジャーがある ディメンション メジャー(キー) メジャー(バリュー)

Slide 11

Slide 11 text

11 Amazon Timestreamをテーブル設計上で重要な機能 • メモリストアとマグネティックストア • 単⼀メジャーとマルチメジャー • パーティションキー • スケジュールクエリ

Slide 12

Slide 12 text

メモリストアとマグネティックストア

Slide 13

Slide 13 text

13 メモリストアとマグネティックストアは役割が違う メモリストア マグネティックストア ⼀定期間後に移動 ⼀定期間後に破棄 多数の送信元から発⽣する ⼤量のデータ送信 • ⾼スループットのデータ書き込み • ⾼速なポイントインタイムクエリ⽤に最適化 • 低スループットの後発データ書き込み • ⻑期データ保存 • ⾼速分析クエリ 単純にメモリストアの⽅が速いキャッシュのような仕組み とは⾔い切れない

Slide 14

Slide 14 text

14 データは⼀定期間後にマグネティックストアに移動する ↓テーブルの設定 メモリストア マグネティックストア 現在がAM7:00だとすると・・・ タイムスタンプが AM6:00〜7:00 タイムスタンプが 〜 AM 5:59 登録NG 1時間後に移動 1⽇後に破棄

Slide 15

Slide 15 text

15 マグネティックストレージの書込み ↓テーブルの設定 メモリストア マグネティックストア 現在がAM7:00だとすると・・・ AM6:00〜7:00の レコード 〜 AM 5:59の レコード 1時間後に移動 1⽇後に破棄 直に マグネティックへ

Slide 16

Slide 16 text

16 メモリストアとマグネティックストアでいきなりつまずく 1. 最初だからコストを気にして、 メモリストアとマグネティックストアの保持期間を最⼩にする 2. 最初だからよくわからないオプションの、 「マグネティックストレージへの書き込み」のチェックを外す 3. テストデータとして過去1週間分のデータを作ってみる 4. 書き込みが全然通らない 5. そもそも書き込みが通らないってどういうこと︖︖︖😰になる

Slide 17

Slide 17 text

17 保持期間の設定をどう考えるか︖ メモリストア マグネティックストア ⼀定期間後に移動 ⼀定期間後に破棄 多数の送信元から発⽣する ⼤量のデータ送信 • ⾼スループットのデータ書き込み • ⾼速なポイントインタイムクエリ⽤に最適化 • 低スループットの後発データ書き込み • ⻑期データ保存 • ⾼速分析クエリ 遅れて到着するデータがどれぐらいか︖などを考慮し、 ここをどれぐらいの時間幅で担保したいか︖で考える (後から変更は可能)

Slide 18

Slide 18 text

18 [余談]メモリストアとマグネティックストアとの速度⽐較 • データが今現在メモリにあるのか、マグネティックにあるのかを確認 する術はなかった • AWS Lamdaとクエリエディタで、5万件ほどのデータを読み書きし てみたが、メモリストアとマグネティックストアにはほどんど速度差 が⾒られなかった。 • 単⼀のクライアントからしかアクセスしてないので、 もっと⼤量のクライアントを⽤意しないと検証不可なのかもしれない。

Slide 19

Slide 19 text

単⼀メジャーとマルチメジャー

Slide 20

Slide 20 text

20 単⼀メジャーとマルチメジャー マルチメジャーは横持ちレコード ⼀つのタイミングで複数の値が送信されるならこちら 単⼀メジャーは縦持ちレコード 各測定値が送信されるタイミングが異なるならこちら [参考] Multi-measure records vs. single-measure records

Slide 21

Slide 21 text

23 マルチメジャーは列が可変 最初は空の状態 マルチメジャー(1列)を指定して登録 次に、マルチメジャー(2列)を指定して登録

Slide 22

Slide 22 text

24 単⼀メジャーとマルチメジャーのコード⽐較 単体メジャー マルチメジャー

Slide 23

Slide 23 text

25 マルチメジャーの制限 1⾏内で、256個を超える列を使⽤して登録すると登録エラーになる ⾃動カットにはならない 可変列 複数レコードで棲み分けても、 可変の列がテーブル全体で合計1024個を超えると登録エラー これも⾃動カットにはならない hostname az region measure_name time 1- 256列⽬ 256- 512列⽬ 512- 768列⽬ 768- 1025列⽬ host-1 az-1 region status time 使⽤ host-2 az-1 region alert time 使⽤ host-3 az-1 region environment time 使⽤ host-4 az-1 region sensor time 使⽤ 4⾏⽬を登録しようと するとエラー

Slide 24

Slide 24 text

26 256と1024という数字について 1024の制約は私には扱いづらいので、 できる限りマルチメジャーの上限は256と捉えて、 データ種類が異なればテーブルを分割するように努めています。

Slide 25

Slide 25 text

27 [余談]ディメンションも追加できてしまった ディメンションを3つ指定して追加 次は、ディメンションを4つ指定して追加 ドキュメントからディメンションは後から変更できないと理解していたのだが、 解釈が違っていたようだ

Slide 26

Slide 26 text

パーティションキー

Slide 27

Slide 27 text

30 パーティションとは テーブル ap_noartheast_1 ap_noartheast_2 パーティションキー= region パーティションは、よく使う条件を⾒越してテーブルの内部を分割しておく技術 パーティションキーに沿ったSQLが速くなる データ データ SELECT count(1) FROM "kaneyasu-timestream-multi"."parition_table” WHERE region = 'ap-northeast-1'

Slide 28

Slide 28 text

31 デフォルトのパーティションキーはmeasure_name 単⼀メジャーにすると、縦持ちレコードになる。 measure_nameを頻繁に指定するだろうから、適切なパーティションキーと思われる。

Slide 29

Slide 29 text

32 マルチメジャーのパーティションキー マルチメジャーにすると、measure_nameが被りがちなので、 独⾃のパーティションキーを設定した⽅がよいと思われる。

Slide 30

Slide 30 text

33 パーティションキーを設定してみる

Slide 31

Slide 31 text

34 パーティションキーの効果を測ってみる パーティションキーあり パーティションキーなし SELECT count(1) FROM "kaneyasu-timestream-multi"."parition_table” WHERE region = 'ap-northeast-1' SELECT count(1) FROM "kaneyasu-timestream-multi".”no_parition_table” WHERE region = 'ap-northeast-1' 0.1520 秒 〜 0.1860 秒 0.1840 秒 〜 0.3770 秒

Slide 32

Slide 32 text

35 パーティションキーの説明⽂の意味の確認 ディメンジョンキーの中から 1つだけ選ぶ ONにすると、 上記設定したキーが含まれないレコードは 登録エラーになる カンマ区切りにしても、 複数指定にはならない [参考] クエリパフォーマンスの最適化につながる Amazon Timestream の顧客定義パーティションキー機能 複合︖🤔

Slide 33

Slide 33 text

スケジュールクエリ

Slide 34

Slide 34 text

37 Amzon Timestreamの関数を利⽤したSQL SELECT fleet, truck_id, fuel_capacity, model, load_capacity, make, measure_name, BIN(time, 1h) AS binned_timestamp, ROUND(AVG(load), 2) AS avg_1hour_load, ROUND(AVG("fuel-reading"), 2) AS "avg_1hour_fuel-reading", ROUND(AVG(speed), 2) AS avg_1hour_speed FROM "kaneyasu-timestream-multi"."IoTMulti" WHERE time BETWEEN ago(2h) AND ago(1h) GROUP BY fleet, truck_id, fuel_capacity, model, load_capacity, make, measure_name, BIN(time, 1h) ORDER BY binned_timestamp ASC ⼀時間ごとに各列の平均値を求めるSQL

Slide 35

Slide 35 text

38 RDBMSでいうVIEWは存在しない 集計機能が豊富なのはわかるが、複雑なSQLを都度書くのは⾯倒 スケジュールクエリという⼿がある

Slide 36

Slide 36 text

39 スケジュールクエリの設定

Slide 37

Slide 37 text

41 スケジュールクエリにこだわり過ぎない 現状、スケジュールクエリは動的なSQLには対応していない 列が固定しきれない場合は、Lambdaで動的なSQLを構築・実⾏した⽅ がよいこともある 列が増えるのが予⾒できて、 固定SQLで対応仕切れない場合は、 スケジュールクエリでの対応は難しい

Slide 38

Slide 38 text

まとめ

Slide 39

Slide 39 text

43 まとめ • Amazon Timestreamは⼤量の書込みに耐えれて、SQLも使⽤可能 • メモリストアとマグネティックストアは⽤途が違う • マルチメジャーの制約はわかりにくいので注意 • パーティションキーは1つだけ︖指定できる • スケジュールクエリは便利だがこだわり過ぎないように 今回の内容が皆様の設計作業の役に⽴てば幸いです。

Slide 40

Slide 40 text

ご清聴ありがとうございました。

Slide 41

Slide 41 text

No content