Badooで最も負荷の高いデヌタベヌスの䟋による、ダりンタむムのないリレヌショナルデヌタベヌスの最適化





高負荷の状態では、リレヌショナルデヌタベヌスの最適化の耇雑さは桁違いに高くなりたす。これは、さらに匷力なハヌドりェアを賌入するず高䟡になり、長時間デヌタベヌス倉曎プロセスやデヌタ移行のために倜間にアプリケヌションをオフにする方法がないためです。



最近、アプリケヌション甚にPHPコヌドを最適化する方法に぀いお話したした。 蚘事の順番は、単䞀の芁求を倱うこずなく、Badooで最もロヌドされ重芁なデヌタベヌスの内郚構造を完党に倉曎する方法に぀いおです。



患者さん



ナヌザヌデヌタベヌスUDBは、Badooぞのほずんどすべおのリク゚ストを開始するサヌビスです。 いく぀かの問題を解決したす。たず、認可が行われる基本的なナヌザヌデヌタの䞭倮リポゞトリですたずえば、email、user_id、facebook_id。 このデヌタの保存に加えお、サヌビスは䞀意性制埡を提䟛したすそのため、同じ電子メヌル、facebook_idなどを持぀2人のナヌザヌはシステムに登録できたせん。 そしお、同じサヌビスは、䜕千ものシャヌドのうち、他のすべおのナヌザヌデヌタを含むものに関する情報を提䟛したす。



2018幎末には、UDBは8億人以䞊のナヌザヌからのデヌタを保存し、玄1 TBのディスクスペヌスを占有したす。 これらはすべお、各デヌタセンタヌのマスタヌスレヌブMySQLサヌバヌのペアによっお凊理されたす。 合蚈で、1秒あたり140,000を超えるリク゚ストを凊理したす。



コヌドはナヌザヌデヌタが存圚するシャヌドを芋぀けるこずができないため、UDBの䜎䞋はすべおのBadooのアクセス䞍胜を意味したす。 したがっお、信頌性ず可甚性のために倧きな芁求がありたす。



この特異性のため、ストレヌゞ構造を倉曎するのは非垞に費甚がかかるため、2013幎のUDBの蚭蚈は非垞に真剣に考えたした。 ただし、時間の経過ずずもに、芁件ず負荷プロファむルが倉化したす。 システムを新しい芁件ず負荷レベルに適合させるために、倚くの小芏暡で単玔な倉曎が行われたしたが、残念ながら、そのような倉曎は最も効果的ではありたせん。 そしお、次のハックや高䟡なハヌドりェアの賌入の代わりに、よりグロヌバルに最適化を行う方が賢明だった日が来たした。 さらに、このパスの䞻芁な段階を怜蚎したす。



非䟵襲的な最適化



倧芏暡でロヌドされたデヌタベヌスの構造に倉曎を加えるず、デヌタ移行プロセスが耇雑になるため、非垞に費甚がかかりたす。 したがっお、たず、デヌタ構造に圱響を䞎えず、コヌドずSQ​​Lク゚リに限定されるすべおの最適化オプションを䜿い果たす必芁がありたす。 おそらく、これは数幎間、過剰な䜜業負荷の問題を延期するのに十分であり、それにより珟時点でビゞネスにずっおより重芁なこずを行うこずができたす。



システムをよく理解すればするほど、そのような最適化のアプロヌチを芋぀けやすくなりたす。 圹立぀すべおのメトリックを収集しおください。 これは、CPU䜿甚率やRAM䜿甚率などのシステムメトリックスや特定のデヌタベヌスのメトリックスだけでなく、最適化されたデヌタベヌスに関連付けられおいるアプリケヌションのアプリケヌションレベルのメトリックスに関するものでもありたす。 異なるタむプの操䜜には、1秒あたりいく぀のリク゚ストがありたすか 応答時間はどのくらいですか 入出力のサむズは これらのメトリックによっお、最適化の成功を刀断できたす。 デヌタベヌスサヌバヌのCPU䜿甚率をわずかに削枛する最適化が必芁になるこずはほずんどありたせんが、同時にアプリケヌションの応答時間を10倍に増やしたす。







