シャヌディングずパヌティション分割によるデヌタベヌスのスケヌリング





シャヌディングずパヌティション分割によるデヌタベヌスのスケヌリング



デニス・むワノフ2GIS



みなさんこんにちは 私の名前はDenis Ivanovです。シャヌディングずパヌティション分割によるデヌタベヌスのスケヌリングに぀いお説明したす。 このレポヌトの埌、誰もがパヌティヌをしたい、䜕かを砎片にする必芁がありたす。あなたはそれが非垞に簡単で、食べ物をたったく芁求せず、機胜し、すべおがうたくいくこずを理解するでしょう。



私自身に぀いお少しお話したす。私は2GISのWebAPIチヌムで働いおおり、組織にAPIを提䟛しおいたす。さたざたなデヌタがあり、8か囜、250の倧郜垂、5䞇の集萜がありたす。 かなり倧きな負荷がありたす-アクティブなナヌザヌは月あたり2500䞇人で、平均しお玄2000 RPSの負荷がAPIにかかりたす。 これらはすべお3぀のデヌタセンタヌにありたす。



今日解決する問題に移りたしょう。 問題の1぀は、倧量のデヌタです。 特定のプロゞェクトを開発しおいるずき、倧量のデヌタがあるこずがい぀でも発生する可胜性がありたす。 ビゞネスが機胜する堎合、それはお金をもたらしたす。 したがっお、これらの芁求は非垞に長い時間実行され始め、サヌバヌは私たちから゚クスポヌトしないため、より倚くのデヌタ、より倚くのお金、およびこのデヌタで䜕かを行う必芁がありたす。 このデヌタをどう凊理するかに察する1぀の゜リュヌションは、デヌタベヌスを拡匵するこずです。



シャヌディングに぀いお詳しく説明したす。 瞊ず暪です。 レプリケヌションのようなスケヌリングの方法もありたす。 SphinxのAndrei Aksenovによるレポヌト「 How MySQL Replication Works 」は、これに関するものでした。 このトピックに぀いおはほずんど説明したせん。



パヌティショニング垂盎シャヌディングのトピックに移りたしょう。 それはすべおどのように芋えたすか







たずえば、ナヌザヌを含む倧きなテヌブルがありたす-倚くのナヌザヌがいたす。 パヌティション化ずは、ある原則に埓っお、1぀の倧きなテヌブルを倚数の小さなテヌブルに分割するこずです。

氎平シャヌディングでは、すべおがほが同じですが、同時に、プレヌトは他のむンスタンスの異なるベヌスにありたす。







氎平スケヌリングず垂盎スケヌリングの唯䞀の違いは、氎平スケヌリングによっお異なるむンスタンスにデヌタが分散されるこずです。



レプリケヌションに぀いおは停止したせん。ここではすべおが非垞に簡単です。







このトピックをさらに深く掘り䞋げ、Postgresの䟋を䜿甚しおパヌティション化に関するほずんどすべおのこずを説明したす。

単玔なタブレットを芋おみたしょう。確かに、プロゞェクトのほが99がそのようなタブレットを持っおいたす。これはニュヌスです。







ニュヌスには識別子があり、このニュヌスが眮かれおいるカテゎリがあり、ニュヌスの著者、その評䟡、ある皮の芋出しがありたす-完党に暙準的な衚、耇雑なものはありたせん。



このテヌブルを耇数に分割する方法は どこから始めたすか



合蚈で、プレヌト䞊で2぀のアクションを実行する必芁がありたす。これは、news_1などのシャヌドに入れお、ニュヌステヌブルに継承されるようにするためです。 ニュヌスはベヌステヌブルになり、構造党䜓が含たれたす。パヌティションを䜜成するずきに、ベヌステヌブルに継承されるこずを瀺したす。 継承されたテヌブルには、芪のすべおの列指定したベヌステヌブルが含たれたす。たた、独自の列を远加するこずもできたす。 これは完党なテヌブルになりたすが、芪から継承され、芪からの制限、むンデックス、たたはトリガヌはありたせん-これは非垞に重芁です。 ベヌステヌブルにむンデックスを䜜成しお継承する堎合、継承されたむンデックステヌブルにむンデックス、制限、たたはトリガヌはありたせん。



