システムデザインのチートシート:ElasticSearch

「システムデザインの簡易ガイド:ElasticSearch」

ElasticSearchを使用するタイミングと方法を理解し、3つの実践的なシステムデザイン例を把握する

はじめに

検索とは何か?なぜ重要なのか?

以前の記事で読んだ方なら、アプリケーションにおける検索の重要性を理解しているでしょう。考えてみてください:毎日使用するさまざまなウェブアプリやモバイルアプリ(Netflix、Amazon、Swiggyなど)の中で、検索バーはおそらく共通のUI要素であり、それも通常はホームページのトップに配置されています。システムを設計している場合、99回中99回は検索エンジンの構築方法を考えることになるでしょう。

検索システムを構築することは容易なことではありませんが、ElasticSearchは優れた出発点です。検索やレコメンデーションシステムの仕組みについて何も知らない場合は、このブログ記事が良いスタート地点となるでしょう。ElasticSearchとは何か、どこで使用されるのか、どこで使用されないのか、そしてElasticSearchが使用される一般的な設計について説明します。検索システムにはさらに多くの属性がありますが、記事の最後に詳細に触れます。

ElasticSearchとは?

ElasticSearchは、ほとんどのデータベースが苦労することを行う人気のあるデータベースです:検索。検索はElasticSearchの本質であり、実際に名前にも含まれています!

しかし、ElasticSearchについて聞いたことがない場合、おそらく次のように考えているかもしれません:なぜ検索は困難なのですか?リレーショナルデータベースはなぜ検索を実行できないのですか?ほとんどのリレーショナルデータベースは、WHEREクエリ、LIKEキーワード、またはインデックスなど、さまざまな方法でデータを検索およびフィルタリングするサポートを提供しています。また、なぜMongoDBのようなドキュメントデータベースは機能しないのですか?MongoDBでもfindクエリを記述することができます。

答えを理解するために、ニュースのウェブサイトを構築していると想像してみてください。ユーザーが検索バーを使用して、「ニューデリーのCOVID19感染」と検索する場合、ユーザーはニューデリーのCOVID感染について話すすべての記事に興味があります。単純な検索システムでは、データベースのすべての記事をスキャンし、「COVID19」、「感染」、または「ニューデリー」という単語を含む記事を返すことになります。しかし、リレーショナルデータベースではそれを実行することはできません。リレーショナルデータベースでは、特定の属性に基づいて記事を検索できますが(たとえば、特定の著者による記事や今日公開された記事など)、特定の単語を含むすべてのニュース記事(通常は数百万件)をスキャンし、それに基づいて返すことはできません(少なくとも効率的にはできません)。

さらに、考慮すべき細かい点もたくさんあります。これらの記事をどのようにスコアリングしますか?COVID19感染拡大について語る記事と、新たな感染について語る記事があるかもしれませんが、ユーザーのクエリに対してどれがより関連性が高いか、つまりこれらの記事を関連性に基づいてソートする方法をどのように知ることができますか?

答えは:ElasticSearch! ElasticSearchは、これらすべてを簡単に行うことができます。

ただし、世の中の他のすべてのものと同様に、ElasticSearchにも欠点があります。ElasticSearchが何か、いつ使用するべきか、そして最も重要なことは、いつ使用しないべきかについて議論しましょう。

ElasticSearch

検索の能力

ElasticSearchは「全文検索」を実行する方法を提供しています。全文検索とは、膨大なドキュメントのコーパス内でフレーズやワードを検索することを指します。先ほどの例を続けてみましょう。数百万のニュース記事を含むニュースウェブサイトを構築していると想像してください。各記事には見出し、サブ見出し、記事の内容、公開日などのデータが含まれています。ElasticSearchのコンテキストでは、各記事はJSONドキュメントとして格納されます。

これらのドキュメントをすべてElasticSearchに読み込み、それぞれのドキュメント内の特定のワードやフレーズを数ミリ秒で検索することができます。したがって、すべてのニュース記事を読み込んでから「ニューデリーのCOVID19感染」という検索を実行すると、ElasticSearchは「COVID19」、「感染」、または「ニューデリー」というワードを含むすべての記事を返します。