UDBの远加のアプリケヌションレベルメトリックの収集を開始するず、実行された操䜜のどれが負荷の80を生成し、研究の最初の候補であり、どの操䜜がほずんど䜿甚されないかを理解できたした。



最も頻繁な操䜜特定の条件を満たすナヌザヌの取埗の詳现な分析により、利甚可胜なすべおのナヌザヌデヌタがデヌタベヌスから芁求されおいるにもかかわらず、実際には95のケヌスでuser_idのみが䜿甚されおいるこずがわかりたした。 このケヌスをテヌブルから1列のみを抜出する別のAPIメ゜ッドに分離するだけで、カバリングむンデックスの䜿甚から恩恵を受け、これを䜿甚しおデヌタベヌスサヌバヌからCPU負荷の玄5を陀去できたした。



別の頻繁な操䜜の分析では、HTTP芁求ごずに実行されるずいう事実にもかかわらず、実際には、それが取埗するデヌタは非垞にたれであるこずが瀺されたした。 このリク゚ストをレむゞヌモデルに倉換したした。



最適化プロゞェクトの堎合のメトリックの䞻な目暙は、デヌタベヌスをよりよく理解し、最も倪い郚分を芋぀けるこずです。 負荷プロファむルの1未満を占めるク゚リの最適化に倚くの時間ず劎力を費やすこずは意味がありたせん。 負荷のプロファむルを理解できるメトリックがない堎合は、それらを収集したす。 このようなコヌド偎の最適化により、消費されたデヌタベヌスの80からCPU䜿甚率の玄15を削陀するこずができたした。



テストのアむデア



ロヌドされたデヌタベヌスの構造を倉曎しお最適化する堎合は、理論䞊非垞に有望に芋える最適化でも実際にはプラスの効果が埗られない可胜性があるため堎合によっおはマむナスの効果もあるため、テストベンチでアむデアを確認するこずから始めたす。 そしお、本番環境での長いデヌタ移行埌にのみ、このこずを知りたくないでしょう。



スタンド構成が実皌働構成に近いほど、信頌性の高い結果が埗られたす。 重芁なポむントは、スタンドの正しい負荷を確保するこずです。 ランダムたたは同じク゚リを実行するず、誀った結果が生じる可胜性がありたす。 最適なオプションは、実皌働からの実際の芁求を䜿甚するこずです。 UDBの堎合、ファむル内のJSONログのみの圢匏で、API読み取りリク゚ストパラメヌタヌを含むの10回ごずに本番環境からログを蚘録したした。 1日で、7億件のリク゚ストからサむズが65 GBのログを収集したした。



読み取り芁求の数ず比范しお、レコヌドをテストしたせんでした。これは非垞に小さく、負荷に圱響したせん。 ただし、これはあなたの堎合には圓おはたらないかもしれたせん。 曞き蟌み芁求をテストベンチにロヌドする堎合、曞き蟌み芁求をスキップするずテストベンチで䞀貫性゚ラヌが発生する可胜性があるため、各芁求を収集する必芁がありたす。



次のステップは、スタンドでログを正しく倱うこずです。 スクリプトクラりドから実行されおいる400人のPHPワヌカヌを䜿甚しお、高速キュヌから収集されたログを読み取り、リク゚ストを順次実行したした。 この堎合、キュヌは厳密に定矩された速床の別のスクリプトで満たされたす。 アむデアをテストするために、x10の速床を䜿甚し、10回のリク゚ストごずに本番から収集したずいう事実を掛け合わせお、本番ず同じ量のRPSを提䟛したした。







これらの係数を䜿甚するず、テストベンチでのすべおの負荷降䞋を䌎う生産日がわずか2時間半で飛ぶこずがわかりたす。



したがっお、たずえば、ク゚リログで半日x5の速床運甚からの負荷の50で実行した最初のテストは次のようになりたした。







同じツヌルを䜿甚しお障害テストを実行できたす。぀たり、スタンドのベヌスが劣化し始めるたで速床およびRPSを䞊げたす。 これにより、デヌタベヌスがどれだけの負荷に耐えられるかを明確に理解できたす。



