🔍

[翻訳] OpenSearch PPL による強化されたログ分析: lookup、join、subsearch の紹介

に公開

本記事は OpenSearch Project に投稿された "Enhanced log analysis with OpenSearch PPL: Introducing lookup, join, and subsearch" の日本語訳版です。一部冗長な表現をカットしています。


OpenSearch 3.0 では、lookupjoinsubsearch コマンドの追加により、Piped Processing Language (PPL) に強力な新機能が導入されました。これらのコマンドは、ログをより効率的に充実化、相関付け、フィルタリングするのに役立ちます。特に可観測性とログ分析のシナリオで有用です。例えば、認証ログとアプリケーションログを結合してセキュリティインシデントを調査したり、lookup コマンドを使用してリアルタイムでログに地理的位置情報のコンテキストを追加したりできます。サポートされている PPL コマンドの詳細については、PPL コマンドリファレンスを参照してください。

これらの機能強化は Apache Calcite によって支えられており、クエリの計画と実行も改善されます。これらが組み合わさることで、将来のバージョンでより高度な分析の基盤が築かれます。このアップデートにより、PPL はインタラクティブなデータ探索のためのより表現力豊かで効率的な言語になります。

これらの新機能を詳しく探索し、ログ分析ワークフローをどのように強化できるかを見てみましょう。

OpenSearch 3.0 PPL の新機能: Lookup、join、subsearch

ログを定期的に分析している場合、潜在的な問題を検出・調査するために大量のデータを篩い分けることがいかに困難かをご存知でしょう。OpenSearch 3.0 では、3 つの新しい PPL コマンド(lookupjoinsubsearch)が導入されました。これらのコマンドは複雑なログクエリを簡素化し、効率を向上させます。

lookupjoinsubsearch コマンドは実験的機能です。これらを使用するには、OpenSearch インスタンスで Calcite を有効にする必要があります。以下のリクエストを使用してこれを行うことができます:

curl -H 'Content-Type: application/json' -X PUT localhost:9200/_plugins/_query/settings -d '{
  "transient" : {
    "plugins.calcite.enabled" : true
  }
}'

新しいコマンドに入る前に、このブログ投稿全体で使用するサンプルデータセットを見てみましょう。

この投稿で使用するサンプルデータセット

新しいコマンドがどのように動作するかを実演するために、以下のサンプルデータセットを使用します。これらの構造を理解することで、例をより簡単に追うことができます。

認証ログ (auth_logs)

このデータセットはユーザーのログイン試行を追跡し、タイムスタンプ、ユーザー名、ログイン状態、IP アドレスなどの詳細を含みます。

timestamp user_id status ip_address
2024-04-29T10:00:00Z jdoe success 192.168.1.1
2024-04-29T10:05:00Z asmith failed 192.168.1.2
2024-04-29T10:10:00Z jdoe success 192.168.1.1

アプリケーションログ (app_logs)

このデータセットは、ログインやログアウトイベントなど、アプリケーションとのユーザーインタラクションを記録します。

timestamp user_id action session_id
2024-04-29T10:00:05Z jdoe login abc123
2024-04-29T10:05:10Z asmith login def456
2024-04-29T10:10:15Z jdoe logout abc123

ユーザー情報 (user_info)

この参照データセットには、部署や役職など、ユーザーに関する追加の詳細が含まれています。

user_id department role
jdoe HR Manager
asmith IT Analyst

データセットに慣れたところで、新しい PPL コマンドを使用してデータを分析する方法を探索してみましょう。

Lookup: 認証ログをユーザー情報で充実化

認証ログ内のユーザーについてより多くのコンテキストを得るには、lookup コマンドを使用して auth_logsuser_info データセットと組み合わせます。

以下のクエリは、departmentrole フィールドを追加することで認証ログを強化し、ログイン失敗試行に関連するユーザーをより良く理解するのに役立ちます:

source=auth_logs | lookup user_info user_id | where status='failed'

サンプル結果は以下のように表示されます。

timestamp user_id status ip_address department
2024-04-29T10:05:00Z asmith failed 192.168.1.2 IT

Join: 認証ログとアプリケーションログの相関付け

