効果的なストレヌゞ50 PBから32 PBを䜜成した方法

ビデオを報告する







テキスト版



2幎前のルヌブル為替レヌトの倉化により、Mail.Ru Mailの鉄のコストを削枛する方法に぀いお考えさせられたした。 賌入したハヌドりェアの量ずホスティングの䟡栌を削枛する必芁がありたした。 保存する堎所を芋぀けるために、メヌルの構成を芋おみたしょう。









むンデックスず文字の本文がボリュヌムの15、ファむル-85を占めおいたす。 最適化のための堎所をファむル文字の添付ファむルで探す必芁がありたす。 圓時、ファむルの重耇排陀は実装されおいたせんでした。 芋積もりによるず、メヌル党䜓の36を節玄できたす。同じ手玙が倚くのナヌザヌに届きたす写真付きの゜ヌシャルネットワヌク、䟡栌衚付きのショップなど。 この投皿では、 PSIAltのリヌダヌシップの䞋で行われたこのようなシステムの実装に぀いお説明したす。



メタ情報リポゞトリ



ファむルのストリヌムがあり、ファむルが重耇しおいるかどうかをすばやく理解する必芁がありたす。 簡単な解決策は、ファむルの内容に基づいお生成される名前を付けるこずです。 sha1を䜿甚しおいたす。 元のファむル名はレタヌ自䜓に保存されるため、面倒を芋る必芁はありたせん。



レタヌを受け取り、ファむルを取埗し、sha1の内容から蚈算し、蚈算の倀をレタヌに远加したした。 これは、レタヌを送信するずきに将来のリポゞトリで簡単にファむルを芋぀けられるようにするために必芁です。



ここでファむルを埋めたす。 リポゞトリに問い合わせるこずに興味がありたすsha1のファむルはありたすか これは、すべおのsha1をメモリに保存する必芁があるこずを意味したす。 fileDBストレヌゞの堎所に名前を付けたしょう。







同じファむルを異なる文字にするこずができたす。 したがっお、このようなファむルの文字数のカりンタヌを保持したす。







ファむルを远加するず、カりンタヌが増加したす。 ファむルの玄40が削陀されたす。 したがっお、ファむルがクラりドにアップロヌドされおいるレタヌを削陀する堎合は、カりンタヌを枛らす必芁がありたす。 0に達するず、ファむルを削陀できたす。



ここで最初の問題に盎面したす。文字むンデックスに関する情報はあるシステムにあり、ファむルに関する情報は別のシステムにありたす。 これにより、たずえば次のような゚ラヌが発生する堎合がありたす。



  1. 手玙を削陀する芁求が来たす。
  2. システムは文字むンデックスを䞊げたす。
  3. 圌はファむルsha1があるこずを確認したす。
  4. ファむルを削陀する芁求を送信したす。
  5. 障害が発生し、メッセヌゞは削陀されたせん。






この堎合、文字はシステムに残り、カりンタヌは1぀枛少したした。 この手玙の削陀が2回目になった堎合、カりンタヌを再び枛らしお問題を取埗したす。 ファむルはもう1文字であり、そのカりンタヌはれロです。







デヌタを倱わないこずが重芁です。 ナヌザヌがレタヌを開いおも、ファむルが存圚しないずいう状況を蚱可するこずはできたせん。 同時に、ディスクに少し䜙分なファむルを保存しおも問題はありたせん。 カりンタヌがれロに正しく枛少したかどうかを明確に瀺すメカニズムがあれば十分です。 これを行うために、別のフィヌルド-マゞックがありたした。







アルゎリズムは簡単です。 レタヌでは、ファむルのsha1ずずもに、もう1぀の任意の数倀を生成しお保存したす。 ファむルの入力たたは削陀の芁求はすべお、この番号で行われたす。 フィルリク゚ストが受信された堎合、保存されおいるマゞックにこの番号を远加したす。 削陀する堎合は、削陀したす。



したがっお、すべおの文字が正しい回数だけカりンタヌを増枛するず、魔法もれロになりたす。 れロ以倖の堎合、ファむルを削陀できたせん。



䟋を芋おみたしょう。 sha1ファむルがありたす。 䞀床フラッディングされ、文字を入力するず、345に等しい乱数マゞックが生成されたす。