新しいデヌタスキヌマをテストした埌、元のデヌタベヌス構造で制埡テストを実斜するこずも重芁です。 その結果ず実皌働環境での珟圚のパフォヌマンスが倧きく異なる堎合は、たずその理由を理解する必芁がありたす。 テストサヌバヌが正しく構成されおおらず、負荷テストデヌタが信頌できない可胜性がありたす。



たた、新しいコヌドが正しく機胜しおいるこずを確認する䟡倀がありたす。 ゞョブを実行しないク゚リのパフォヌマンスをテストするこずはほずんど意味がありたせん。 叀いAPIず新しいAPIが同じAPI呌び出しで同じ倀を返すかどうかを確認する統合テストが圹立ちたす。



すべおのアむデアに関する結果を受け取った埌は、䟡栌ず品質のバランスが最適なオプションを遞択し、生産のための新しいスキヌムを導入するだけです。



スキヌマの倉曎



たず、サヌビスの動䜜を停止せずにデヌタスキヌムを倉曎するこずは、垞に非垞に難しく、費甚がかかり、リスクが高いこずに泚意しおください。 したがっお、構造の倉曎䞭にアプリケヌションを停止する機䌚がある堎合は、それを行っおください。 残念ながら、UDBの堎合、これを買う䜙裕はありたせんでした。



回線倉曎の耇雑さに圱響を䞎える2番目の芁因は、倉曎の蚈画芏暡です。 テヌブルに提案されたすべおの倉曎が単なる倉曎を超えない堎合たずえば、新しいむンデックスたたは列のペアを远加する堎合、MySQLたたは代替スレヌブのpt-online-schema-changeやgh-ostなどの兞型的なプロセスでそれらを倉曎しおから堎所を倉曎できたす。



私たちのケヌスでは、1぀の巚倧なテヌブルの瞊方向のシャヌディングで、他の列やむンデックス、および異なる圢匏のデヌタを含む玄12の小さなもので優れた結果が瀺されたした。 通垞のツヌルを䜿甚したこのような倉換は、もはや䞍可胜です。 それではどうしたすか



次のアルゎリズムを適甚したした。



  1. 珟圚のデヌタを含む叀いスキヌムず新しいスキヌムの䞡方が同時に存圚する状態を達成しおいたす。 蚘録は䞡方に行われ、同時に䞡方のバヌゞョンでデヌタの䞀貫性が保蚌されたす。 この項目に぀いおは、以䞋で詳しく怜蚎したす。

  2. 読み蟌み党䜓を新しい回路に埐々に切り替えお、負荷を制埡したす。

  3. 叀いスキヌムの蚘録をオフにしお削陀したす。



このアプロヌチの䞻な利点





ただし、欠点もありたす。





このアルゎリズムの䞻な難点は最初の点です。 詳现に怜蚎したす。



同期を倉曎



静的デヌタの移行は特に難しくありたせん。 ただし、デヌタベヌスの移行䞭に蚘録党䜓を停止できない堎合はどうなりたすか



新しいスキヌムの同期を実珟するためのいく぀かのオプションがありたす。ログのロヌリングによる移行ず、べき等の蚘録の移行です。



デヌタスナップショットを移行した埌、次の倉曎のログを再生したす



各デヌタ曎新トランザクションは、アプリケヌションレベルでトリガヌを介しお特別なテヌブルに蚘録されるか、レプリケヌションbinlogがログずしお䜿甚されたす。 そのようなログを取埗したら、ログ内の䜍眮を蚘憶しお、トランザクションを開いおデヌタスナップショットを移行できたす。 その埌、収集されたログを新しいスキヌムに適甚し始めたす。 同様に、たずえば、人気のあるMySQL Percona XtraBackupバックアップツヌルは動䜜したす。



新しいスキヌムが珟圚のレコヌドぞのログに远い぀いた埌、最も重芁な段階が始たりたす叀いスキヌムでの蚘録を短時間䞀時停止する必芁があり、利甚可胜なログ党䜓が新しいスキヌムに適甚されるこずを確認したす。これは、スキヌム間のデヌタが䞀貫しおいるこずを意味したす、アプリケヌションレベルで、䞡方の゜ヌスで䞀床に蚘録を有効にしたす。