Elasticsearchの検索機能をデモンストレーションするために、Elasticsearchをセットアップし、データをロードしてみましょう。この投稿では、Kaggleで見つけたこのニュースデータセット(Misra, Rishabh. “News Category Dataset.” arXiv preprint arXiv:2209.11429 (2022)) (ソース) (ライセンス)を使用します。このデータセットは非常にシンプルで、約21万のニュース記事が含まれており、見出し、短い説明、著者、他のいくつかのフィールドが含まれています。全部のデータは必要ありませんので、ESには約1万のドキュメントをロードして検索を開始します。

以下はデータセット内のいくつかのドキュメントの例です。

[  {    "link": "https://www.huffpost.com/entry/new-york-city-board-of-elections-mess_n_60de223ee4b094dd26898361",    "headline": "Why New York City’s Board Of Elections Is A Mess",    "short_description": "“There’s a fundamental problem having partisan boards of elections,” said a New York elections attorney.",    "category": "POLITICS",    "authors": "Daniel Marans",    "country": "IN",    "timestamp": 1689878099  },  ....]

各ドキュメントはニュース記事を表しています。各記事にはlinkheadlineshort_descriptioncategoryauthorscountry(ランダムな値、私が追加しました)、およびtimestamp(再びランダムな値、私が追加しました)が含まれています。

ElasticsearchのクエリはJSON形式で記述されます。検索クエリを作成するために使用できるさまざまな構文について深く掘り下げる代わりに、シンプルに始めてそこから構築していきましょう。

最もシンプルな全文検索クエリの1つがmulti_matchクエリです(Elasticsearchでのデータのクエリについては、心配する必要はありません。それは非常に簡単であり、記事の最後でそれについて話す予定です)。アイデアはシンプルで、クエリを書き、Elasticsearchがフルテキスト検索を実行し、データベース内のすべてのドキュメントをスキャンし、そのクエリ内に含まれる単語を含むドキュメントを見つけ、それにスコアを付けて返すことです。例えば、

GET news/_search{  "query": {    "multi_match": {      "query": "COVID19 infections"    }  }}

上記のクエリは、クエリ「COVID19 infections」に関連する記事を検索します。以下は、取得した結果です。

 [      {        "_index" : "news",        "_id" : "czrouIsBC1dvdsZHkGkd",        "_score" : 8.842152,        "_source" : {          "link" : "https://www.huffpost.com/entry/china-shanghai-lockdown-coronavirus_n_62599aa1e4b0723f8018b9c2",          "headline" : "Strict Coronavirus Shutdowns In China Continue As Infections Rise",          "short_description" : "Access to Guangzhou, an industrial center of 19 million people near Hong Kong, was suspended this week.",          "category" : "WORLD NEWS",          "authors" : "Joe McDonald, AP",          "country" : "IN",          "timestamp" : 1695106458        }      },      {        "_index" : "news",        "_id" : "ODrouIsBC1dvdsZHlmoc",        "_score" : 8.064016,        "_source" : {          "link" : "https://www.huffpost.com/entry/who-covid-19-pandemic-report_n_6228912fe4b07e948aed68f9",          "headline" : "COVID-19 Cases, Deaths Continue To Drop Globally, WHO Says",          "short_description" : "The World Health Organization said new infections declined by 5 percent in the last week, continuing the downward trend in COVID-19 infections globally.",          "category" : "WORLD NEWS",          "authors" : "",          "country" : "US",          "timestamp" : 1695263499        }      },      ....]

ご覧の通り、COVID19感染についての文書が返されます。また、関連性の順に並べ替えられます(_scoreフィールドは、特定の文書の関連性を示します)。

ElasticSearchには多機能なクエリ言語がありますが、今のところ、シンプルな検索システムを構築するためには、ElasticSearchにすべてのデータを読み込んで、私たちが話し合ったシンプルなクエリを使用するだけで十分です。検索パフォーマンスと関連性を改善、設定、微調整するためのオプションは豊富にあります(この投稿の最後にさらに詳しく説明します)。

分散アーキテクチャ