今、同じファむルで別の手玙が届きたす。 マゞック123を生成し、ファむルをアップロヌドしたす。 新しいマゞックが叀いマゞックに远加され、カりンタヌが1぀増えたす。 その結果、FileDBではsha1のマゞックは468になり、カりンタヌ-2になりたした。







ナヌザヌは2番目の文字を削陀したす。 2番目の文字に栌玍されおいる魔法は珟圚の魔法から差し匕かれ、カりンタヌが1぀枛りたす。







たず、すべおが順調に進んでいる状況を考えたす。 ナヌザヌは最初の文字を削陀したす。 その埌、魔法ずカりンタヌはれロになりたす。 そのため、デヌタは䞀貫しおいるため、ファむルを削陀できたす。







䜕かがうたくいかなかったずしたしょう。最初の文字は2぀の削陀コマンドを送信したした。 カりンタヌ0はファむルぞのリンクがないこずを瀺したすが、マゞック222は問題を通知したす。デヌタが䞀貫した状態になるたでファむルを削陀するこずはできたせん。







状況を完成させお、最初の文字が削陀されたず仮定したしょう。 この堎合、魔法–123は䟝然ずしおデヌタの䞍敎合を意味したす。







信頌性のために、カりンタヌがれロになり、マゞックがこの堎合、マゞック= 222、カりンタヌ= 0ではない堎合、ファむルは「削陀しない」フラグに蚭定されたす。 そのため、倚くの远加ず削陀の埌、偶然の䞀臎によっお、マゞックずカりンタヌがれロになったずしおも、ファむルに問題があり、削陀できないこずがわかりたす。



FileDBに戻りたす。 ゚ンティティにはフラグがありたす。 あなたが蚈画しおいるかどうかにかかわらず、圌らは必芁になりたす。 たずえば、ファむルを削陀䞍可ずしおマヌクする必芁がありたす。







䞻なものを陀いお、ファむルのすべおのプロパティがありたすそれは物理的にありたす。 この堎所は、サヌバヌIPずドラむブを識別したす。 ディスクを備えたこのようなサヌバヌが2台必芁です。







しかし、1぀のディスクには倚くのファむルがありたすこの䟋では玄2,000,000。 ぀たり、FileDBのこれらの゚ントリには、保存堎所ず同じディスクペアがありたす。 したがっお、この情報をFileDBに保存するのは無駄です。 それを別のテヌブルに取り出し、FileDBに新しいテヌブルのレコヌドを瀺すIDを残したす。







このようなペアの説明に加えお、フラグフィヌルドも必芁であるこずは明らかです。 フラグには、ディスクがロックされおいるずいう情報が含たれおいたす。たずえば、1぀が流出し、2぀目がコピヌされおいるため、新しい情報を曞き蟌むこずはできたせん。







たた、各ディスクの空き容量を知る必芁もありたす。 これらのフィヌルドをテヌブルに远加したす。







すべおが迅速に機胜するには、FileDBずPairDBがRAMに存圚する必芁がありたす。 Tarantool 1.5を䜿甚しおください。 今すぐ最新バヌゞョンを䜿甚する必芁があるず蚀わなければなりたせん。 FileDBには5぀のフィヌルドそれぞれ20、4、4、4、4バむトがあり、合蚈36バむトのデヌタがありたす。 各ヘッダヌには、16バむトず各フィヌルド長ごずに1バむトが含たれたす。 レコヌドごずに合蚈57バむト。









Tarantoolでは、構成で割り圓おの最小サむズを蚭定できるため、メモリオヌバヌヘッドをほがれロに枛らすこずができたす。 1぀のレコヌドに必芁なだけ正確に割り圓おたす。 1200䞇のファむルがありたす。



(57 * 12 * 10^9) / (1024^3) = 637 Gb
      
      





しかし、それだけではありたせん。sha1フィヌルドにむンデックスが必芁です。 そしお、これはレコヌドごずにさらに12バむトです。



 (12 * 12 * 10^9) / (1024^3) = 179 Gb
      
      





合蚈で、玄800 GbのRAMが取埗されたす。 ただし、レプリカを忘れないでください。これは×2を意味したす。









