blog

BIGO大量小ファイルストレージの実践

大量の小容量ファイルのストレージ問題を解決するためには、分散ストレージを使用する必要があり、現在の分散ストレージは主に2つのアーキテクチャを採用しています。代表的な分散ストレージはGFS、HDFS、M...

Sep 29, 2020 · 11 min. read
シェア

BIGOの製品とビジネスの特徴は、コンテンツ監査のスクリーンショット、ソーシャルネットワーキングの過程でユーザーが送信した小ファイル、ユーザーのアバターなど、大量の小ファイルのストレージ需要を決定します。現在、BIGOは毎日数十億の小ファイルを追加しており、約30TBのストレージスペースを占有しています。膨大な小ファイルストレージのために、ストレージのコストを削減しながら、どのように高いパフォーマンスを確保するかが、BIGOストレージチームが解決しなければならない問題になっています。

大量の小さなファイルのストレージ問題を解決するためには、分散ストレージを使用する必要があり、現在、分散ストレージは主に2つのアーキテクチャを使用しています:集中型メタデータ管理アーキテクチャと分散型アーキテクチャ。

メタデータを集中管理するアーキテクチャを持つ代表的な分散ストアは、GFS、HDFS、MooseFsなどです。それらの典型的なアーキテクチャを図1に示します:



このアーキテクチャは3つの主要部分から構成されています:

1) 主に、分散ストレージシステムにアクセスするためのインターフェースを提供するために使用されます;

2) 主に分散ストレージシステムの名前空間とファイルに関するメタデータ情報を保存するために使用されます。

3) 主にファイル固有のデータの保存を担当。

メタデータ管理に一元化されたアプローチを使用する主な利点は次のとおりです:

1) ストレージシステムのコマンドスペースやファイルのメタデータがメタデータサーバーに保存され、ディレクトリの一覧表示やファイルのメタデータ作成などのメタデータ操作のパフォーマンスが向上します;

2) すべてのファイルのロケーション情報はメタデータサーバに保存され、クラスタを拡張して新しいノードを追加する必要がある場合でも変更する必要がないため、クラスタの拡張時にデータを移行する必要がありません。

主な欠点は以下の通り:

1) ファイルデータにアクセスするクライアントは通常、メタデータノード上のファイルの位置情報を照会する必要があるため、必然的にメタデータノードがシステム全体のパフォーマンスボトルネックになります。

2) パフォーマンスを向上させるために、メタデータノードのデータは一般的にメモリに保持されます。

メタデータの集中アーキテクチャの問題を解決するために、分散アーキテクチャの分散ストレージが登場しました。その代表的なアーキテクチャを図2に示します:



このアーキテクチャは3つの主要部分から構成されています:

1) 主に分散ストレージシステムにアクセスするためのインターフェースを提供するために使用。

2) 主にファイル固有のデータとメタデータの保存を担当。

分散型アーキテクチャでは、ファイルの名前空間とメタデータを保存する独立したメタデータノードはありません。メタデータは依然としてストレージノードに保存され、ファイルのアドレス指定は一般にDHT(一貫したHASH)方式で計算されます。このアーキテクチャは一般に、複数のストレージノードを論理的にグループ化し、データの信頼性を確保するためにグループ内レプリケーションを行うため、クラスタ全体のストレージノードとグループ化情報を保存する中央サーバがオプションで用意されます。たとえば、CephはCeph monitorを使用してクラスタ全体のメンバーシップとステータス情報を保持しますが、GlusterFsはすべてのストレージノードにこの情報を保存することを選択します。

分散型アプローチを採用する主な利点は以下の通り:

1) 独立したメタデータノードがなく、クライアントはハッシュによって直接ファイルをアドレスし、ストレージノードに直接アクセスできます。

2) 独立したメタデータ・ノードがないため、理論上、ファイル数はセンターエンド・ノードの容量に制限されません。

3) 読み取りと書き込みのリクエストは、メタデータ・ノードをアドレスする必要はなく、ハッシュ計算法を使用します。

GlusterFsのストレージノードは、データの保存にLinuxローカルファイルシステムを使用しますが、これは小さなファイルの読み書きに最適化されておらず、Cephは大量の小さなファイルの読み書きに最適化されたBlueStoreストレージエンジンをJewelバージョンから導入しているため、大量の小さなファイルの保存にはCephを使用することにしました。

Cephは他の分散ストレージよりも大量の小さなファイルを保存するのに適していますが、まだ解決すべき問題がいくつかあります:

1) 小さなファイルが大量にある場合、バケットインデックスのデータ量が急激に増加し、バケットインデックスを頻繁に再シャーディングする必要があります。リストバケットを必要としないほとんどのシナリオでは、この問題はインデックスレスバケットを使うことで解決できます。リストバケットを必要としないほとんどのシナリオでは、この問題はインデックスレスバケットを使うことで解決できます。 バケットインデックスを必要とするシナリオについては、バケットインデックス最適化ソリューションの逐次配布が追加されましたが、これはこの記事の範囲外であり、後の記事で紹介します。

2)Cephは、データ拡張の過程で、ファイルの場所を再ハッシュする必要があり、データ移行操作の多数をもたらす、データ移行プロセスは、大きなパフォーマンスの損失をもたらすでしょう。同時に、大量の小さなファイルのデータ移行に長い時間がかかり、ディスク障害やプロセス内のマシンの障害が発生した場合、データの回復時間が不確かになり、これは大きなデータのセキュリティリスクをもたらすでしょう。

3) Cephのデフォルトの最小割り当て単位は64KBで、現在の小ファイルの平均サイズは15KBです。 ストレージ効率を向上させるため、最小割り当て単位を4KBに調整できます(読み取りと書き込みのパフォーマンスは低下します)。修正コードなどの小さなファイルを格納するために修正コードを使用する場合、ファイルの最小割り当て単位は6 * 4キロバイト= 24キロバイトになります。 ストレージ効率を向上させるために、小さなファイルを格納するために修正コードを使用しますが、ストレージリソースのより多くの無駄。

Cephで大量の小さなファイルを保存する問題を解決するには、以下の目的を満たすシステムを設計する必要があります:

1)分散ストレージシステムは、エンドユーザーの読み書きの要求を満たす必要があり、ユーザーのデータアクセスのニーズを満たす低レイテンシは、分散ストレージシステムの重要な目標です。

2) ストレージシステムの負荷を増大させ、それによってエンドユーザーに対するストレージシステムのサービス品質に影響を与える、大量のデータ移行操作を回避することも、システム設計における重要な目標です。

3)マシン障害やディスク障害は、データの移行につながる、小さなファイルの数が多いため、障害復旧に時間がかかる、障害復旧時間が長いほど、この期間中に他のマシンやディスク障害の確率が高く、データ損失のリスクが大きいので、障害復旧速度を高速化することも、システム設計の目的の一つです。

4) 小さなファイルが大量にあると、ストレージリソースを大量に消費すると同時に、大量のファイルは時間が経つとコールドデータになってしまうため、いかにストレージ効率を高めてストレージコストを削減するかも、システム設計の目的の一つです。

現在、業界では、主にいくつかの最適化手法に次のソリューションを持っている巨大な小さなファイルのストレージを解決するために:

1) 大容量小ファイルの読み書きのボトルネックは、通常機械式ハードディスクにあります。ハードウェアの最適化は、主に機械式ハードディスクの代わりにSSDハードディスクドライブのランダムな読み取りと書き込みをサポートするために、大幅に小さなファイルの大量の読み取りと書き込みのパフォーマンスを向上させることができます。しかし、コスト要因を考慮すると、大量のデータの場合、SSDハードディスクドライブは、一般的にキャッシュとしてのみシステム内にあります。

3)1つの大きなファイルに多数の小さなファイルを組み合わせることで、ファイル数が大幅に削減することができ、また、メタデータの量を削減し、メタデータのクエリが高速になります。大規模なファイルについては、機械的なハードドライブが大幅にハードドライブの負荷を軽減することができ、シーケンシャルな読み取りと書き込みを行うことができます。

本システムは、上記のアプローチを組み合わせて、Cephの大容量小ファイルストレージの問題を解決するために、2階層ストレージプールに基づく小ファイルマージ最適化スキームを設計し、そのシステム設計を以下の図3に示します:



異なるバケットまたはサイズのファイルを異なるストレージ・プールに書き込むように、異なるストレージ・ポリシーを設定できます。大容量の小さなファイルは、高性能なストレージプールに書き込むことが推奨され、小さなファイルの読み書きに高いパフォーマンスが保証されます。

次に、構成ポリシーを通じてマージ機能をオンにし、高性能ストレージプール内の小さなファイルを大容量ストレージプールに格納する大きなファイルにマージします。大容量ストレージ・プールの空き容量が不足した場合、既存のストレージ・プールを拡張する代わりに、新しいストレージ・ノードを追加して新しい大容量ストレージ・プールを作成します。