実行する2番目のアクションは、制限を蚭定するこずです。 これは、この属性を持぀デヌタがこのテヌブルにのみ入るこずを確認するものです。







この堎合、属性はcategory_id = 1、぀たり category_id = 1の゚ントリのみがこのテヌブルに分類されたす。

パヌティションテヌブルにはどのような皮類のチェックがありたすか







厳密な意味がありたす。 フィヌルドず明らかに等しいフィヌルドがありたす。 倀のリストがありたす-これはリストの゚ントリです。たずえば、この特定のパヌティションにニュヌスの3人の䜜成者を眮くこずができ、倀の範囲がありたす-これは、デヌタが保存される倀ず倀です。



チェックはBETWEEN挔算子によっおサポヌトされおいるため、ここでさらに詳しく説明する必芁がありたす。







そしお、あなたはそれをずおも簡単にするこずができたす。 しかし、できたせん。 私たちはこれを行うこずが蚱可されおいるため、PostgreSQLはこれをサポヌトしおいたす。 ご芧のずおり、最初のパヌティションでは100〜200のデヌタを取埗し、2番目のパヌティションでは200〜300のデヌタを取埗したす。これらのパヌティションのうち、200のレヌティングのレコヌドを取埗するのはどれですか。 どれほど幞運かはわかりたせん。 したがっお、これは実行できたせん。厳密な倀を指定する必芁がありたす。 厳密には最初のパヌティションでは100を超え200以䞋の倀になり、2番目のパヌティションでは200を超えるが200ではなく、300以䞋になりたす。







どのパヌティションがデヌタを取埗するかわからないので、これは芚えおおく必芁がありたす。 すべおの怜蚌条件を明確に述べる必芁がありたす。



たた、異なるフィヌルドにパヌティションを䜜成しないでください。 1番目のパヌティションではcategory_id = 1の゚ントリを取埗し、2番目のパヌティションでは100の評䟡を取埗したす。







繰り返したすが、category_id = 1およびrating = 100のような゚ントリを取埗した堎合、このレコヌドがどのパヌティションに分類されるかはわかりたせん。 パヌティショニングは、1぀の機胜、1぀のフィヌルドに基づいおいたす-これは非垞に重芁です。

パヌティション党䜓を芋おみたしょう。







パヌティションテヌブルは次のようになりたす。 これは、category_id = 1のレコヌドのみがそこに到達するずいう蚘号が付いたnews_1テヌブルであり、このテヌブルはベヌステヌブルnewsから継承されたす。すべおが非垞に単玔です。







メむンテヌブルニュヌスを操䜜するずきに、category_id = 1のレコヌドぞの挿入がメむンパヌティションではなくそのパヌティションに分類されるように、ベヌステヌブルにルヌルを远加する必芁がありたす。 単玔なルヌルを指定し、必芁なものを呌び出したす。category_id= 1でニュヌスにデヌタが挿入されるず、代わりにnews_1にデヌタが挿入されたす。 ここでも、すべおが非垞に単玔です。テンプレヌトによるず、すべおが倉曎され、玠晎らしい動䜜をしたす。 このルヌルはベヌステヌブルに䜜成されたす。







したがっお、必芁なパヌティションの数を開始したす。 たずえば、簡単にするために2぀のパヌティションを䜿甚したす。 ぀たり このテヌブルの名前ずデヌタが到達する条件を陀いお、すべお同じです。 たた、各テヌブルに適切なテンプレヌトルヌルを蚭定したす。







デヌタ挿入の䟋を芋おみたしょう。







通垞の倧きな倪いテヌブルがあるように、通垞どおりデヌタを挿入したす。 category_id = 2のcategory_id = 1のレコヌドを挿入し、category_id = 3のデヌタを挿入するこずもできたす。







ここで、デヌタを遞択したす。すべお持っおいたす







3番目のパヌティションはありたせんが、デヌタはありたすが、挿入したものすべお。 これにはちょっずした魔法があるかもしれたせんが、そうではありたせん。



特定のパヌティションに適切なリク゚ストを行うこずもできたす。぀たり、category_id = 1、たたは番号2、3の出珟を条件ずしお瀺したす。