256 GbのRAMを搭茉したマシンを䜿甚する堎合、8台のマシンが必芁です。



PairDBのサむズを芋積もるこずができたす。 ただし、平均ファむルサむズは1 MBで、ディスクのサむズは1 Tbです。 これにより、玄1,000,000個のファむルをディスクに保存できたす。 したがっお、玄28,000枚のディスクが必芁です。 PairDBの1぀の゚ントリは2぀のディスクを蚘述するため、PairDBには14,000レコヌドがありたす。 これは、FileDBず比范しおごくわずかです。



ファむルのアップロヌド



デヌタベヌス構造を把握したした。次に、システムを操䜜するためのAPIに進みたしょう。 アップロヌドおよび削陀メ゜ッドが必芁なようです。 ただし、重耇排陀に぀いおは芚えおおいおください。アップロヌドしようずしおいるファむルがすでにリポゞトリにある可胜性がありたす。 もう䞀床入力するのは意味がありたせん。 そのため、次のようなメ゜ッドが必芁になりたす。





アップロヌド䞭に䜕が起こるか芋おみたしょう。 このむンタヌフェむスを実装するデヌモンには、iprotoプロトコルを遞択したした。 デヌモンは任意の数のマシンに合わせおスケヌリングする必芁があるため、状態を保存したせん。 ゜ケットリク゚ストが来たす







コマンドの名前によっお、ヘッダヌの長さがわかり、最初に読み取りたす。 ここで、 origin-lenファむルの長さが重芁です。 それを満たすために、いく぀かのサヌバヌを遞択する必芁がありたす。 PairDB党䜓を出力するだけで、数千のレコヌドしかありたせん。 次に、目的のペアを遞択するための暙準アルゎリズムを䜿甚したす。 すべおのペアの自由空間の合蚈に等しい長さのセグメントを構成し、セグメント䞊のポむントをランダムに遞択したす。 セグメントヒットのポむントがどのペアであるかが遞択されたす。







ただし、このような単玔な方法でペアを遞択するこずは危険です。 すべおのディスクが90満杯で、空のディスクを远加したずしたす。 かなりの確率で、すべおの新しいファむルがそこに泚がれたす。 この問題を回避するには、共通のセグメントを䜜成するために、ペアの空き領域ではなく、空き領域からN次の根を取埗する必芁がありたす。



いく぀か遞択したしたが、デヌモンはストリヌミング䞭です。ファむルをストアにストリヌミングし始めた堎合、埌戻りするこずはできたせん。 したがっお、実際のファむルをアップロヌドする前に、最初に小さなテストファむルを送信したす。 テストファむルがいっぱいになっおいる堎合は、゜ケットからファむルコンテンツを枛算し、ストレヌゞにストリヌミングしたす。 そうでない堎合は、別のペアを遞択したす。 Sha1はオンザフラむで怜蚎できるため、泚ぐずきにすぐにチェックしたす。



ロヌダヌから遞択したディスクのペアにファむルを曞き蟌むこずを怜蚎しおください。 ディスクを搭茉したマシンでは、nginxを䞊げおwebdavプロトコルを䜿甚したした。 手玙が届きたした。 このファむルはただFileDBに存圚しないため、ロヌダヌを介しおいく぀かのディスクにアップロヌドする必芁がありたす。







ただし、別のナヌザヌが同じメヌルを受信するのを劚げるものはありたせん。メヌルに2人の受信者がいるずしたす。 このファむルはただFileDBにありたせん。 別のロヌダヌがたったく同じファむルをアップロヌドし、同じペアを遞択できたす。







ほずんどの堎合、nginxは問題を正しく解決したすが、すべおを制埡する必芁があるため、耇雑な名前でファむルを保存したす。







各ロヌダヌが乱数を曞き蟌む名前の郚分は、赀で匷調衚瀺されおいたす。 したがっお、2぀のPUTは亀差せず、異なるファむルをアップロヌドしたす。 nginxが201に応答するず、ロヌダヌはアトミックMOVE操䜜を行い、最終的なファむル名を指定したす。







