データモデリング - Amazon Timestream

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

データモデリング

Amazon Timestream for LiveAnalytics は、タイムスタンプ付きの一連のデータを生成するアプリケーションやデバイスから時系列データを収集、保存、分析するように設計されています。最適なパフォーマンスを得るには、Timestream for LiveAnalytics に送信されるデータに時間的特性が必要であり、時間はデータの本質的なコンポーネントである必要があります。

Timestream for LiveAnalytics は、アプリケーションの要件に合わせてさまざまな方法でデータをモデル化する柔軟性を提供します。このセクションでは、これらのパターンのいくつかについて説明し、コストとパフォーマンスを最適化するためのガイドラインを提供します。ディメンションやメジャーなどの Timestream for LiveAnalytics の主要な概念を理解します。このセクションでは、以下について詳しく説明します。

データを保存するテーブルを 1 つ作成するか、複数のテーブルを作成するかを決定するときは、次の点を考慮してください。

  • 同じテーブルに配置するデータと、複数のテーブルとデータベース間でデータを分離する場合。

  • Timestream for LiveAnalytics の複数メジャーレコードと単一メジャーレコードのどちらを選択するか、特にアプリケーションが複数の測定値を同時に追跡している場合に、複数メジャーレコードを使用してモデリングする利点。

  • ディメンションまたはメジャーとしてモデル化する属性。

  • メジャー名の属性を効果的に使用してクエリのレイテンシーを最適化する方法。

単一テーブルと複数テーブル

アプリケーションでデータをモデル化する場合、もう 1 つの重要な点は、データをテーブルとデータベースにモデル化する方法です。Timestream for LiveAnalytics のデータベースとテーブルは、アクセスコントロールの抽象化、KMS キーの指定、保持期間などです。Timestream for LiveAnalytics は、データを自動的にパーティション化し、アプリケーションの取り込み、ストレージ、クエリの負荷と要件に合わせてリソースをスケーリングするように設計されています。

Timestream for LiveAnalytics のテーブルは、保存されたデータをペタバイト、数十ギガバイト/秒のデータ書き込みにスケールでき、クエリは 1 時間あたり数百TBsを処理できます。Timestream for LiveAnalytics のクエリは、複数のテーブルとデータベースにまたがることができ、結合とユニオンを提供して、複数のテーブルとデータベースのデータにシームレスにアクセスできます。したがって、Timestream for LiveAnalytics でデータを整理する方法を決定する場合、データやリクエストボリュームのスケールが主な懸念事項にはなりません。以下は、同じテーブルと異なるテーブル、または異なるデータベースのテーブルにどのデータを共に配置するかを決定する際の重要な考慮事項です。

  • データ保持ポリシー (メモリストア保持、マグネティックストア保持など) は、テーブルの粒度でサポートされています。したがって、異なる保持ポリシーを必要とするデータは、異なるテーブルに存在する必要があります。

  • AWS KMS データの暗号化に使用される キーは、データベースレベルで設定されます。したがって、暗号化キーの要件が異なる場合は、データが異なるデータベースに存在する必要があることを意味します。

  • Timestream for LiveAnalytics は、テーブルとデータベースの粒度でリソースベースのアクセスコントロールをサポートします。同じテーブルに書き込むデータと異なるテーブルに書き込むデータを決定するときは、アクセスコントロールの要件を考慮してください。

  • どのデータをどのテーブルに保存するかを決定するときは、ディメンション数、メジャー名、複数メジャー属性名の制限に注意してください。

  • クエリのレイテンシーと書き込みのしやすさはそれに依存するため、データの整理方法を決定するときは、クエリのワークロードとアクセスパターンを考慮してください。

    • 頻繁にクエリするデータを同じテーブルに保存する場合、通常、クエリの記述方法が簡単になるため、結合、ユニオン、または一般的なテーブル式を書き込む必要がなくなります。また、通常、クエリのレイテンシーも低くなります。ディメンションとメジャー名に述語を使用して、クエリに関連するデータをフィルタリングできます。

      例えば、6 つの大陸にあるデバイスからのデータを保存する場合を考えてみましょう。クエリが大陸間で頻繁にデータにアクセスしてグローバル集計ビューを取得する場合、これらの大陸のデータを同じテーブルに保存すると、クエリの書き込みが容易になります。一方、異なるテーブルにデータを保存しても、同じクエリでデータを結合することはできますが、テーブル間でデータを結合するクエリを記述する必要があります。

    • Timestream for LiveAnalytics は、データに対して適応型のパーティショニングとインデックス作成を使用します。そのため、クエリは、クエリに関連するデータに対してのみ課金されます。例えば、6 大陸にまたがる 100 万台のデバイスからのデータを保存するテーブルがある場合、クエリに WHERE device_id = 'abcdef'または の形式の述語がある場合WHERE continent = 'North America'、クエリはデバイスまたは大陸のデータに対してのみ課金されます。

    • 可能な限り、メジャー名を使用して、同時に出力されない、またはクエリの頻度が低い同じテーブル内のデータを分離し、クエリWHERE measure_name = 'cpu'で などの述語を使用すると、計測上の利点が得られるだけでなく、Timestream for LiveAnalytics はクエリ述語でメジャー名を使用しないパーティションを効果的に排除することもできます。これにより、クエリのレイテンシーやコストに影響を与えることなく、同じテーブルに異なるメジャー名を持つ関連データを保存でき、データを複数のテーブルに分散することを回避できます。メジャー名は、基本的にデータをパーティション化し、クエリに関係のないパーティションをプルーニングするために使用されます。