システム間でのユーザー行動を分析するには、user_idtimestamp に基づいて auth_logsapp_logs を結合できます。この相関付けにより、ユーザーのアクションを追跡し、アプリケーションとのインタラクションを理解するのに役立ちます:

source=auth_logs 
| join left=l right=r ON l.user_id = r.user_id AND TIME_TO_SEC(TIMEDIFF(r.timestamp, l.timestamp)) <= 60 app_logs 
| fields timestamp, user_id, action

サンプル結果は以下のように表示されます。

timestamp user_id action status
2024-04-29T10:00:00Z jdoe login success
2024-04-29T10:05:00Z asmith login failed
2024-04-29T10:10:00Z jdoe logout success

Subsearch: subsearch を使用した疑わしい活動の調査

subsearch コマンドを使用して、ログイン失敗を経験した後に成功ログインなどの特定のアクションを実行したユーザーを特定できます。これにより、さらなる調査のために潜在的に不正なアクセス試行を浮上させるのに役立ちます:

source=auth_logs 
| where status='failed' AND exists [source=app_logs | where user_id=auth_logs.user_id AND action='login']

サンプル結果は以下のように表示されます。

timestamp user_id status
2024-04-29T10:05:00Z asmith failed

各コマンドをいつ使用するか

各コマンドは特定のタイプのログ分析タスク用に設計されています。適切なものを選択するのに役立つクイックガイドは以下の通りです:

  • lookup – 外部参照データでログを充実化するのに最適。
  • join – 異なるインデックスからのログを相関付けて結合するのに理想的。
  • subsearch – 別のクエリの結果に基づく動的クエリ条件に優れている。

これらの新機能を完全に理解するには、Calcite 統合がどのように動作するかを理解することが役立ちます。

仕組み: Calcite 統合

OpenSearch PPL 3.0 は、堅牢な SQL 解析と最適化フレームワークである Apache Calcite を統合しています。強力な最適化機能、拡張性、強力なコミュニティサポートのために Calcite を選択しました。Calcite は解析とクエリ最適化レイヤーを提供することで OpenSearch PPL と統合されます。PPL クエリを最適化された実行プランに変換し、クエリの効率とスケーラビリティを大幅に向上させます。

Calcite でのクエリライフサイクル

OpenSearch PPL は、OpenSearch と PPL-on-Spark の両方で広く採用されている既存のクエリ文法と抽象構文木 (AST) を再利用します。文法は ANTLR4 を使用して定義され、Java、JavaScript、Python を含む複数のバックエンドとフロントエンドのポリグロットバリデーター間で共有されます。互換性を維持し既存のコンポーネントを再利用するために、統合アーキテクチャは以下の図に示すようにこの基盤の上に構築されます。

Query Lifecycle{:class="img-centered"}

クエリ処理ワークフローは複数の変換段階で構成され、クエリを生テキストから様々な中間表現を経て、最終的に実行される最終形式に変換します。主な段階の内訳は以下の通りです:

  1. クエリ解析:
    まず、SQL クエリテキストが ANTLR4 を使用して解析され、生クエリが解析木に変換されます。この木は次に AST に変換され、クエリの階層的構文構造をより抽象的な形で表現します。

  2. プラン変換:
    AST は RelBuilder と一連のビジターを使用して Calcite の RelNode 木に変換されます。RelNode は関係操作の Calcite の内部表現です。RelNode オブジェクトは論理プラン木を形成し、各ノードはフィルター、プロジェクト、結合などの関係代数操作を表します。

  3. 最適化と変換:
    Calcite のオプティマイザーは RelNode 木に様々な変換ルールを適用します。最適化された木は次に OpenSearchEnumerableRel ノード(Linq4j 式にマッピングできる Calcite の関係演算子の OpenSearch 固有の実装)に変換されます。

  4. コード生成と実行:
    Linq4j はブリッジフレームワークとして機能し、関係演算子を実行可能な Java コードに変換するためのテンプレートと式を提供します。このコードはメモリ内で行ごとにデータを処理します。パフォーマンス最適化のために、可能な場合、演算子またはプランのサブツリー(フィルターや集約など)がプッシュダウンされ、ネイティブ OpenSearch QueryBuilder API 呼び出しに変換され、OpenSearch エンジンによって直接実行されます。

Calcite オプティマイザーの動作