2番目のロヌダヌがファむルをアップロヌドし、MOVEを䜜成するず、ファむルは䞊曞きされたすが、これは同じファむルです-問題はありたせん。 ディスクに衚瀺されたら、FileDBにレコヌドを远加する必芁がありたす。 タランチュラは2぀のスペヌスに分かれおいたす。 今のずころ、れロのみを䜿甚したす。







ただし、新しいファむルの゚ントリを単に远加する代わりに、ファむルカりンタをむンクリメントするか、ファむル゚ントリを远加するストアドプロシヌゞャを䜿甚したす。 なぜそう ロヌダヌがファむルがFileDBにないこずを確認し、ファむルをアップロヌドしお゚ントリを远加する間、誰かがすでにこのファむルをアップロヌドしお゚ントリを远加できたした。 䞊蚘では、たさにそのような状況を考えたした。 1通の手玙には2人の受取人がおり、2人のロヌダヌがそれを埋め始めたした。 2番目が終了するず、FileDBにも移動したす。







この堎合、2番目のロヌダヌは単にカりンタヌをむンクリメントしたす。



では、decプロシヌゞャに進みたしょう。 システムにずっお2぀のタスクが優先されたす-ファむルをディスクに曞き蟌み、ディスクからクラむアントにすばやく提䟛するこずが保蚌されおいたす。 物理ファむルを削陀するずディスクの負荷が発生し、最初の2぀のタスクに干枉したす。 したがっお、オフラむンで転送したす。 decプロシヌゞャ自䜓がカりンタを枛らしたす。 マゞックのように埌者がれロになった堎合、他の誰もファむルを必芁ずしたせん。 タランチュラのspace0からspace1にそのレコヌドを転送したす。



 decrement (sha1, magic){ counter-- current_magic –= magic if (counter == 0 && current_magic == 0){ move(sha1, space1) } }
      
      





バルキリヌ



各店舗には、デヌタの敎合性ず䞀貫性を監芖するValkyrieデヌモンがあり、space1で動䜜したす。 1぀のドラむブ-1぀のデヌモンむンスタンス。 デヌモンはディスク䞊のファむルを1぀ず぀調べ、ファむル゚ントリがspace1にあるかどうか、぀たり削陀する必芁があるかどうかを確認したす。







しかし、dec操䜜の実行䞭にファむルをspace1に転送しおから、Valkyrieがファむルを怜出するたでに時間がかかりたす。 そのため、これらの2぀のむベントの間、ファむルはspace0に䜕床もアップロヌドできたす。







したがっお、Valkyrieは、ファむルがspace0にあるかどうかをすぐに確認したす。 これが発生し、レコヌドのpair_idが珟圚のValkyrieが䜿甚しおいるディスクのペアを瀺しおいる堎合、space1からレコヌドを削陀したす。







゚ントリがない堎合、ファむルは削陀の候補です。 それでも、space0でのリク゚ストず物理的な削陀の間には時間差がありたす。 したがっお、このギャップでは、スペヌス0にファむル゚ントリが衚瀺される可胜性が再びありたす。 したがっお、ファむルを怜疫したす。







ファむルを削陀する代わりに、deletedずtimestampを名前に远加しお名前を倉曎したす。 ぀たり、蚭定で指定された時間の間、タむムスタンプ+ファむルを物理的に削陀したす。 障害が発生し、ファむルが誀っお削陀されるこずが決定された堎合、ナヌザヌはそのファむルにアクセスしたす。 ファむルを埩元し、デヌタを倱うこずなく゚ラヌを修正したす。



ここで、2぀のディスクがあり、それぞれに独自のValkyrieがあるこずを思い出しおください。 Valkyriesは互いに同期しおいたせん。 質問が発生したすspace1から゚ントリを削陀するのはい぀ですか







2぀のこずを行いたす。 最初に、特定のファむルにValkyrieりィザヌドの1぀を割り圓おたす。 これは非垞に簡単に行われたす。ファむル名の最初のビットです。 0の堎合、マスタヌはdisk0で、1の堎合、マスタヌはdisk1です。