複数メジャーレコードと単一メジャーレコードの比較

Timestream for LiveAnalytics では、レコードごとに複数のメジャー (複数メジャー) またはレコードごとに 1 つのメジャー (単一メジャー) を使用してデータを書き込むことができます。

複数メジャーレコード

多くのユースケースでは、追跡しているデバイスまたはアプリケーションが、複数のメトリクスまたはイベントを同じタイムスタンプで出力することがあります。このような場合、同じタイムスタンプで出力されたすべてのメトリクスを同じ複数メジャーレコードに保存できます。つまり、同じ複数メジャーレコードに保存されているすべてのメジャーは、同じデータ行に異なる列として表示されます。

例えば、アプリケーションが同時に測定されるデバイスから cpu、メモリ、disk_iops などのメトリクスを出力しているとします。以下は、同時に出力される複数のメトリクスが同じ行に格納されるテーブルの例です。2 つのホストが 1 秒に 1 回メトリクスを出力していることがわかります。

ホスト名 measure_name [時間] cpu 「メモリ」 disk_iops
host-24Gju メトリクス 2021-12-01 19:00:00 35 54.9 38.2
host-24Gju メトリクス 2021-12-01 19:00:01 36 58 39
host-28Gju メトリクス 2021-12-01 19:00:00 15 55 92
host-28Gju メトリクス 2021-12-01 19:00:01 16 50 40

単一メジャーレコード