クエリを実行すると、Calcite はクエリオプティマイザーとして機能し、SQL ステートメントを効率的な実行プランに変換します。適用される中核的な最適化戦略の一つはフィルタープッシュダウンです。これは、フィルター条件をデータ取得操作にできるだけ近づける技術です。これにより、処理・転送されるデータ量が削減され、大幅なパフォーマンス向上につながります。

explain コマンドを使用したクエリプランの検査

クエリプランを表示し、Calcite がどのように実行を最適化したかを理解するには、EXPLAIN コマンドを使用できます。以下の例は、認証ログをユーザー詳細で充実化し、ログイン失敗試行をフィルタリングするクエリを検査する方法を示しています:

explain source=auth_logs | lookup user_info user_id | where status='failed'

論理プラン

論理プランは、クエリを実行するための高レベルで抽象的な戦略を表します。実行方法を指定せずに実行される操作の概要を示します。この例では、前述のクエリは以下の論理プランに変換されます:

LogicalProject(ip_address=[$0], user_id=[$1], status=[$2], timestamp=[$3], department=[$4])
  LogicalFilter(condition=[=($2, 'failed')])
    LogicalProject(ip_address=[$0], user_id=[$1], status=[$2], timestamp=[$3], department=[$10], _id=[$12], _index=[$13], _score=[$14], _maxscore=[$15], _sort=[$16], _routing=[$17])
      LogicalJoin(condition=[=($1, $11)], joinType=[left])
        CalciteLogicalIndexScan(table=[[OpenSearch, auth_logs]])
        CalciteLogicalIndexScan(table=[[OpenSearch, user_info]])

このプランでは、Calcite はクエリが status='failed' でフィルタリングし、user_id フィールドで auth_logs テーブルと user_info テーブルを結合すべきであると判断します。

物理プラン

物理プランは、論理プラン操作がどのように実行されるかを記述します。ソート、結合方法、フィルタープッシュダウンなどの具体的なステップと戦略が含まれます。最適化後、物理プランは以下のように表示される場合があります:

EnumerableCalc(expr#0..5=[{inputs}], proj#0..4=[{exprs}])
  EnumerableMergeJoin(condition=[=($1, $5)], joinType=[left])
    EnumerableSort(sort0=[$1], dir0=[ASC])
      EnumerableCalc(expr#0..9=[{inputs}], proj#0..3=[{exprs}])
        CalciteEnumerableIndexScan(table=[[OpenSearch, auth_logs]], PushDownContext=[[FILTER->=($2, 'failed')], OpenSearchRequestBuilder(sourceBuilder={"from":0,"timeout":"1m","query":{"term":{"status.keyword":{"value":"failed","boost":1.0}}},"sort":[{"_doc":{"order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
    EnumerableSort(sort0=[$1], dir0=[ASC])
      EnumerableCalc(expr#0..7=[{inputs}], proj#0..1=[{exprs}])
        CalciteEnumerableIndexScan(table=[[OpenSearch, user_info]])

このプランでは、Calcite はフィルター条件 status='failed'auth_logs テーブルの CalciteEnumerableIndexScan 操作にプッシュダウンしました。フィルターは次に OpenSearch クエリドメイン固有言語 (DSL) に変換されます。これは、フィルタリングがデータ取得段階で直接発生し、メモリに読み込まれて後続の操作で処理されるデータ量を最小化することを意味します。

今後の予定

OpenSearch コミュニティは Calcite 統合の構築を継続し、PPL の機能を拡張しています。計画されている内容は以下の通りです:

  • SQL を Calcite フレームワークに移行 – SQL と PPL を Calcite オプティマイザーの下で統一することで、クエリ処理が合理化され、クエリ言語間でより一貫した動作が可能になります。
  • より多くの PPL コマンドの追加 – 高度な分析ユースケースをサポートするために、eventstatsstreamstats などの新しいコマンドが計画されています。

OpenSearch PPL 3.0 の新機能を探索し、フィードバックを共有し、将来の改善に貢献することをお勧めします。OpenSearch クラスターで新しい PPL 3.0 機能を試し、ログ分析とクエリワークフローをどのように改善できるかを確認してください。皆様の意見はプロジェクトの方向性を形作り、コミュニティのニーズを満たすことを確実にするのに役立ちます。

Discussion