大容量ストレージ・プールについては、マージされたファイルの保存効率を向上させるためにECで保存することができます。大容量ファイル用のストレージなので、最小アロケーション単位を128KBなど大きく調整することで、BlueStoreのメタデータ量を減らし、パフォーマンスを向上させることができます。

上記のシステム設計において、具体的な実装を行う上で重要な事項は以下の通りです。

下の図4に示すように、大きなファイルをボリュームとして考え、それぞれの小さなファイルがそのスペースの一部を占めていると考えてください:



各スモールファイルは、ボリューム内で3つのパートに分割されます:

1) ファイルのメタデータ情報(ファイル名、ファイルサイズ、ファイルのチェックサム情報、ボリューム内のオフセットなど)を保存します。

2) ミニファイルの実際のデータ内容。

3) キャリブレーション用に固定マジックを保存します。

高性能ストレージプールから大容量ストレージへのデータ移行の具体的な方法を図5に示します:



ストレージゲートウェイの操作ログは、ストレージゲートウェイの現在の操作を記録し、操作ログはバケットと時間に従って保存され、移行ツールは異なるバケットポリシーに従って、現在のバケットの操作ログファイルを読み取ることができます。具体的な移行プロセスは4つのステップに分けられます:

1) Bucket のマイグレーションポリシーに従って、操作ログファイルを読み込み、各操作を解析してファイル名と操作情報を取得します。並列移行に対応するため、ハッシュ化することでファイル名を複数のキューに入れることができます。

2) 処理対象のファイル名をキューから取得し、高性能ストレージプールからファイルのデータを読み込みます。

3) 大容量ストレージプールからボリュームを要求し、現在の小さなファイルをボリュームに追加し、ヘッダー、データ、フッターの順にファイルを移行します。

4) High Performance Storage Poolのファイルデータを削除し、データだけを空にし、ファイルのメタデータ情報を保持し、メタデータにボリューム内の小ファイルの現在位置の情報を追加します。

ファイルのデータが大容量記憶域プールに移行されると、ストレージ・ゲートウェイによるデータの読み出しプロセスが以下の図6に示すように変更されます:



この時、ファイルのデータ内容は大容量ストレージプールに保存され、ファイルのメタデータとファイル内容の位置情報は高性能ストレージプールに保存されるため、ストレージゲートウェイはデータ内容を読み出す際に、まず高性能ストレージプールに移動してファイルの位置情報を読み出す必要があります。

1) 高性能ストレージ・プールでは、大量のホット・データがすでに読み取り操作を完了しており、大容量ストレージへの移行は通常、読み取り要求が大幅に少ないコールド・データです。

2) ファイル・メタデータの読み取りは高性能ストレージ・プールで行われ、大容量ストレージ・プールで直接行うよりもはるかに性能が向上します。

3) プログラムの大容量記憶域プールであるBlueStoreの割り当てユニット数が多く、BlueStore要素の数が多い。

ファイルの削除には、ファイルのデータコンテンツとメタデータの両方を削除する必要があります。 高性能ストレージプールに保存されているファイルのメタデータは直接削除できますが、ファイルのデータコンテンツは大容量ストレージプールのVolumeの一部でしかなく、直接削除してストレージ容量を回復することはできないため、ファイルの削除と容量の回復は別々に行われます。

エンドユーザーからの削除要求に応じると、Volumeから対応するファイルHeaderが検出され、ファイルが削除されてアクセスできないことを示す削除フラグが書き込まれ、現在のVolumeの有効サイズ情報が変更されます。以下の図7に示すように



赤色のヘッダーは、現在のファイルが削除マークが付いていることを示します。スペース回復ストラテジーによると、ボリュームのストレージスペースに対する有効スペースが50%未満であり、削除されたスペースが50%以上であることを示す場合、次の方法でボリュームにコンパクション操作を実行する必要があります:

1) ボリューム全体をスキャンして各ファイルを検索します。

3) ボリューム全体のスキャンが完了し、有効なファイルが移行されたら、現在のボリュームの大容量ファイルを削除します。

ファイル削除操作に加えて、ファイル変更操作でも、同様のアプローチを使用して、古いデータ・コンテンツによって占有されていた領域を取り戻す必要があります。変更操作のログを処理するとき、古いデータ内容のヘッダーは削除のためにマークされ、データ領域のこの部分は、後続のコンパクション操作の間に取り戻されます。

この設計ソリューションの最適化を検証するため、同じネットワーク環境上に2つの分散ストレージシステムを構築しました:

1) 3台のサーバーに、それぞれ最小割り当て単位4KBの機械式ハードディスク・ドライブ・ストレージ・ノードを5台配置。