ElasticSearchは分散データベースとして動作します。これは、単一のElasticSearchクラスタ内に複数のノードが存在することを意味します。単一のノードが利用できなくなったり、障害が発生した場合、通常、システムにダウンタイムは発生せず、他のノードが余分な作業を引き受けてユーザーリクエストを処理し続けます。そのため、複数のノードは高い可用性を実現します。

複数のノードはシステムをスケーリングするのにも役立ちます。データとユーザーリクエストをこれらのノードに分割することで、各ノードあたりの負荷を減らすことができます。たとえば、100万のニュース記事をElasticSearchに保存したい場合、そのデータを複数のノードに分割し、各ノードが特定の記事セットを保存するようにすることができます。これは非常に簡単でシームレスに行うことができます。

スケーラビリティ

ElasticSearchは水平方向にスケーリングし、データを複数のノードに分割できます。これにより、ElasticSearchクラスタにノードを追加することでクエリのパフォーマンスを常に改善することができます。

ただし、単にサーバーを追加するだけでElasticSearchクラスタのアーキテクチャを設計するには、より多くの考えが必要です。異なるタイプのノードがあり、これらのノードは「シャード」と呼ばれるプロセスを実行し、各シャード、ノードは複数のタイプと設定オプションを持つことができます。ElasticSearchクラスタのアーキテクチャや動作方法については、詳しく説明する内容がたくさんありますので、もし深く理解したい場合は、アーキテクチャについての完全な投稿をこちらに書いています。

要約すると、クラスタのスケーリングとパフォーマンス改善のためにマシンを追加することができます。データとクエリは複数のマシンに分割されます。これにより、パフォーマンスが向上し、スケーラビリティが向上します。

ドキュメントベースのデータモデリング

ElasticSearchはドキュメントベースのデータベースであり、データをJSONドキュメント形式で保存します。MongoDBと似たような形式です。したがって、例えば、ニュース記事はクラスタ内でJSONドキュメントとして保存されます。

リアルタイムデータ分析

リアルタイムデータ分析は、リアルタイムでユーザーのアクションを確認し、ユーザーパターンと行動を理解することです。ニュースウェブサイト上のユーザーごとのクリック、スクロールイベント、閲覧時間などをチャート化し、数日間観察することで、ユーザーについての洞察を得ることができます。この情報を活用することで、ピークタイム(午前9時から10時)中にリソースを過剰に供給したり、ユーザーの国に関連した記事をホームページに表示することができます。

Elasticsearchは、分散アーキテクチャと強力な検索機能により、リアルタイムデータ分析に適しています。ログ、メトリクス、ソーシャルメディアの更新など、リアルタイムデータを扱う場合、Elasticsearchは効率的にインデックス化して情報を保存します。ほぼリアルタイムでデータを検索可能とするため、データの取り込み後ほぼすぐにデータを検索できます。ElasticSearchは、Kibanaのような他のツールとも連携がうまくいきます。可視化のためのKibanaやメトリクスの収集のためのLogstashやBeatsなどがあります。

この記事の終わりに、これを可能にするアーキテクチャについても説明します。

コスト

ElasticSearchの運用と保守はコストがかかります。この世の中にはすべてが何かの代価を伴うようになっています。フルテキスト検索を実行するため、ElasticSearchは大量のデータをRAMに保持し、複雑なインデックスを構築します。これには多くのRAMが必要であり、それは高価です。

つまり、フルテキスト検索を実行する際には素晴らしいパフォーマンスを提供しますが、安くはありません。

ElasticSearchを使わない場合

ACID準拠

ElasticSearchは、ほとんどのNoSQLデータベースと同様、ACIDのサポートが非常に限定されているため、強い一貫性やトランザクションのサポートが必要な場合、ElasticSearchは適切なデータベースの選択ではないかもしれません。このため、ElasticSearchにドキュメントを挿入(ElasticSearchでは「ドキュメントをインデックス化する」と呼ばれる)すると、他のノードですぐにそのドキュメントにアクセスできない場合があり、他のノードに表示されるまで数ミリ秒かかることがあります。

仮に銀行システムを構築しているとしましょう。ユーザーが自分の口座にお金を預けると、そのデータがユーザーが行う他のトランザクションに即座に表示されるようにしたいと思うでしょう。一方、ニュースウェブサイトでElasticSearchを使用して検索機能を提供している場合、新しい記事が公開されても最初の数ミリ秒はすべてのユーザーには表示されないことが受け入れられるでしょう。