今、私たちはそれらを時間内に広げたす。 リコヌルファむル゚ントリがspace0にある堎合、敎合性をチェックするマゞックフィヌルドがありたす。 レコヌドをspace1に転送するずき、魔法は必芁ないため、転送時間のタむムスタンプをspace1に曞き蟌みたす。 珟圚、Valkyrieマスタヌはspace1のレコヌドをすぐに凊理し、スレヌブはタむムスタンプに遅延を远加し、埌でレコヌドを凊理し、space1からレコヌドを削陀したす。







これにより、さらにプラスが埗られたす。 ファむルがマスタヌで誀っお隔離された堎合、マスタヌを芁求するず、ログでこれが衚瀺され、それが把握されたす。 その間にファむルを芁求したクラむアントはスレヌブでハッキングされ、ナヌザヌはファむルを受け取りたす。



Valkyrieがディスク䞊にsha1ずいう名前のファむルを芋぀け、このファむル削陀の候補ずしおにspace1に゚ントリがある堎合を調べたした。 他にどんなオプションが可胜か芋おみたしょう。



䟋。 ファむルはディスク䞊にありたすが、FileDBには蚘録がありたせん。 䜕らかの理由でValkyrieマスタヌが䜕らかの理由でしばらく動䜜しなかった堎合、スレヌブはファむルを怜疫し、space1から゚ントリを削陀したした。 この堎合、sha1.deleted.tsを䜿甚しおファむルを怜疫したす。



別の䟋。 レコヌドはありたすが、別のペアを指したす。 これは、1぀のメッセヌゞが2人の受信者に送信された堎合、ファむルのアップロヌド時に発生する可胜性がありたす。 図を思い出したしょう。







2番目のロヌダヌが最初のロヌダヌず同じディスクペアにファむルをダりンロヌドしなかった堎合はどうなりたすか space0のカりンタをむンクリメントしたすが、ゞャンクファむルはそれが泚がれたディスクのペアに残りたす。 このペアに進み、ファむルが読み蟌たれ、sha1が䞀臎するこずを確認したす。 すべおが問題なければ、そのようなファむルはすぐに削陀できたす。



Valkyrieは、隔離されたファむルに遭遇するこずもありたす。 怜疫の有効期限が切れおいる堎合、ファむルは削陀されたす。



ノァルキリヌは良いファむルを芋぀けたした。 sha1ず比范しお、ディスクから読み取っお敎合性をチェックする必芁がありたす。 次に-ペアから別のドラむブに移動し、そこにファむルがあるかどうかを確認したす。 これにはHEADリク゚ストで十分です。 ファむルの敎合性は、そのマシンで実行されおいるデヌモンによっおチェックされたす。 珟圚のマシンでファむルの敎合性が䟵害されおいる堎合、すぐに別のディスクからロヌドされたす。 そのドラむブにファむルがない堎合は、珟圚のドラむブで2番目たでいっぱいにしたす。



最埌のケヌスであるディスクの問題を考慮する必芁がありたす。 監芖埌、管理者はこれが起こったこずを理解したす。 ディスクをサヌビス読み取り専甚モヌドにし、2番目のディスクでがかし手順を開始したす。 2番目のディスクのすべおのファむルは、他のペアに散圚しおいたす。



結果



最初に戻りたしょう。 メヌルは次のようになりたした。









新しい回路に移行した埌、18 Pbを節玄したした。









メヌルは32 Pbを占有し始めたした25-むンデックス、75-ファむル。 解攟された18 Pbにより、長い間、新しい鉄を賌入しないこずができたした。



PS sha1に぀いお



コメントには倚くの質問があるため、ここに远加したす。 珟圚、SHA-1自䜓の衝突の既知の公に蚈算された䟋はありたせん。 圧瞮関数ぞのベクトルを初期化するための衝突SHA-1フリヌスタヌト衝突の䟋がありたす。 ランダムな衝突が120億個のファむルで発生する可胜性10 ^ -38未満。



しかし、これが可胜だずしたす。 この堎合、sha1を䜿甚しおファむルを芁求するずき、アップロヌド時に特定のレタヌのむンデックスで蚘憶したサむズずcrc32のコンプラむアンスをチェックしたす。 ぀たり ファむルがこのレタヌでアップロヌドされた堎合にのみファむルを提䟛したす。そうでない堎合は䜕も提䟛したせん。



All Articles