2) 15台のストレージ・ノードに大容量の3レプリカ・ストレージ・プールを作成します。

1) 3台のサーバーに、それぞれ5台のメカニカルハードドライブストレージノードと、最小割り当て単位64KBの1台のSATA SSDストレージノードを配置。

2) 15台のストレージ・ノード上に大容量3レプリカ・ストレージ・プールを作成し、3台のSATA SSDストレージ・ノード上に高性能3レプリカ・ストレージ・プールを作成します。

3) 高性能ストレージプール内の小さなファイルは、書き込み後2時間経過すると自動的に大容量ストレージプールに移行するように設定します。大容量ストレージプール内のボリュームサイズはデフォルトで4MBです。

この設計ソリューションの最適化は、以下の方法で評価できます:

まだ大容量ストレージプールに移行していない大量の小容量ファイルデータのパフォーマンス比較。

以下の図 8 に示すように、1,000 万個の 20KB ファイルをそれぞれ複数の異なる同時実行シナリオで書き込んだ場合の性能テスト結果です:



高性能ストレージ・プールで使用されているストレージ・ハードウェアはSATA SSDであるため、高性能ストレージ・プールには3台のストレージ・ノードしかなく、大容量ストレージ・プールには15台のストレージ・ノードがあるにもかかわらず、最適化システムの書き込みQPSは最適化前のQPSの3倍に達しています。

以下の図9に示すように、いくつかの異なる同時実行シナリオの下で、1,000万個の20KBファイルを読み込んだパフォーマンステストの結果です:



最適化されたシステムの読み出しQPSは、最適化前と比較して20%から30%向上し、書き込みの最適化効果は、主にストレージ・ノードのキャッシュの役割により達成されていないことがわかります。

データが高性能ストレージ・プールに書き込まれた後、ポリシーに従ってデータは大容量ストレージ・プールに移行され、最適化前と最適化後の読み取り性能の比較結果は以下の図10に示されています:



小さなファイルの結合のため、ファイルの読み取りは、まず高性能ストレージプールのメタデータを読み取り、次に大容量ストレージプールのファイルのデータを読み取る必要があり、実際にはさらに1つのネットワークRTTを通過するため、一定の読み取り性能の低下を招き、結果から、読み取りQPSは約12%低下しました。この後のシステムでは、より性能の高いNVME SSDを使用して、テスト用の高性能ストレージプールを構築する予定です。

最適化されたシステムにおいて、小ファイルのマージ前とマージ後のストレージ・リソースの使用状況を図11に示します:



マージ前の最小ストレージ単位は64KBなので、20KBのファイルも64KBのストレージを占め、3部コピーされるので、必要なストレージ容量は、メタデータを除けば、64KB * 3 * 10000000 = 1831GBとなります。

マージ後のボリュームサイズは4MBで、1つの20KBのファイルは、20KBのデータ保存領域と少量のメタデータ保存領域を占有するだけでよいため、メタデータの保存領域をカウントしない場合の必要容量は次のとおりです:20KB * 3 * 10000000 = 572GB。

そのため、統合後の保管効率は、統合後の保管効率の3倍以上になります。

同じ1,000万ファイルを1つのストレージノードがオフラインの状態で、この時点ではデータを復元するためにデータ移行を行うことになりますが、デフォルトの構成のみを使用して、最適化前と最適化後に消費されたデータ復元時間を以下の図12に示します:



最適化された大容量ストレージプールには大容量ファイルのみが保存されるため、復旧速度が向上し、最適化後の障害復旧速度は最適化前の16倍に達しました。

本論文では、Cephを使用して大量の小ファイルを保存する際の課題と問題点を分析し、ハードウェア最適化、メタデータ管理最適化、小ファイルマージ最適化の各レベルから、2階層ストレージプールに基づく小ファイルマージ最適化ケース一式を検討、設計、実装し、比較を通じて、新しい方式が読み取り/書き込み性能、ストレージ効率、障害回復速度でより大きな改善をもたらすことを発見しました。





Read next

Linuxシステムノート コンテナ化

1台の物理マシンから多数の仮想マシンを仮想化することで、リソースの作成に柔軟性が生まれます。しかし、仮想化のアプローチはまだ非常に複雑であることもわかるでしょう。子会社を設立しに行くようなもので、会社は小さいと言われていますが、結局のところ、どこかの独立した会社で、雀の涙ほどで、すべての臓器、したがって、前の章で見たように、CPU、メモリ、ネットワーク、ハードディスクをすべて仮想化する必要があります、、、。

Sep 29, 2020 · 10 min read