伝統的なデータベースにおける検索のボトルネック
以前、PostgreSQLに保存された約500万件のレコードを持つ製品カタログのプロジェクトを担当したことがあります。クライアントから「Googleのような」検索バーが欲しいと言われるまでは、パフォーマンスは非常に良好でした。彼らが求めていたのは、曖昧一致、関連性スコアリング、そして数十ものカラムにわたる瞬時の検索結果でした。MySQLやPostgreSQLは構造化データには強力ですが、このような特定の重い処理には向いていません。
SQLのLIKE '%keyword%'演算子はパフォーマンスの罠です。これはデータベースにフルテーブルスキャンを強制します。1万行なら管理可能ですが、500万行となると致命的です。私たちのケースでは、データセットが増えるにつれてクエリ時間が50ミリ秒から4秒近くまで跳ね上がりました。これを解決するには「転置インデックス(inverted index)」が必要です。長年、Elasticsearchが標準でしたが、ライセンスの変更により、コミュニティは真のオープンソースの代替案であるOpenSearchへと移行しました。
なぜOpenSearchなのか?
OpenSearchは、Elasticsearch 7.10.2からフォークされたコミュニティ主導のプロジェクトです。使い慣れたRESTful APIを維持しているため、既存のほとんどのアプリケーションでそのまま置き換えが可能です。主に2つのタスクに優れています。意図に基づいたドキュメント検索を行う全文検索と、数百万件のタイムシリーズイベントを解析するログ分析です。
これはOSDスタック(OpenSearch、Fluentd/Logstash、Dashboards)を支えるエンジンだと考えてください。アプリケーションがテキストクエリで動作が重くなっている場合や、50もの異なるマイクロサービスからのログを一元管理する必要がある場合、OpenSearchは最も信頼できる解決策です。Dockerを使ってマシン上で動かしてみましょう。
システムの前提条件
イメージをプルする前に、1つ重要なシステム設定を調整する必要があります。OpenSearchはインデックスの保存にmmapfsを使用します。ほとんどのLinuxディストリビューションではデフォルトのメモリマップ制限が低すぎ、OpenSearchコンテナが起動直後に「out of memory」エラーでクラッシュする原因となります。
以下のコマンドをLinuxホスト上で実行し、制限を必要な262,144まで引き上げます。
sudo sysctl -w vm.max_map_count=262144
この変更を再起動後も有効にするには、/etc/sysctl.confファイルにvm.max_map_count=262144を追加してください。WindowsやMacのDocker Desktopを使用している場合は、基盤となる仮想マシン内でこれを実行する必要があるかもしれません。
Docker Composeによるデプロイ
Docker Composeは、検索エンジンとそのウェブインターフェース(Dashboards)をまとめて管理する最もスマートな方法です。新しいプロジェクトフォルダを作成し、docker-compose.ymlファイルを配置します。スムーズに動作させるために、ホストマシンに少なくとも4GBのRAMを割り当てることを推奨します。
以下の設定ではセキュリティプラグインを無効にしています。これはローカル開発には便利ですが、本番環境では絶対に行わないでください。検索データをインターネットに公開する場合は、常にSSL/TLSと強力な認証を使用してください。
version: '3.8'
services:
opensearch-node:
image: opensearchproject/opensearch:2.11.0
container_name: opensearch-node
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node
- discovery.type=single-node
- bootstrap.memory_lock=true
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- osdata:/usr/share/opensearch/data
ports:
- 9200:9200
networks:
- opensearch-net
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.11.0
container_name: opensearch-dashboards
ports:
- 5601:5601
environment:
- 'OPENSEARCH_HOSTS=["http://opensearch-node:9200"]'
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true"
networks:
- opensearch-net
volumes:
osdata:
networks:
opensearch-net:
次のコマンドでスタックを起動します。
docker-compose up -d
サービスが起動するまで30〜60秒ほど待ちます。docker logs -f opensearch-nodeを実行してログを追跡し、進行状況を確認できます。
インストールの確認
デフォルトポートにアクセスして、APIが稼働しているか確認します。curlやブラウザを使用して、ステータスエンドポイントにアクセスしてください。
curl http://localhost:9200
バージョン番号(例:「2.11.0」)と「The OpenSearch Project: https://opensearch.org/」というキャッチフレーズを含むJSONペイロードが表示されれば、エンジンの準備は完了です。
次に、ブラウザでhttp://localhost:5601にアクセスします。これでOpenSearch Dashboardsが開きます。これはデータの可視化、インデックスの管理、複雑なcurlコマンドを書かずにクエリをテストできる強力なGUIです。
データのインデックス作成と検索
OpenSearchではSQLとは異なる用語を使用します。「テーブル」ではなくインデックス(index)、「行」ではなく**ドキュメント(document)**と呼びます。実際にやってみましょう。
1. ドキュメントの追加
booksという名前のインデックスを作成し、1つのエントリを追加します。OpenSearchはスキーマレスなので、”publish_date”が日付であり、”title”が文字列であることを自動的に検出します。
curl -X PUT "http://localhost:9200/books/_doc/1" -H 'Content-Type: application/json' -d'
{
"title": "The Phoenix Project(フェニックスプロジェクト)",
"author": "Gene Kim",
"category": "IT & DevOps",
"summary": "IT、DevOps、そしてビジネスの成功をテーマにした小説。",
"publish_date": "2013-01-10"
}'
2. 全文検索の実行
ここからが本番です。summaryフィールドの中から「ビジネス」という単語を検索します。OpenSearchはBM25アルゴリズムを使用して、見つかったすべてのドキュメントの関連性スコアを計算します。
curl -X GET "http://localhost:9200/books/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"summary": "ビジネス"
}
}
}'
レスポンスには_scoreが含まれます。もし「ビジネス」に言及している本が100冊あれば、その単語がより目立つ本がリストのトップに表示されます。
実践的なユースケース:ログ分析
本の検索も重要ですが、分散システムのトラブルシューティングはまた別物です。50ものマイクロサービスがある場合、個々のサーバーにSSHでログインしてログを読むのは不可能です.Fluent Bit経由でログをOpenSearchに転送すれば、100GBのデータからミリ秒単位で検索できます。
Dashboardsのインターフェースで、**Discover**タブを使用してサービス名やエラーレベルでログをフィルタリングできます。404エラー対500エラーの比率を示すリアルタイムの円グラフや、リクエストのレイテンシを追跡する折れ線グラフを作成することも可能です。この可視化の有無が、5分間のダウンタイムで済むか、5時間かかるかの分かれ道となります。
最後に
基本的なSQLクエリからOpenSearchのような専用エンジンに移行することで、開発ワークフローが変わります。遅いデータベーススキャンに悩まされることがなくなり、ユーザーが本当に喜ぶ機能の構築に集中できるようになります。Dockerを使えばテスト用のインスタンスを簡単に立ち上げられますし、ElasticsearchとAPI互換があるため、エコシステム内の既存のライブラリやツールのほとんどを利用できます。
Eコマースサイトを構築する場合でも、監視スタックを構築する場合でも、OpenSearchはデータの増加に合わせてスケールする、高性能でオープンソースな基盤を提供してくれます。