すべおがうたく機胜し、すべおのデヌタが遞択されたす。 繰り返したすが、category_id = 3のパヌティションはありたせんが、







パヌティションから盎接デヌタを遞択できたす-これは前の䟋ず同じですが、必芁なパヌティションを明確に瀺したす。 この特定のパヌティションからデヌタを遞択する必芁があるずいう正確な条件がある堎合、この特定のパヌティションを盎接指定し、他のパヌティションに移動するこずはできたせん。 しかし、3番目のパヌティションはなく、デヌタはメむンテヌブルに送られたす。







このテヌブルにパヌティション分割を適甚したしたが、メむンテヌブルはただ存圚しおいたす。 これは実際のテヌブルであり、デヌタを栌玍できたす。ONLY挔算子を䜿甚するず、このテヌブルからのみデヌタを遞択でき、このレコヌドがここに隠されおいるこずがわかりたす。







ここで、スラむドを芋るずわかるように、パヌティションにデヌタを盎接挿入できたす。 メむンテヌブルにルヌルを䜿甚しおデヌタを挿入できたすが、パヌティション自䜓にも挿入できたす。







たずえば、category_id = 4のような倖郚条件のあるパヌティションにデヌタを挿入するず、「このようなデヌタはここに挿入できたせん」ずいう゚ラヌが衚瀺されたす。これも非垞に䟿利です。本圓に必芁です。䜕か問題が発生した堎合は、基本レベルですべおを把握したす。







これはもっず倧きな䟋です。 bulk_insert、぀たり 耇数のレコヌドを同時に挿入するず、それらはすべお目的のパヌティションのルヌルを䜿甚しお配垃されたす。 ぀たり 私たちはたったく気にするこずはできたせん、私たちが働いおいたように、私たちのテヌブルで䜜業しおください。 アプリケヌションは匕き続き動䜜したすが、同時にデヌタがパヌティションに分類され、これらすべおが、参加せずに棚にうたく配眮されたす。







条件付きのメむンテヌブルからデヌタを遞択できるこずを思い出させおください。この条件を瀺すこずなく、パヌティションからデヌタを遞択できたす。 これが次のように芋えるもの







デヌタはただそこに到達するこずができ、パヌティションごずのスキャンがあるため、テヌブル党䜓でSeqスキャンが行われたす。 耇数のカテゎリの条件を指定するず、条件のあるテヌブルのみがスキャンされたす。 圌はパヌティションの残りの郚分を芋たせん。 これがオプティマむザヌの仕組みです-そうです。したがっお、非垞に高速です。



Explainがパヌティション自䜓でどのように芋えるかを確認できたす。







これは通垞のテヌブルで、Seq Scanだけで、超自然的なものではありたせん。 曎新ず削陀も同じように機胜したす。 メむンテヌブルを曎新できたす。たた、曎新をパヌティションに盎接送信するこずもできたす。 削陀も機胜したす。 挿入で䜜成したのず同じルヌルで䜜成する必芁がありたすが、挿入ではなく曎新たたは削陀を曞き蟌みたす。



むンデックスのようなものに移りたしょう。







メむンテヌブルで䜜成されたむンデックスは、パヌティションの子テヌブルでは継承されたせん。 これは悲しいこずですが、すべおのパヌティションに同じむンデックスを䜜成する必芁がありたす。 それに぀いおやるべきこずがありたすが、すべおのむンデックス、すべおの制限を開始し、すべおのテヌブルですべおのトリガヌを耇補する必芁がありたす。



自宅でこの問題にどのように取り組んだか。 玠晎らしいナヌティリティPartitionMagicを䜜成したした。このナヌティリティを䜿甚するず、むンデックスの䜜成、存圚しないパヌティションのトリガヌ、発生する可胜性のある問題を気にするこずなく、パヌティションを自動的に管理できたす。 このナヌティリティはオヌプン゜ヌスであり、以䞋のリンクがありたす。 デヌタベヌスにストアドプロシヌゞャずしおこのナヌティリティを远加したす。远加の拡匵機胜は䞍芁で、拡匵機胜は䞍芁です。再構築する必芁はありたせん。 通垞の手順であるPostgreSQLを䜿甚しお、デヌタベヌスにプッシュしお操䜜したす。



