150mの一意のラベルを持つテキストファイルの高速読み取りのためのAPIアーキテクチャ設計
150mの一意のレコードを持つテキストファイルを想定します。
各レコードには、(1)文字列と(2)整数の2つの列があります。
文字列は一意のラベルであり、整数はラベルの値です。
唯一のクエリは、指定されたラベルの整数値を返します。
このテキストファイルをAPIとして公開するための複数のアーキテクチャを検討しています。
このテキストファイルは72時間ごとに再生成されます。データの約90%は再生全体で同じままですが、この再生はサードパーティによって制御されます。72時間ごとに新しいテキストファイルを取得するだけです。
読み取りあたり100ミリ秒から500ミリ秒のクエリパフォーマンスを目指しています。
アーキテクチャ1
- テキストファイルをディスクに保存します。テキストファイルをクエリします。クエリをメモリにキャッシュします。
- 長所:簡単な実装。データの更新が簡単。
- 短所:エレガントではありません。キャッシュされていない読み取りクエリは低速です。
アーキテクチャ2
- テキストファイルを従来の/ NoSQLデータベースに解析し、各行をデータベースレコード/ドキュメントとして扱います。データベースに対してクエリを実行します。
- 長所:標準アーキテクチャのようです。
- 短所:1億5000万のデータベースレコードの更新は遅く、無駄に思えます。特に、レコードの約90%が同じままであるためです。
アーキテクチャ3
- Redisまたはインメモリデータベースを使用して、5GBのテキストファイルを保存します。インメモリデータベースに対してクエリを実行します。
- 長所:高速クエリ。データの更新が簡単。
- 短所:高価です。
アーキテクチャ4
- ElasticSearchを使用してレコードをクエリします。
- 長所:ElasticSearchは検索用に設計されています。
- 短所:ESは、このような単純なクエリではやり過ぎかもしれません。
質問:
他のアーキテクチャを検討する必要がありますか、それとも見落としている長所/短所がありますか?
このエンジニアリング上の課題は一般的なようです。変化する1億5000万レコードのデータストアに対して高速読み取りを生成しようとするときに、コストとパフォーマンスのバランスを取るための最も「標準的な」アーキテクチャは何ですか。
回答
一般的に言えば、これはETLフローの典型的なケースのように見えます。新しいファイルを取得し、データを抽出し、それをフォーマットに変換して、DBにロードします。いくつかの注意:
覚えておくべき重要なことは、ロードとクエリは、まったく関係のない異なる操作に対するものであるということです。1つの質問は、「レコードの90%が重複している場合に、毎日150mのレコードファイルをデータストアに効率的にロードする方法」であり、もう1つの質問は、「150mレコードのキー/値ストアを効率的にクエリする方法」です。これらの2つの質問は独立しているため、別々に答えてください。
最初の質問では、90%同一のレコードをロードするのは無駄だと心配しています。かかる時間を測定しましたか?テキストファイルから150mのレコードを読み取るには数秒かかるはずであり、優れたキー/値ストアは冗長なUPDATE操作を最適化できるはずです。または、新しいファイルを前のファイルと比較して、ETLフローの一部として実際の変更リストを作成してから、ロードに進みます。ソリューションを評価できるように、このソリューションのメトリック(読み取り、差分、ロード、ロード中のクエリ操作の中断など)を定義します。
質問2については、既成のオプションが存在する場合はカスタムソリューションの実装を避けてください。キー付き整数を格納しているだけなので、ElasticSearchはやり過ぎかもしれませんが、ディスクバックアップメモリキャッシング、MRUキャッシング、または使用状況に応じたさまざまなキャッシング戦略など、読み取りに優れたパフォーマンスを提供するキー/値ストアがたくさんあります。おそらく、前述のno-opUPDATE操作などです。繰り返しますが、質問1のように、成功の指標を定義します。「5GBをRAMにロードするのはコストがかかります。それですか?サーバーにはどのくらいのRAMがありますか?一般的なクエリをキャッシュすることを検討します。必要ですか?キャッシュされていない読み取りの速度はどれくらいですか?測定してください!関連するレコードをプリキャッシュするようなカスタムキャッシュ戦略が必要ですか? ?使用パターンを調べます。
私はあなたに最善のアプローチが何であるかを言うことができません。あなただけが知っている変数が多すぎます-予算と使用パターン、システムの将来の計画と拡張性の可能性、サードパーティのデータソースとの関係(たとえば、差分だけを生成することを確信できるか、タイムスタンプ/バージョンタグを追加することができますか?記録など)。私にできることは、コアパターンを提案することだけです。つまり、取り込みフローをクエリフローから分離し、実証済みのツールを使用し、とりわけ、測定、測定、測定を行います。
DJBernsteinのcdbが採用したアプローチを検討してください。
cdbは、定数データベースを作成および読み取るための高速で信頼性の高いシンプルなパッケージです。そのデータベース構造はいくつかの機能を提供します:
高速ルックアップ:大規模なデータベースでルックアップを成功させるには、通常2回のディスクアクセスしか必要ありません。失敗したルックアップは1つだけかかります。
低オーバーヘッド:データベースは、2048バイト、レコードあたり24バイト、およびキーとデータ用のスペースを使用します。
ランダムな制限なし:cdbは最大4ギガバイトのデータベースを処理できます。他の制限はありません。レコードはメモリに収まる必要さえありません。データベースは、マシンに依存しない形式で保存されます。
アトミックデータベースの高速置換:cdbmakeは、他のハッシュパッケージよりも2桁速くデータベース全体を書き換えることができます。
高速データベースダンプ:cdbdumpは、データベースの内容をcdbmake互換形式で出力します。
cdbは、電子メールなどのミッションクリティカルなアプリケーションで使用するように設計されています。データベースの交換は、システムのクラッシュに対して安全です。リーダーは、書き換え中に一時停止する必要はありません。
おそらく次のような、4GiB制限はありませんより多くの近代的な実装を、お勧めします。この1。