単一メジャーレコードは、デバイスが異なる期間に異なるメトリクスを出力する場合や、metrics/events at different time periods (for instance, when a device's reading/state の変更を出力するカスタム処理ロジックを使用している場合に適しています)。すべてのメジャーには一意のタイムスタンプがあるため、メジャーは Timestream for LiveAnalytics の独自のレコードに保存できます。例えば、土壌の温度と湿度を追跡する IoT センサーを考えてみましょう。これは、以前に報告されたエントリからの変更を検出した場合にのみレコードを発行します。次の例は、単一メジャーレコードを使用して出力されるデータの例を示しています。

device_id measure_name [時間] measure_value::double measure_value::bigint
sensor-sea478 温度 2021-12-01 19:22:32 35 NULL
sensor-sea478 温度 2021-12-01 18:07:51 36 NULL
sensor-sea478 湿度 2021-12-01 19:05:30 NULL 21
sensor-sea478 湿度 2021-12-01 19:00:01 NULL 23

単一メジャーレコードと複数メジャーレコードの比較

Timestream for LiveAnalytics では、アプリケーションの要件と特性に応じて、データを単一メジャーまたは複数メジャーのレコードとして柔軟にモデル化できます。アプリケーションの要件に応じて、単一のテーブルに単一メジャーレコードと複数メジャーレコードの両方を保存できます。一般に、アプリケーションが複数のメジャー/イベントを同時に出力する場合は、パフォーマンスの高いデータアクセスと費用対効果の高いデータストレージには、通常、データを複数メジャーレコードとしてモデル化することをお勧めします。

例えば、数十万台のサーバーからの DevOps ユースケース追跡メトリクスとイベントを考慮すると、各サーバーは定期的に 20 個のメトリクスと 5 個のイベントを出力し、イベントとメトリクスは同時に出力されます。そのデータは、単一メジャーレコードまたは複数メジャーレコードを使用してモデル化できます (結果のスキーマについては、オープンソースのデータジェネレーターを参照してください)。このユースケースでは、複数メジャーレコードを使用したデータのモデリングを単一メジャーレコードと比較した場合、次の結果になります。

  • 取り込み計測 - 複数メジャーレコードでは、書き込まれる取り込みバイト数が約 40% 減少します。

  • 取り込みバッチ処理 - 複数メジャーレコードでは、送信されるデータのバッチが大きくなります。つまり、クライアントが取り込みを処理するために必要なスレッドと CPU が少なくなります。

  • ストレージ計測 - 複数メジャーレコードでは、ストレージが約 8X低くなり、メモリとマグネティックストアの両方でストレージを大幅に節約できます。

  • クエリレイテンシー - 複数メジャーレコードでは、単一メジャーレコードと比較して、ほとんどのクエリタイプでクエリレイテンシーが低くなります。

  • クエリ計測バイト s - 10MB 未満のデータをスキャンするクエリの場合、単一メジャーレコードと複数メジャーレコードの両方が同等です。1 つのメジャーにアクセスし、> 10MB のデータをスキャンするクエリの場合、1 つのメジャーレコードは通常、計測バイト数が低くなります。3 つ以上のメジャーを参照するクエリの場合、複数メジャーのレコードは計測されるバイト数が低くなります。

  • 複数メジャークエリの表現のしやすさ - クエリが複数のメジャーを参照する場合、複数メジャーレコードでデータをモデル化することで、よりコンパクトなクエリを簡単に記述できます。

前述の要因は、追跡するメトリクスの数、データに含まれるディメンションの数などによって異なります。前の例では、1 つの例に関する具体的なデータをいくつか示していますが、多くのアプリケーションシナリオとユースケースで、アプリケーションが同時に複数の測定を発する場合、複数測定レコードとしてデータを保存する方が効果的であることがわかります。さらに、複数メジャーレコードは、データ型の柔軟性を提供し、他の複数の値をコンテキストとして保存します (例えば、リクエストIDsの保存や、後で説明する追加のタイムスタンプなど)。

複数メジャーレコードは、前の例のような単一メジャーレコードのスパースメジャーをモデル化することもできます。measure_name を使用してメジャーの名前を保存し、value_double を使用してDOUBLEメジャーを保存、value_bigint を使用してBIGINTメジャーを保存、value_timestamp を使用して追加のTIMESTAMP値を保存など、一般的な複数メジャー属性名を使用できます。

ディメンションとメジャー

Timestream for LiveAnalytics のテーブルでは、ディメンション (保存しているデバイス/データの属性を識別) と測定 (追跡しているメトリクス/値) を保存できます。詳細については、「Timestream for LiveAnalytics の概念」を参照してください。Timestream for LiveAnalytics でアプリケーションをモデル化する際、データをディメンションと測定にマッピングする方法は、取り込みとクエリのレイテンシーに影響します。以下は、ユースケースに適用できるディメンションとメジャーとしてデータをモデル化する方法に関するガイドラインです。

ディメンションの選択

時系列データを送信しているソースを識別するデータは、時間の経過とともに変化しない属性であるディメンションに適しています。例えば、メトリクスを発行するサーバーがある場合、ホスト名、リージョン、ラック、アベイラビリティーゾーンなど、サーバーを識別する属性がディメンションの候補になります。同様に、時系列データを報告する複数のセンサーを持つ IoT デバイスの場合、デバイス ID、センサー ID などがディメンションの候補です。

複数メジャーレコードとしてデータを書き込む場合、Word を実行するか、テーブルで DESCRIBE SELECTステートメントを実行すると、ディメンションと複数メジャー属性が列としてテーブルに表示されます。したがって、クエリを記述するときに、同じクエリでディメンションとメジャーを自由に使用できます。ただし、データを取り込むように書き込みレコードを作成するときは、ディメンションとして指定する属性とメジャー値として指定する属性を選択するときに、次の点に注意してください。

  • ディメンション名、値、メジャー名、タイムスタンプは、時系列データを一意に識別します。Timestream for LiveAnalytics は、この一意の識別子を使用してデータを自動的に重複排除します。つまり、Timestream for LiveAnalytics がディメンション名、ディメンション値、メジャー名、タイムスタンプの同じ値を持つ 2 つのデータポイントを受信した場合、値のバージョン番号が同じであれば、Timestream for LiveAnalytics は重複排除されます。新しい書き込みリクエストのバージョンが Timestream for LiveAnalytics に既に存在するデータよりも古い場合、書き込みリクエストは拒否されます。新しい書き込みリクエストのバージョンが大きい場合、新しい値は古い値を上書きします。したがって、ディメンション値の選択方法は、この重複排除動作に影響します。

  • ディメンション名と値は更新できず、測定値は にすることができます。そのため、更新が必要なデータはすべて、メジャー値としてモデル化される方が適しています。例えば、工場の現場に色を変更できる機械がある場合、重複排除に必要な識別属性としても色を使用する場合を除き、その色をメジャー値としてモデル化できます。つまり、測定値を使用して、時間の経過とともに徐々に変化する属性を保存できます。

Timestream for LiveAnalytics のテーブルは、ディメンション名と値の一意の組み合わせの数を制限しないことに注意してください。例えば、このような一意の値の組み合わせを数十億個テーブルに保存できます。ただし、次の例で示すように、ディメンションとメジャーを慎重に選択すると、特にクエリの場合、リクエストのレイテンシーが大幅に最適化されます。

ディメンション内の一意のIDs

アプリケーションシナリオで、すべてのデータポイント (リクエスト ID、トランザクション ID、相関 ID など) に一意の識別子を保存する必要がある場合、ID 属性をメジャー値としてモデル化することで、クエリのレイテンシーが大幅に向上します。複数メジャーレコードでデータをモデル化する場合、ID は他のディメンションや時系列データとのコンテキストで同じ行に表示されるため、クエリで引き続き効果的に使用できます。例えば、サーバーによって出力されるすべてのデータポイントに一意のリクエスト ID 属性がある場合の DevOps ユースケースを考えた場合、リクエスト ID をメジャー値としてモデル化すると、一意のリクエスト ID をディメンションとしてモデル化するのではなく、異なるクエリタイプ間でクエリレイテンシーが最大 4 倍低くなります。

すべてのデータポイントに対して完全に一意ではないが、数十万または数百万の一意の値を持つ属性に同様の類例を使用できます。これらの属性は、ディメンション値またはメジャー値の両方としてモデル化できます。前述のように、書き込みパスの重複排除に値が必要な場合、またはクエリでその属性の値に等価述語を持つ WHERE句 (例えば、アプリケーションが数百万のデバイスを追跡device_id = ‘abcde’している場所など) としてよく使用する場合、ディメンションとしてモデル化します。

複数メジャーレコードによるデータ型の豊富さ

複数メジャーレコードを使用すると、データを効果的にモデル化する柔軟性が得られます。複数メジャーレコードに保存するデータは、ディメンションに似た列としてテーブルに表示されるため、ディメンションとメジャー値のクエリも同じように簡単になります。これらのパターンの一部は、前述の例で確認できました。以下に、複数メジャーレコードを効果的に使用してアプリケーションのユースケースに対応するための追加パターンを示します。

複数メジャーレコードは、、DOUBLEBIGINTVARCHARBOOLEAN、および のデータ型の属性をサポートしますTIMESTAMP。そのため、さまざまなタイプの属性に自然に適合します。

  • 位置情報: 例えば、位置 (緯度と経度で表される) を追跡する場合、複数メジャー属性としてモデル化すると、特に緯度と経度の述語がある場合に、VARCHARディメンションとして保存するよりもクエリのレイテンシーが低くなります。

  • レコード内の複数のタイムスタンプ: アプリケーションシナリオで時系列レコードの複数のタイムスタンプを追跡する必要がある場合は、複数メジャーレコードの追加属性としてモデル化できます。このパターンは、将来のタイムスタンプまたは過去のタイムスタンプを含むデータを保存するために使用できます。すべてのレコードは、引き続き時間列のタイムスタンプを使用して、レコードをパーティション化、インデックス作成、一意に識別することに注意してください。

特に、クエリに述語がある数値データまたはタイムスタンプがある場合、それらの属性をディメンションではなく複数メジャー属性としてモデル化すると、クエリのレイテンシーが低くなります。これは、複数メジャーレコードでサポートされている豊富なデータ型を使用してこのようなデータをモデル化する場合、ディメンションとしてデータをモデル化すれば、VARCHAR から別のデータ型に値をキャストする代わりに、ネイティブデータ型を使用して述語を表現できるためです。

複数メジャーレコードでのメジャー名の使用

Timestream for LiveAnalytics のテーブルは、メジャー名と呼ばれる特別な属性 (または列) をサポートします。Timestream for LiveAnalytics に書き込むレコードごとに、この属性の値を指定します。単一メジャーレコードでは、メトリクスの名前 (cpu、サーバーメトリクスのメモリ、センサーメトリクスの温度、圧力など) を使用することが自然です。複数メジャーレコードを使用する場合、複数メジャーレコードの属性には名前が付けられるため (これらの名前はテーブルの列名になる)、cpu、メモリ、または温度、圧力が複数メジャーの属性名になる可能性があります。したがって、自然な質問は、メジャー名を効果的に使用する方法です。

Timestream for LiveAnalytics は、メジャー名属性の値を使用してデータをパーティション化およびインデックス化します。したがって、テーブルに複数の異なるメジャー名があり、クエリがそれらの値をクエリ述語として使用する場合、Timestream for LiveAnalytics はカスタムパーティショニングとインデックス作成を使用して、クエリに関連しないデータをプルアウトできます。例えば、テーブルに cpu とメモリのメジャー名があり、クエリに述語 がある場合WHERE measure_name = 'cpu'、Timestream for LiveAnalytics はクエリに関連しないメジャー名のデータを効果的にプルーニングできます。例えば、この例ではメジャー名のメモリを持つ行です。このプルーニングは、複数メジャーレコードでメジャー名を使用する場合にも適用されます。メジャー名属性は、テーブルのパーティショニング属性として効果的に使用できます。測定名とディメンション名と値、および時間は Timestream for LiveAnalytics テーブル内のデータのパーティション化に使用されます。Timestream for LiveAnalytics テーブルで許可される一意のメジャー名の数の制限に注意してください。また、メジャー名はメジャー値のデータ型にも関連付けられます。例えば、1 つのメジャー名は 1 つのタイプのメジャー値にのみ関連付けることができます。そのタイプは、DOUBLEBIGINT、、BOOLEANVARCHAR、および のいずれかになりますMULTI。メジャー名で保存された複数メジャーレコードのデータ型は になりますMULTI。1 つの複数メジャーレコードは、異なるデータ型 (DOUBLEBIGINT、、VARCHARTIMESTAMP) を持つ複数のメトリクスを保存できるためBOOLEAN、異なるタイプのデータを複数メジャーレコードに関連付けることができます。

以下のセクションでは、測定名属性を効果的に使用して、同じテーブル内の異なるタイプのデータをグループ化する方法のいくつかの異なる例について説明します。

品質と価値を報告する IoT センサー

IoT センサーからのデータをモニタリングするアプリケーションがあるとします。各センサーは、温度、圧力などのさまざまな測定値を追跡します。実際の値に加えて、センサーは測定値の品質も報告します。これは、読み取り値がどの程度正確であるかの尺度であり、測定の単位でもあります。品質、単位、値は一緒に出力されるため、以下の例のデータに示すように、複数メジャーレコードとしてモデル化できます。ここで、device_id はディメンション、品質、値、単位は複数メジャー属性です。

device_id measure_name [時間] Quality [単位]
sensor-sea478 温度 2021-12-01 19:22:32 92 35 c
sensor-sea478 温度 2021-12-01 18:07:51 93 34 c
sensor-sea478 pressure 2021-12-01 19:05:30 98 31 psi
sensor-sea478 pressure 2021-12-01 19:00:01 24 132 psi

このアプローチにより、複数メジャーレコードの利点を、メジャー名の値を使用してデータのパーティショニングとプルーニングと組み合わせることができます。クエリが温度などの単一のメジャーを参照している場合、クエリにメジャー名の述語を含めることができます。以下に、このようなクエリの例を示します。このクエリでは、品質が 90 を超える測定値の単位も射影されます。

SELECT device_id, time, value AS temperature, unit FROM db.table WHERE time > ago(1h) AND measure_name = 'temperature' AND quality > 90

クエリで measure_name 述語を使用すると、Timestream for LiveAnalytics はクエリに関連しないパーティションとデータを効果的にプルーニングできるため、クエリのレイテンシーが向上します。

すべてのメトリクスが同じタイムスタンプで出力されたり、複数のメトリクスが同じクエリで一緒にクエリされたりする場合、すべてのメトリクスを同じ複数メジャーレコードに保存することもできます。例えば、tempority_quality、tempority_value、tempority_unit、 pressure_quality、 pressure_value、 pressure_unit などの属性を持つ複数メジャーレコードとして構築できます。単一メジャーレコードと複数メジャーレコードを使用したデータのモデリングについて前述した点の多くは、データのモデル化方法の決定に適用されます。クエリのアクセスパターンとデータの生成方法を考慮して、コスト、取り込みとクエリのレイテンシー、クエリの記述のしやすさを最適化するモデルを選択します。

同じテーブル内のさまざまなタイプのメトリクス

複数メジャーレコードとメジャー名の値を組み合わせるもう 1 つのユースケースは、同じデバイスから独立して出力されるさまざまなタイプのデータをモデル化することです。 DevOps モニタリングのユースケースサーバーが定期的に生成されるメトリクスと不規則なイベントの 2 種類のデータを生成しているとします。このアプローチの例は、a DevOps ユースケースをモデル化するデータジェネレーターで説明されているスキーマです。この場合、異なるメジャー名を使用して、同じサーバーから出力される異なるタイプのデータを同じテーブルに保存できます。例えば、同時に出力されるすべてのメトリクスは、メジャー名のメトリクスとともに保存されます。メトリクスとは別の時点で出力されるすべてのイベントは、メジャー名イベントとともに保存されます。テーブルのメジャースキーマ (SHOW MEASURESクエリの出力など) は次のとおりです。

measure_name data_type ディメンション
events multi [{"data_type "varchar"dimension_nameavailability_zone"},{"data_type"varchar"dimension_name"microservice_name"},{"data_type"varchar""dimension_name"},{"data_type"varchar""instance_name"},{"data_type"""""""data_name""""""""."data_type""varchar"""""},{"data_type"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
メトリクス multi [{"data_type "varchar"dimension_nameavailability_zone"},{"data_type"varchar"dimension_name"microservice_name"},{"data_type"varchar""dimension_name"},{"data_type"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

この場合、イベントとメトリクスのディメンションのセットも異なることがわかります。イベントには異なるディメンション jdk_version と process_name があり、メトリクスにはディメンション instance_type と os_version があります。

異なるメジャー名を使用すると、 などの述語を使用してクエリを記述WHERE measure_name = 'metrics'し、メトリクスのみを取得できます。また、同じテーブル内の同じインスタンスから出力されるすべてのデータがある場合、instance_name 述語を使用してより単純なクエリを記述して、そのインスタンスのすべてのデータを取得することもできます。例えば、measure_name 述語WHERE instance_name = ‘instance-1234’のないフォームの述語は、特定のサーバーインスタンスのすべてのデータを返します。

複数メジャーレコードのパーティション化に関する推奨事項

重要

このセクションは廃止されました。

これらのレコメンデーションは古くなっています。お客様が定義したパーティションキーを使用して、パーティショニングをより適切に制御できるようになりました。

時系列エコシステムでは、大量のデータを取り込んで保存する必要があるワークロードが増え、同時に高基数セットのディメンション値でデータにアクセスするときに低レイテンシーのクエリレスポンスが必要であることがわかりました。

このような特性のため、このセクションの推奨事項は、次のようなお客様のワークロードに役立ちます。

  • 複数メジャーレコードを採用する、または採用したい。

  • システムに大量のデータが入り、長期間保存されることを想定しています。

  • メインアクセス (クエリ) パターンには低レイテンシーの応答時間が必要です。

  • 最も重要なクエリパターンには、述語で何らかのフィルタリング条件が含まれることに注意してください。このフィルタリング条件は、高基数ディメンションに基づいています。例えば、Word、 UserId、ServerID DeviceId、host-name などのイベントや集計を考えてみましょう。

このような場合、エンジンは複数メジャー名を使用してデータをパーティション化し、単一の値を指定すると、得られるパーティションの利点が制限されるため、すべての複数メジャーの単一の名前は役に立ちません。これらのレコードのパーティショニングは、主に 2 つのディメンションに基づいています。時間は X 軸に、ディメンション名のハッシュに、Y 軸measure_nameに があるとします。このような場合measure_name、 はパーティショニングキーとほぼ同様に機能します。

推奨事項は次のとおりです。

  • 前述のようなユースケースのためにデータをモデル化する場合は、メインクエリアクセスパターンの直接派生measure_nameである を使用します。例:

    • ユースケースでは、エンドユーザーの観点からアプリケーションのパフォーマンスと QoE を追跡する必要があります。これは、単一のサーバーまたは IoT デバイスの測定値を追跡することにもなります。

    • UserId でクエリおよびフィルタリングする場合は、取り込み時に UserId measure_nameに関連付ける最適な方法を見つける必要があります。

    • 複数メジャーテーブルには 8,192 個の異なるメジャー名しか保持できないため、採用される式は 8,192 個を超える値を生成しないでください。

  • 文字列値に成功して適用した方法の 1 つは、文字列値にハッシュアルゴリズムを適用することです。次に、ハッシュ結果の絶対値と 8192 を使用してモジュロオペレーションを実行します。

    measure_name = getMeasureName(UserId)
    int getMeasureName(value) {
        hash_value =  abs(hash(value))
        return hash_value % 8192
    }
  • またabs()、 を追加して、値の範囲が -8192 から 8192 である可能性を排除しました。これはモジュロ操作の前に実行する必要があります。

  • この方法を使用すると、パーティション分割されていないデータモデルで を実行するのにかかる時間のごく一部でクエリを実行できます。

  • データをクエリするときは、新たに導出された measure_name の値を使用するフィルタリング条件を述語に含めるようにしてください。例:

    • SELECT * FROM your_database.your_table WHERE host_name = 'Host-1235' time BETWEEN '2022-09-01' AND '2022-09-18' AND measure_name = (SELECT cast(abs(from_big_endian_64(xxhash64(CAST('HOST-1235' AS varbinary))))%8192 AS varchar))
    • これにより、時間の経過とともに高速クエリに変換されるデータを取得するためにスキャンされるパーティションの合計数が最小限に抑えられます。

このパーティションスキーマの利点を享受するには、クライアント側でハッシュを計算し、クエリエンジンに静的な値として Timestream for LiveAnalytics に渡す必要があることに注意してください。前の例では、生成されたハッシュが必要に応じてエンジンによって解決できることを検証する方法を示しています。

時間 host_name ロケーション server_type cpu_usage available_memory cpu_temp

2022-09-07 21:48:44 .000000000

host-1235

us-east1

5.8xl

55

16.2

78

R2022-09-07 21:48:44 .000000000

host-3587

us-west1

5.8xl

62

18.1

81

2022-09-07 21:48:45.000000000

host-258743

eu-central

5.8xl

88

9.4

91

2022-09-07 21:48:45 .000000000

host-35654

us-east2

5.8xl

29

24

54

R2022-09-07 21:48:45 .000000000

host-254

us-west1

5.8xl

44

32

48

レコメンデーションmeasure_nameに従って関連する を生成するには、取り込みパターンに依存する 2 つのパスがあります。

  1. 履歴データのバッチ取り込みの場合 - バッチプロセスに独自のコードを使用する場合は、書き込みコードに変換を追加できます。

    前の例の上に構築します。

    List<String> hosts = new ArrayList<>(); hosts.add("host-1235"); hosts.add("host-3587"); hosts.add("host-258743"); hosts.add("host-35654"); hosts.add("host-254"); for (String h: hosts){ ByteBuffer buf2 = ByteBuffer.wrap(h.getBytes()); partition = abs(hasher.hash(buf2, 0L)) % 8192; System.out.println(h + " - " + partition); }

    出力

    host-1235 - 6445
    host-3587 - 6399
    host-258743 - 640
    host-35654 - 2093
    host-254 - 7051
    

    結果のデータセット

    時間 host_name ロケーション measure_name server_type cpu_usage available_memory cpu_temp

    2022-09-07 21:48:44 .000000000

    host-1235

    us-east1

    6445

    5.8xl

    55

    16.2

    78

    R2022-09-07 21:48:44 .000000000

    host-3587

    us-west1

    6399

    5.8xl

    62

    18.1

    81

    2022-09-07 21:48:45.000000000

    host-258743

    eu-central

    640

    5.8xl

    88

    9.4

    91

    2022-09-07 21:48:45 .000000000

    host-35654

    us-east2

    2093

    5.8xl

    29

    24

    54

    R2022-09-07 21:48:45 .000000000

    host-254

    us-west1

    7051

    5.8xl

    44

    32

    48

  2. リアルタイム取り込みの場合 - データが入ってくるとmeasure_name、処理中の を生成する必要があります。

いずれの場合も、ハッシュ生成アルゴリズムを両端 (取り込みとクエリ) でテストして、同じ結果が得られることを確認することをお勧めします。

に基づいてハッシュ化された値を生成するコード例をいくつか示しますhost_name

例 Python
>>> import xxhash >>> from bitstring import BitArray >>> b=xxhash.xxh64('HOST-ID-1235').digest() >>> BitArray(b).int % 8192 ### 3195
例 Go
package main import ( "bytes" "fmt" "github.com/cespare/xxhash" ) func main() { buf := bytes.NewBufferString("HOST-ID-1235") x := xxhash.New() x.Write(buf.Bytes()) // convert unsigned integer to signed integer before taking mod fmt.Printf("%f\n", abs(int64(x.Sum64())) % 8192) } func abs(x int64) int64 { if (x < 0) { return -x } return x }
例 Java
import java.nio.ByteBuffer; import net.jpountz.xxhash.XXHash64; public class test { public static void main(String[] args) { XXHash64 hasher = net.jpountz.xxhash.XXHashFactory.fastestInstance().hash64(); String host = "HOST-ID-1235"; ByteBuffer buf = ByteBuffer.wrap(host.getBytes()); Long result = Math.abs(hasher.hash(buf, 0L)); Long partition = result % 8192; System.out.println(result); System.out.println(partition); } }
例 Maven の依存関係
<dependency> <groupId>net.jpountz.lz4</groupId> <artifactId>lz4</artifactId> <version>1.3.0</version> </dependency>