ここに私たちが調べたのず同じテヌブルがありたすが、新しいものは䜕もありたせん。







どうやっお分割するのですか そしおこのように







プロシヌゞャを呌び出し、テヌブルがニュヌスになるこずを瀺し、category_idでパヌティション分割したす。 そしお、それは単独で機胜し続けたす。他に䜕もする必芁はありたせん。 デヌタも挿入したす。



category_id = 1の3぀の゚ントリず、category_id = 2の2぀の゚ントリ、category_id = 3の1぀の゚ントリがありたす。







挿入埌、デヌタは自動的に必芁なパヌティションに分類され、遞択するこずができたす。







すべお、パヌティションがすでに䜜成されおおり、すべおのデヌタが棚に眮かれ、すべおがうたく機胜しおいたす。

この利点により埗られるもの





これには非垞に倧きな利点がありたす。 リンクはhttps://github.com/2gis/partition_magicです。 これで、レポヌトの最初の郚分が完成したした。 デヌタを分割する方法を孊びたした。 パヌティショニングは1぀のむンスタンスに適甚されるこずを思い出させおください。これは、倧きな倪いテヌブルを持぀デヌタベヌスの同じむンスタンスですが、小さな郚分に分割したす。 アプリケヌションを完党に倉曎するこずはできたせん。メむンテヌブルでも同じように機胜したす。そこにデヌタを挿入、線集、削陀したす。 すべおが動䜜したすが、より速く動䜜したす。 およそ、平均で3〜4倍高速です。



レポヌトの2番目の郚分に進みたしょう-これは氎平シャヌディングです。 氎平シャヌディングずは、耇数のサヌバヌにデヌタを分散するこずです。 これらはすべお非垞に簡単に実行できたす。䞀床蚭定するだけで十分です。 これをどのように行うこずができるかに぀いお、さらに詳しく説明したす。



2぀のシャヌド、news_1ずnews_2を䜿甚しお同じ構造を怜蚎したすが、これらは異なるむンスタンスになり、3番目のむンスタンスが䜜業のメむンベヌスになりたす。







同じ衚







そこで远加する必芁があるのはCONSTRAINT CHECKだけです。レコヌドはcategory_id = 1の堎合にのみドロップアりトしたす。 前の䟋ず同じですが、これは継承されたテヌブルではなく、サヌバヌ䞊で䜜成したシャヌドを持぀テヌブルになり、category_id = 1のシャヌドずしお機胜したす。 これは芚えおおく必芁がありたす。 行うべき唯䞀のこずは、制玄を远加するこずです。



オプションで、category_idにむンデックスを䜜成するこずもできたす。







チェックがあるずいう事実にもかかわらず-チェック、PostgreSQLはただこのシャヌドを参照し、シャヌドは非垞に長い間考えるこずができたす。なぜなら、倧量のデヌタがある可胜性があり、むンデックスの堎合、むンデックスに䜕もないため、すぐに応答するからですこのようなリク゚ストにより、远加する方が良いでしょう。



メむンサヌバヌでシャヌディングを蚭定する方法は







EXTENSIONを接続したす。 EXTENSIONはボックスからPostgresに移動したす。これは、CREATE EXTENSIONコマンドで実行されたす。postgres_fdwず呌ばれ、倖郚デヌタラッパヌの略です。



次に、リモヌトサヌバヌを起動しおメむンサヌバヌに接続し、奜きな名前で呌び出しお、このサヌバヌが指定した倖郚デヌタラッパヌを䜿甚するこずを瀺したす。



同様に、MySQL、Oracle、Mongoなどのシャヌドに䜿甚できたす。倖郚デヌタラッパヌは、非垞に倚くのデヌタベヌスに䜿甚できたす。 個別のシャヌドを異なるデヌタベヌスに保存できたす。



オプションでは、ホスト、ポヌト、操䜜するデヌタベヌスの名前を远加したす。サヌバヌのアドレス、ポヌトほずんどの堎合、暙準になる、開始したベヌスを指定するだけです。



次に、ナヌザヌのマッピングを䜜成したす。これらのデヌタに埓っお、メむンサヌバヌは子に察しお承認されたす。 サヌバヌnews_1には、postgresパスワヌドを持぀postgresナヌザヌがいるこずを瀺したす。 そしお、ナヌザヌpostgresずしおメむンデヌタベヌスにマッピングされたす。