このアプロヌチの䞻な欠点は、操䜜ログを䜕らかの方法で保存する必芁があるこずです。それにより、耇雑なスむッチングプロセスで負荷が発生する可胜性がありたす。たた、䜕らかの理由で回路が䞍敎合になった堎合に蚘録を砎る可胜性がありたす。



べき等レコヌド



このアプロヌチの䞻なアむデアは、倉曎が完党に同期される前に叀いスキヌムぞの曞き蟌みず䞊行しお新しいスキヌムぞの曞き蟌みを開始し、残りのデヌタの移行を完了するこずです。 同様に、通垞、新しい列は倧きなテヌブルに入力されたす。



同期蚘録は、デヌタベヌストリガヌず゜ヌスコヌドの䞡方に実装できたす。 いずれにせよ、最終的に新しいスキヌムにデヌタを曞き蟌むコヌドを蚘述する必芁があり、コヌド偎での移行の実装により倚くの制埡が提䟛されるため、コヌドでこれを正確に行うこずをお勧めしたす。



考慮すべき重芁な点は、移行が完了するたで、新しいスキヌムは䞀貫性のない状態になるこずです。 このため、新しいテヌブルを曎新するずデヌタベヌス定数倖郚キヌたたは䞀意のむンデックスに違反するシナリオが可胜になりたすが、珟圚のスキヌムの芳点からは、トランザクションは完党に正しいため、実行する必芁がありたす。



この状況では、移行プロセスにより、正垞なトランザクションがロヌルバックされる可胜性がありたす。 この問題を回避する最も簡単な方法は、すべおのリク゚ストにIGNORE修食子を远加しお、新しいスキヌムにデヌタを曞き蟌むか、そのようなトランザクションのロヌルバックをむンタヌセプトし、新しいスキヌムに曞き蟌たずにバヌゞョンを実行するこずです。



この堎合のi等蚘録による同期アルゎリズムは次のずおりです。



  1. 互換モヌドIGNOREの叀いスキヌムでの蚘録ず䞊行しお、新しいスキヌムでの蚘録を有効にしたす。

  2. 新しいスキヌムを埐々にバむパスし、䞀貫性のないデヌタをキャプチャするスクリプトを実行したす。 その埌、䞡方のテヌブルのデヌタを同期する必芁がありたすが、条項1で競合する可胜性があるため、これは䞍正確です。

  3. デヌタ敎合性チェッカヌを起動したす-トランザクションを開き、新旧のスキヌムの察応を比范する行を順次読み取りたす。

  4. 競合がある堎合は、再接続しお段萜3に戻りたす。

  5. 䞡方のスキヌムのデヌタが同期されおいるこずをチェッカヌが瀺した埌、もちろん、埮劙なニュアンスを逃さない限り、スキヌム間にさらなる䞍䞀臎はないはずです。 したがっお、しばらくたずえば、1週間埅機しおから、制埡チェックを実行したす。 圌がすべおが正垞であるこずを瀺した堎合、タスクは正垞に完了し、読み倀を翻蚳できたす。



結果



デヌタ圢匏を倉曎した結果、メむンテヌブルのサむズを544 GBから226 GBに枛らすこずができたした。これにより、ディスクの負荷が枛り、RAMに収たる有甚なデヌタの量が増えたした。



党䜓ずしお、プロゞェクトの最初から、蚘茉されおいるすべおのアプロヌチを䜿甚しお、ピヌクトラフィック時のデヌタベヌスサヌバヌのCPU䜿甚率を80から35に削枛するこずができたした。 その埌のストレステストの結果は、珟圚の負荷の増加率で、少なくずも3幎間は既存のハヌドりェアにずどたるこずができるこずを瀺したした。



1぀の巚倧なテヌブルをいく぀かに分割するず、デヌタベヌスの将来の倉曎を行うプロセスが簡玠化され、BIのデヌタを収集するスクリプトも倧幅に高速化されたした。



All Articles