複雑なジョインが必要な場合

ElasticSearchはJOIN操作や異なるテーブル間の関係をサポートしていません。リレーショナルデータベースを使用していた場合、これは少し驚くかもしれませんが、ほとんどのNoSQLデータベースはこのような操作に限定的なサポートしか提供していません。

JOINの実行や外部キーを使用して関連性の高い構造化データを扱いたい場合、ElasticSearchはあなたのユースケースには最適な選択肢ではないかもしれません。

データセットが小さいか、シンプルなクエリが必要な場合

ElasticSearchは複雑で高コストです。大規模なElasticSearchクラスタを実行し管理するには、ソフトウェアエンジニアやDevOpsエンジニアの知識と技術だけでなく、「ElasticSearch Architects」と呼ばれるクラスタの管理と設計を得意とする専門家が必要な場合もあります。構成オプションやアーキテクチャの選択肢は豊富であり、それぞれがクエリとデータ取り込みに大きな影響を与えるため、システム内のコアフローでユーザーエクスペリエンスに間接的な影響を及ぼすことになります。

シンプルなクエリを実行したり、比較的少量のデータを扱いたい場合は、シンプルなデータベースがアプリケーションに適しているかもしれません。

システムデザインでElasticSearchを使用する方法

通常、1つのソフトウェアシステムには複数のデータベースが必要であり、それぞれが異なる機能を提供しています。ElasticSearchの使用に関する設計選択肢を理解するために、例を挙げてみましょう。

仮にNetflixのようなビデオストリーミングサービスを構築したいとします。この例ではElasticSearchがどのように適用されるかを見てみましょう。

検索システムとして

ElasticSearchの非常に一般的な使用例は、フルテキスト検索クエリをサポートするためのセカンダリデータベースとしての使用です。これはビデオストリーミングアプリケーションに非常に便利です。ビデオをElasticSearchに保存することはできませんし、請求関連のデータやユーザー関連のデータもElasticSearchに保存する必要はありません。

そのため、他のデータベースを使用できますが、映画のタイトル、説明、ジャンル、評価などをElasticSearchに保存することができます。

以下のようなアーキテクチャを採用することができます:

Image by author

フルテキスト検索が必要なデータをElasticSearchにインジェストできます。ユーザーが検索操作を実行すると、ElasticSearchクラスタに対してクエリを実行できます。これにより、ElasticSearchのフルテキスト検索機能を活用できます。ユーザー情報を更新する必要がある場合は、プライマリストレージ内で更新を実行できます。

リアルタイムデータ分析パイプラインとして

前述のように、ユーザーの行動やパターンを理解することは製品の進化方法を決定するために重要です。クリックストリームイベントやスクロールイベントなどのイベントを公開し、ユーザーが製品をどのように使用しているかをより良く理解することができます。

たとえば、ビデオストリーミングアプリケーションでは、ユーザーが映画やショーをクリックしたときにユーザーと映画のデータとともにイベントを公開できます。これにより、ユーザーが製品をどのように使用しているかを分析し、集計データを作成できます。たとえば、ユーザーが午後よりも夜に製品をより多く使用していることが分かるかもしれず、また、ユーザーが他の言語よりも地元の言語のショーまたは映画を好む傾向があるかもしれません。これを活用して、ユーザーエクスペリエンスを向上させるために製品の開発を行うことができます。

これは、ElasticSearchとKibana(ElasticSearchとの連携がよく機能するダッシュボードツール)を使用したリアルタイムデータ分析の基本システムの例です:

Image by author

推奨システムとして

ElasticSearchで特定の属性により優先度(ブースティングと呼ばれる)を与えるクエリを構築することができます。たとえば、単純なクエリではなく、

私たちはElasticSearchで基本的な推薦システムを構築することができます。ユーザーの国、年齢、好みなどの情報を保存し、そのユーザー向けの人気のある映画やシリーズを取得するクエリを生成することができます。

クエリ言語の理解や特定のフィールドを強化し、集計を行うことはそれ自体が大きなトピックですが、ここでは基礎をカバーしたブログ記事を書いています:

Elasticsearchのマスタリング:強力な検索と精度のための初心者向けガイド—パート1

パート1でElasticsearchのパワーを解き放つ:Elasticsearchにダイブして、基本的な検索クエリを理解し、文法を探求する…

towardsdatascience.com

結論

ElasticSearchクラスターのアーキテクチャーはどうやって構築する?

ElasticSearchクラスターのアーキテクチャを構築することは容易なことではありません。ノード、シャード、インデックスの知識が必要であり、それらを統合する方法を知る必要があります。選択肢は無限に存在し、このフィールドは絶えず進化しています(特にAIとAIパワードサーチの人気が高まっているため)。詳細については、非常に基本的な内容から検索クラスターを構築するために必要なすべてをカバーした完全なブログ記事を書きました:

betterprogramming.pub

検索クエリの理解と検索システムの改善

検索は非常に複雑です。検索システムをより強力にし、ユーザーのニーズを理解するために様々な方法があります。すでにElasticsearchとそれが何であるかについて学びました。ここから出発し、基本的な検索クエリを構築し、クエリとシステムの問題を理解し、例を用いて段階的に進化させてシステムを改善していきましょう。

Elasticsearchのマスタリング:強力な検索と精度のための初心者向けガイド—パート1

パート1でElasticsearchのパワーを解き放つ:Elasticsearchにダイブして、基本的な検索クエリを理解し、文法を探求する…

towardsdatascience.com

コンテキストに応じた検索

最近、検索システムについて素晴らしい類似性を読みました。これまでに議論した検索システムは、機械的で堅実な検索と考えることができます。ユーザーが単語を入力すると、その単語が含まれるすべてのドキュメントを見つけて返します。

また、検索システムは司書のように考えることもできます。ユーザーが「第二次世界大戦でのウィンストン・チャーチルの役割は何ですか?」という質問をすると、司書は単に「ウィンストン」、「チャーチル」、「第二次世界大戦」という単語が含まれる書籍を教えるだけではありません。代わりに、司書は顧客と文脈を評価し理解します。たとえば、それが学生なら、巨大な教科書を勧めるのではなく、より若い子供向けの本を見つけます。また、彼女が「ウィンストン・チャーチル」というタイトルの本を持っていない場合は、代わりに第二次世界大戦やイギリスの首相について話している本を見つけてそれを勧めるかもしれません。司書は試験用の本と夏休みの宿題用の本を別々に推奨するかもしれません(これを知らない人もいるかもしれませんが、一部の国では夏休みの宿題が非常に多いです)

これはあなたと私にとっては理解しやすいですが、システムはウィンストン・チャーチルがイギリスの首相であり、第二次世界大戦中のイギリスに関する本を推奨し、また、システムは議論の文脈を理解しユーザーを理解し適切な本を推奨する方法をどのように知るのでしょうか?

それが一見困難に見えるかもしれませんが、実際はそんなに難しいことではありません。それがセマンティックサーチと呼ばれるもので、大手テック企業のほとんどが自社の検索システムを構築する方法です。セマンティックサーチは、ユーザーのクエリとコンテンツの文脈を理解することを目指す一連の検索技術であり、検索語の間の関係や検索の意図を考慮に入れることで、より正確で文脈に即した検索結果を可能にします。

それは大きなトピックであり、私はまだそれについて読んだり理解したりすることがありますが、基本から始まるブログ記事が近々提供されますので、このトピックについてもっと知りたい場合は、VoAGIで私をフォローしてください。

他のデータベース

私はデータベース、キュー、パブサブシステムなどのシステム設計の概念について書いていますので、同様の記事についてはVoAGIで私をフォローしてください。LinkedInでもさまざまな内容のコンテンツを投稿しています(例:この投稿では、RabbitMQとKafkaの違いについて述べています)ので、短い形式のコンテンツについてはLinkedInでも私をフォローしてください。

その間、他のデータベースやシステム設計の概念に関する私のブログ記事をチェックすることもできます。

VoAGIでサニル・クラーナがキュレーションしたリスト

Linux、Cassandra、面接の質問などの探求を始めましょう

VoAGI.com

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more