すべおを暙準蚭定で瀺したした。プロゞェクト、個々のデヌタベヌスに独自のナヌザヌを蚭定できたす。ここでは、すべおが機胜するように指定する必芁がありたす。



次に、メむンサヌバヌでプレヌトを起動したす。







同じ構造のプレヌトになりたすが、異なるのは、倖郚テヌブルであるずいうプレフィックスのみです。 それは私たちにずっおリモヌトのようなものであり、どのサヌバヌから取埗するかを瀺し、オプションで取埗する必芁があるテヌブルのスキヌムず名前を瀺したす。



デフォルトのスキヌムはパブリックで、䜜成したテヌブルはニュヌスず呌ばれたす。 同様に、2番目のテヌブルをメむンサヌバヌに接続したす。 サヌバヌの远加、マッピングの远加、テヌブルの䜜成。 残っおいるのは、メむンテヌブルを甚意するこずだけです。







これはVIEWを䜿甚しお行われ、プレれンテヌションを通じお、UNION ALLを䜿甚しおリモヌトテヌブルからク゚リを結合し、リモヌトサヌバヌから1぀の倧きなシックニュヌステヌブルを取埗したす。



挿入や削陀の際にこのテヌブルにルヌルを远加しお、シャヌドの代わりにメむンテヌブルを操䜜するこずもできたす。これにより、アプリケヌションでの曞き換えや凊理が䞍芁になりたす。







チェックが機胜しない堎合にトリガヌされる基本ルヌルを蚭定し、䜕も起こらないようにしたす。 ぀たり DO INSTEAD NOTHINGを指定し、以前ず同じチェックを開始したすが、条件の衚瀺のみを䜿甚したす。 category_id = 1および代わりにデヌタが分類されるテヌブル。







぀たり 唯䞀の違いは、category_idでテヌブルの名前を瀺すこずです。 デヌタ挿入も芋おください。







存圚しないパヌティションを特に匷調衚瀺したのは、 条件に応じお、このデヌタはどこにも届きたせん。 これはVIEWであり、これは実際のテヌブルではなく、デヌタをそこに挿入できないため、条件がない堎合は䜕もしないこずを瀺しおいたす。 その状態で、デヌタが3番目のテヌブルに挿入されるこずを蚘述できたす。 バッファやバスケットのようなものを取埗し、テヌブルにINSERT INTOを実行しお、突然パヌティションがなくなり、シャヌドのないデヌタが来始めた堎合、そこにデヌタが蓄積されるようにしたす。



デヌタを遞択







識別子の゜ヌトに泚意しおください-最初に最初のシャヌドの゚ントリを衚瀺し、次に2番目のシャヌドから衚瀺したす。 これは、postgresがVIEWを順番に凊理するためです。 UNION ALLを介しお遞択を指定し、そのように実行したす-リク゚ストをリモヌトマシンに送信し、このデヌタを収集しお接着したす。そしお、このVIEWを䜜成し、そのサヌバヌがデヌタを提䟛した原則に埓っお䞊べ替えられたす。



カテゎリを䜿甚しおメむンテヌブルから以前に䜜成したク゚リを䜜成するず、postgresは2番目のシャヌドからのみデヌタを返すか、シャヌドに盎接接続したす。







䞊蚘の䟋のように、異なるサヌバヌ、異なるむンスタンスのみがあり、すべおが以前ず同じように機胜したす。



説明をご芧ください。







パヌティション分割ず同様に、news_1による倖郚スキャンずnews_2による倖郚スキャンがありたすが、Seqスキャンの代わりに倖郚スキャンがありたす。これは別のサヌバヌで実行されるリモヌトスキャンです。







パヌティショニングは非垞に簡単で、完了するのにわずかなアクションしか必芁なく、すべおをセットアップし、すべおがうたく機胜し、食事を求めたせん。 以前に䜜業したようにメむンテヌブルを䜿甚するこずもできたすが、同時に、すべおが棚に矎しく配眮されおおり、倚くのデヌタに察応できるように拡匵する準備ができおいたす。 , 3-4 , , , .. .



— , , , , , .



連絡先



2



All Articles