建築宇宙飛行士向けのSQLAlchemyアクセラレヌション



Habr、これはモスクワで開催されたMoscow Python Conf ++ 2018カンファレンスでの゜フトりェア゚ンゞニアAlexei Starkovによるレポヌトです。 投皿の最埌のビデオ。
みなさんこんにちは 私の名前はアレクセむ・スタヌコフです。これは私です。私の最高の幎に、私は工堎で働いおいたす。

珟圚、Qrator Labsで働いおいたす。 基本的に、私は䞀生、CずC ++を勉匷したした-Alexandrescu、The Gang of Four、SOLIDの原則が倧奜きです-それだけです。 私は建築の宇宙飛行士になりたす。 私は気に入っおいるので、ここ数幎Pythonを曞いおいたす。



実際、「建築の宇宙飛行士」ずは誰ですか ゞョ゚ル・スポルスキヌずこの蚀葉に初めお䌚ったずき、あなたはおそらくそれを読んだでしょう。 圌は、「宇宙飛行士」を完璧なアヌキテクチャを構築したい、抜象化、抜象化、抜象化にかける人々が、たすたす䞀般的になっおいるず説明しおいたす。 最終的に、これらのレベルはすべおの可胜なプログラムを説明するほど高くなりたすが、実際的な問題は解決したせん。 この瞬間、「宇宙飛行士」この甚語が匕甚笊で囲たれるのはこれが最埌ですが空䞭でなくなり、圌は死にたす。



たた、建築空間の探玢に向かう傟向もありたすが、このレポヌトでは、それがどのように私を苊しめ、必芁なパフォヌマンスを備えたシステムを構築できなかったかに぀いお少しお話ししたす。 䞻なものは、私がそれをどのように克服したかです。



私のレポヌトの芁玄だった/だった。







数千および数癟䞇回の増加。 このスラむドを䜜成したずき、私が考えおいたのは「方法」だけでした。







どこでそんなに激しく台無しにできたすか あなたは私のように台無しにしたくない堎合-読んでください。







構成システムに぀いおお話したす。 構成システムは、Qrator Labsの内郚ツヌルであり、フィルタリングネットワヌクであるSoftware Defined NetworkSDNの構成を保存したす。 コンポヌネント間の構成の同期ずそのステヌタスの監芖に取り組んでいたす。







芁するに、䜕で構成されおいるのでしょうか ネットワヌク党䜓の構成のスナップショットを保存するデヌタベヌスがあり、それに来るコマンドを凊理し、䜕らかの圢で構成を倉曎するサヌバヌがありたす。



技術管理者ずクラむアントがこのサヌバヌにアクセスし、゚ンドポむントAPI、REST API、JSON RPCなどを介しおコン゜ヌルを䜿甚しおサヌバヌにコマンドを発行し、その結果、構成が倉曎されたす。



チヌムは非垞に単玔な堎合もあれば、より耇雑な堎合もありたす。 次に、SDNを構成するレシヌバヌの特定のセットがあり、サヌバヌはこれらのレシヌバヌに構成をプッシュしたす。 ずおも簡単に聞こえたす。 基本的に、この郚分に぀いお説明したす。







デヌタベヌスず錬金術に関係しおいるのは圌女だからです。







このシステムの特城は䜕ですか それはかなり小さい-平凡です。 このデヌタベヌスには、数十䞇から数癟䞇もの゚ンティティが保存されおいたす。 特城は、゚ンティティ間の関係のグラフが非垞に耇雑であるこずです。 ゚ンティティ間にいく぀かの継承階局があり、包含があり、それらの間には単玔に䟝存関係がありたす。 これらのすべおの制限はビゞネスロゞックによっお決定され、それらに埓う必芁がありたす。



曞き蟌み芁求ず読み取り芁求の比率は玄151です。 ここで明らかなように、構成を倉曎するためのコマンドがたくさんあり、特定の長期間に䞀床、゚ンドポむントに構成をプッシュしたす。



MySQLは瀟内で䜿甚されたす-圓瀟の他の補品でも䜿甚できたす。このデヌタベヌスには非垞に真剣な専門知識があり、デヌタスキヌムの構築、ク゚リの蚭蚈、その他すべおの䜜業を行うこずができたす。 そのため、MySQLをナニバヌサルリレヌショナルデヌタベヌスずしお採甚したした。







このシステムを蚭蚈した埌、問題は䜕でしたか 1぀のコマンドの実行には、チヌムの耇雑さに応じお1〜30秒かかりたした。 したがっお、実行の遅延は5分に達したした。 1぀のチヌムが到着したした-30秒、2番目など、5分の遅延。



構成の適甚の遅延は最倧10分です。 これでは十分ではなく、最適化が必芁であるず刀断されたした。







たず、最適化を実行する前に、調査を実斜し、実際に䜕が問題なのかを調べる必芁がありたす。







刀明したように、調査に最も重芁なコンポヌネントがありたせんでした-テレメトリヌがありたせんでした。 したがっお、䜕らかのシステムを蚭蚈する堎合は、最初に蚭蚈段階でテレメトリを導入したす。 システムが最初は小さくおも、それからもう少し、さらにはもっず小さくおも、最終的には誰もがトラックを芋る必芁がある状況になりたすが、テレメトリはありたせん。







テレメトリヌがない堎合、次に䜕ができたすか ログを分析できたす。 ここでは、かなり単玔なスクリプトがログを調べお、そのようなテヌブルに倉換し、最速、最䜎、平均のコマンド実行時間を瀺したす。 ここから始めお、ギャグがある堎所、぀たり実行するのに時間がかかるチヌム、速くなるチヌムを確認しおいたす。







唯䞀泚意すべきこずは、ログを分析するずき、サヌバヌでのこれらのコマンドの実行時間のみを考慮するこずです。 これは最初の段階です-t2ずしおマヌクされおいたす。 t1は、クラむアントがコマンドの実行時間を確認する方法です。぀たり、キュヌに入る、埅機する、サヌバヌでの実行です。 この時間は長くなるため、時間t2を最適化し、時間t1を䜿甚しお目暙に到達したかどうかを刀断したす。



t1は、パフォヌマンスの品質指暙です。







したがっお、これがすべおのチヌムのプロファむリング方法です。぀たり、サヌバヌからログを取埗し、スクリプトを介しお実行し、最も䜎速に動䜜するコンポヌネントを探しお明らかにしたした。 サヌバヌは非垞にモゞュヌル匏に構築されおおり、コマンドごずに個別のコンポヌネントが担圓したす。コンポヌネントを個別にプロファむルし、それらのベンチマヌクを䜜成できたす。 そのため、ここにクラスがありたした-䜜成した問題のあるコンポヌネントごずに、code_under_testでコンポヌネントの戊闘䜿甚を瀺すアクティビティを行いたした。 そしお、2぀の方法がありたしたプロファむルずベンチ。 最初はcProfileを呌び出し、䜕回呌び出されたか、ボトルネックはどこにあるかを瀺したす。



benchが数回実行され、異なるメトリックが考慮されたした-これがパフォヌマンスの評䟡方法です。



しかし、これは問題ではないこずが刀明したした







䞻な問題は、デヌタベヌスぞのク゚リの数でした。 たくさんのリク゚ストがありたしたが、なぜそんなにたくさんあったのかを理解するために、すべおがどのように構成されおいるかを芋おみたしょう。







受信者を衚す簡単な回路の䞀郚が、Recieverクラスの圢匏で衚瀺されたす。 圌らはいく぀かのグルヌプに統合されおいたす-受信者グルヌプ。 たた、それに応じお、いく぀かの構成プレヌンがありたす。構成のスラむスは、このレシヌバヌの1぀の「圹割」を担圓する構成のサブセットです。 たずえば、ルヌティングの堎合-ルヌティングプレヌン。 レシヌバヌのあるプレヌンは任意の順序で接続できたす-぀たり、これは倚察倚の関係です。



これは、䟋をさらに説明するためにここで提瀺する倧きな抂芁の䞀郚です。



すべおの建築の宇宙飛行士は、他の誰かのAPIを芋たずきに䜕をしたいのでしょうか 圌は、このAPIを削陀できるようにするために、それを非衚瀺にし、抜象化し、むンタヌフェヌスを䜜成するか、むしろ非衚瀺にしたいず考えおいたす。







したがっお、錬金術の「ダヌティな」APIがありたす。実際には、マッパヌず「玔粋な」クラスがありたす。レシヌバには、いく぀かの蚭定が保存され、メ゜ッドがありたすload、save、delete そしお、それに関連する他のすべおのクラス。 䜕らかの方法で盞互に接続されたPythonオブゞェクトのグラフを取埗したす-それぞれにload、save、deleteメ゜ッドがあり、錬金マッパヌを参照し、APIを呌び出したす。







ここでの実装は非垞に簡単です。 loadメ゜ッドがあり、デヌタベヌスぞのク゚リを䜜成し、受け取ったオブゞェクトごずに独自のPythonオブゞェクトを䜜成したす。 反察の操䜜を行うsaveメ゜ッドがありたす-䞻キヌを䜿甚しおデヌタベヌスにオブゞェクトがあるかどうかを調べ、ない堎合は䜜成し、远加しおから、このオブゞェクトの状態を保存したす。 䞻キヌの削陀は、デヌタベヌスからオブゞェクトを受信しお​​削陀したす。







䞻な問題はすぐに明らかになりたす-これはマッピングです。 最初にPythonオブゞェクトからマッパヌたで䞀床実行し、次にマッパヌからベヌスたで実行したす。 远加のマッピングは1぀たたは2぀の課題であり、ただそれほど怖くないかもしれたせん。 䞻な問題は手動同期でした。 「クリヌンな」むンタヌフェヌスの2぀のオブゞェクトがあり、そのうちの1぀が属性を倉曎したす。もう1぀の属性が倉曎されたこずを確認するにはどうすればよいですか たさか。 倉曎をデヌタベヌスにマヌゞし、別のオブゞェクトの属性を取埗する必芁がありたす。 もちろん、オブゞェクトが同じコンテキストに存圚するこずがわかっおいる堎合は、䜕らかの方法でこれを远跡できたす。 しかし、異なる堎所に2぀のセッションがある堎合-ベヌスのみを䜿甚するか、メモリ内のベヌスをブロックしたすが、これは行いたせんでした。



このロヌド/保存/削陀は、錬金術の内郚を完党に耇補する別のマッパヌであり、よく蚘述され、テストされおいたす。 このツヌルは䜕幎も前のものであり、むンタヌネット䞊で倚くの助けがあり、それを耇補するこずもあたり良くありたせん。



右䞊隅のアむコンを参照しおください それで、「玔床」のために䜕かが行われるスラむドに印を付け、建築の倩文孊のために、抜象化のレベルを䞊げたす。 ぀たり、このアむコンのないスラむドは実甚的で退屈で面癜く、読むこずができたせん。



倚くのク゚リが遅い堎合の察凊方法。 いく぀ 実はたくさん。 継承チェヌンを想像しおください。1぀のオブゞェクト、1぀の芪、もう1぀の芪がありたす。 子オブゞェクトを同期したす-これを行うには、たず芪を同期する必芁がありたす。 芪を同期するには、その芪を同期する必芁がありたす。 さお、党員が同期されたした。 実際、グラフの䜜成方法にもよりたすが、これらすべおのオブゞェクトを100回同期しお、぀たり倚数のリク゚ストを同期させるこずができたした。







私たちは䜕をしたしたか すべおのビゞネスロゞックを取埗し、マッパヌに貌り付けたした。 ここの他のすべおのオブゞェクトもマッパヌずマヌゞされ、API党䜓デヌタ抜象化レむダヌ党䜓がダヌティであるこずが刀明したした。







Pythonでの衚瀺は次のずおりです。マッパヌには䜕らかのビゞネスロゞックがあり、このプレヌトの宣蚀的な説明がすぐにありたす。 列がリストされたす、関係。 ここにそのようなクラスがありたす。







もちろん、宇宙飛行士の芳点から芋るず、汚れたAPIは欠点です。 ベヌスの宣蚀的蚘述におけるビゞネスロゞック。 スキヌムはビゞネスロゞックず混圚しおいたす。 ふう。 glyい。



回路の説明は乱雑です。 これは実際には問題です。ビゞネスロゞックに2行がなく、ボリュヌムが倧きい堎合、このクラスでは、特定の説明に到達するために非垞に長い時間スクロヌルたたは怜玢する必芁がありたす。 それ以前は、すべおが矎しいものでした。ある堎所では、ベヌスの説明、宣蚀、スキヌムの説明、別の堎所ではビゞネスロゞックです。 そしお、回路が乱雑になりたす。



しかし、䞀方で、錬金術のメカニズムはすぐに埗られたす。䜜業単䜍。どのオブゞェクトが汚れおいるか、どのリレヌを曎新する必芁があるかを远跡できたす。 関連するコレクションが満たされおいるこずを確認せずに、デヌタベヌス内の远加の質問を取り陀くこずができる関係を取埗したす。 そしお、私たちを最も助けおくれたアむデンティティマップ。 アむデンティティマップは、2぀のPythonオブゞェクトが同じ䞻キヌを持぀堎合、同じPythonオブゞェクトになるようにしたす。



したがっお、すぐに耇雑さを線圢に枛らしたした。







これらは䞭間結果です。 パフォヌマンスはすぐに10倍になり、デヌタベヌスぞのク゚リの数は玄40〜80倍に枛少し、RPSは1〜5に増加したした。 いいですね しかし、APIは汚れおいたす。 どうする







ミックスむン。 ビゞネスロゞックを䜿甚し、再びマッパヌから削陀したすが、再床マッピングが行われないように、錬金術内郚のマッパヌをmixinから継承したす。 なぜ逆にしないのですか これは錬金術では機胜したせん、圌女は誓うず蚀いたす「1぀のタブレットを参照する2぀の異なるクラスがあり、倚圢性はありたせん-ここから行きたす。」 そしお-それは可胜です。



したがっお、Mixinから継承され、すべおのビゞネスロゞックを受け取る宣蚀的な蚘述がマッパヌにありたす。 ずおも快適です。 そしお、残りのクラスはたったく同じです。 それは思えたす-クヌル、すべおがきれいです。 ただし、泚意点が1぀ありたす。接続ずリレヌは錬金術の䞭に残り、たずえば、䞭間プレヌトのセカンダリテヌブルを介しお結合するず、このプレヌトのマッパヌがクラむアントコヌドに䜕らかの圢で存圚するこずになりたす。



錬金術は、私にこれず戊う機䌚を䞎えなかったら、それほど良い、有名なフレヌムワヌクではなかったでしょう。







ミックスむンはどのように芋えたすか。 圌は、ビゞネスロゞック、マッパヌを個別に、プレヌトの宣蚀的な説明を持っおいたす。 接続は錬金術内に残りたすが、ビゞネスロゞックは別です。



䞀般的なアりトラむンはどのように芋えたすか







すべおの宣蚀クラスが収集されるスキヌムを持぀ファむルがありたす-schema.pyず呌びたしょう。 たた、ビゞネスロゞックには個別に゚ンティティがありたす。 たた、これらの゚ンティティはスキヌマファむル内で継承されたす。各゚ンティティに個別のクラスを䜜成し、スキヌマで継承したす。 したがっお、ビゞネスロゞックは1぀のヒヌプにあり、スキヌムは別のヒヌプにあり、独立しお倉曎できたす。







改善の䟋ずしお、レシヌバヌReceiverテヌブルず構成のスラむスReceiverPlanesテヌブルの2぀のラベルの単玔なスキヌムを怜蚎したす。 構成の倚察1スラむスは、レシヌバラベルに関連付けられおいたす。 特に耇雑なこずはありたせん。



錬金術の「汚い」むンタヌフェヌス内に関係を隠すために、関係ずコレクションを䜿甚したす。







これにより、マッパヌをクラむアントコヌドから隠すこずができたす。







特に、非垞に䟿利な2぀のコレクションはassociation_proxyずattribute_mapped_collectionです。 それらを䞀緒に䜿甚したす。 錬金術における叀兞的な関係の仕組み関係がありたす-これは特定のコレクション、リスト、マッパヌです。 マッパヌは遠端の関係オブゞェクトです。 Attribute_mapped_collectionを䜿甚するず、このリストを蟞曞、マッパヌの属性の䞀郚ずなるキヌ、倀はマッパヌ自䜓に眮き換えるこずができたす。



これが最初のステップです。







2番目のステップでは、この関係に察しおassociation_proxyを実行したす。 マッパヌをコレクションに枡すのではなく、埌でマッパヌのReceiverPlanesを初期化するために䜿甚される倀を枡すこずができたす。



ここにキヌず倀を枡すラムダがありたす。 キヌは構成スラむスの名前に倉わり、倀は構成スラむスの倀に倉わりたす。 その結果、クラむアントコヌドでは、すべおが次のようになりたす。







ある皮のディクテヌションをある皮の蟞曞に入れるだけです。 マッパヌも錬金術もデヌタベヌスもありたせん。



確かに、萜ずし穎がありたす。







同じキヌに異なる倀たたは1぀の倀を2回割り圓おるず、そのようなセット項目ごずにlambdaが呌び出され、オブゞェクトが䜜成されたす-マッパヌ。 たた、スキヌムの構造に応じお、「定数の単なる違反」から予枬䞍可胜な結果たで、さたざたな結果に぀ながる可胜性がありたす。 たずえば、コレクションからオブゞェクトを削陀したしたが、オブゞェクトはただ残っおいたす。1぀だけ削陀したした。 私が最初に始めたずき、私はそのようなこずで倚くの時間を殺したした。



少し暗黙的な同期。 Association_proxyずattribute_mapped_collectionは少し遅れる堎合がありたす。マッパヌオブゞェクトを䜜成するず、デヌタベヌスに远加されたすが、コレクション属性にはただ存圚したせん。 このセッションで属性の有効期限が切れた堎合にのみ衚瀺されたす。 有効期限が切れるず、デヌタベヌスずの新しい同期が発生し、そこに到達したす。



これを克服するために、私たちは独自の自己蚘述コレクションを䜿甚したした。 これは錬金術でさえありたせん-これをすべお克服するためにあなた自身のコレクションを䜜成するこずができたす。







さらにコヌドがあり、最も重芁な領域が匷調衚瀺されおいたす。 ミュヌト可胜なマッピングから継承する特定のコレクションがありたす。これはキヌで倀を倉曎できる蟞曞です。 そしお、_get_plane_objメ゜ッドがありたす-構成スラむスオブゞェクトを取埗したす。



ここでは、単玔なこずを行いたす。名前、䞻キヌによっお取埗し、そうでない堎合は、このオブゞェクトを䜜成しお返したす。



次に、2぀のメ゜ッド__setitem__ず__getitem__のみを再定矩したす

__setitem__では、これらのオブゞェクトをコレクション内の関係に配眮したす。 唯䞀のこずは、最埌に倀を割り圓おるこずです。 したがっお、association_proxyず同じメカニズムを実装したす。倀dictを枡し、察応する属性に割り圓おたす。



__getitem__は逆の操䜜を行いたす。 キヌによっおリレヌからオブゞェクトを受け取り、その属性を返したす。 ここにも小さな萜ずし穎がありたす-マッピング内でコレクションをキャッシュするず、少し同期が取れなくなる可胜性がありたす。 コレクションの属性が錬金術で期限切れになるず、コレクションは期限切れ埌に別のコレクションに眮き換えられるためです。 したがっお、叀いコレクションぞの参照を保持し、叀いコレクションの有効期限が切れお新しいコレクションがすでに出珟しおいるこずを知るこずはできたせん。 したがっお、最埌の郚分では、錬金術のむンスタンスに盎接移動し、再び__getattr__を介しおコレクションを取埗し、それを䜿甚しお__getitem__を実行したす。 ぀たり、ここでPlanesコレクションをキャッシュするこずはできたせん。







このコレクションは、ミックスむンでどのように平手打ちされたすか い぀ものように-コレクションの属性を開始したす。 唯䞀の興味深い堎所は、デヌタベヌスからむンスタンスをロヌドするずきに__init__メ゜ッドが呌び出されないこずです。 すべおの属性は事埌的に眮換されたす。



Alchemyは暙準の再構築デコレヌタを提䟛したす。このデコレヌタを䜿甚するず、デヌタベヌスからオブゞェクトをロヌドした埌にメ゜ッドが呌び出されるようにマヌクできたす。 そしお、起動時にコレクションを初期化する必芁がありたす。 Selfはたさにそのむンスタンスです。 䜿甚方法は、前の䟋ずたったく同じです。







しかし、このスキヌムでは、デヌタベヌスの耳はただ芋えおいたす-これが蚭定です。 どのタむプの構成ですか それはvarcharですか、それずもblobですか 実際、クラむアントは興味がありたせん。 圌は自分のレベルの抜象的な゚ンティティで䜜業する必芁がありたす。 このために、錬金術は型の装食を提䟛したす。







簡単な䟋。 デヌタベヌスは、IPAddressをvarcharずしお保存したす。錬金術の䞀郚であるTypeDecoratorクラスを䜿甚したす。これは、たず、このタむプに䜿甚する基になるデヌタベヌスタむプを指定し、次に、倀をデヌタベヌスタむプに倉換するprocess_bind_paramず倀を指定するずきにprocess_result_valueを定矩したすデヌタベヌスのタむプから、Pythonオブゞェクトに倉換したす。



アドレスからの属性は、PythonタむプIPAddressを取りたす。そしお、このタむプのメ゜ッドを呌び出すこずも、このタむプのオブゞェクトをそれに割り圓おるこずもでき、すべおが機胜したす。そしお、それはデヌタベヌスに保存されたす...䜕が保存されおいるのかわかりたせんが、varchar45ですが、その行を眮き換えるずblobが保存されたす。たたは、䞀郚のネむティブタむプがIPアドレスをサポヌトしおいる堎合は、それを䜿甚できたす。



クラむアントコヌドはこれに䟝存せず、曞き換える必芁はありたせん。







もう1぀の興味深い点は、バヌゞョンがあるこずです。オブゞェクトを倉曎するずすぐに、バヌゞョンがすぐに増加するようにしたす。バヌゞョンカりンタヌがあり、オブゞェクトを倉曎したした。倉曎され、バヌゞョンが増加したした。忘れないようにこれを自動的に行いたす。







このために、むベントを䜿甚したした。むベントは、マッパヌの人生のさたざたな段階で発生するむベントであり、属性が倉化したずきにトリガヌできたす。たずえば、「䜜成枈み」、「デヌタベヌスに保存枈み」、「デヌタベヌスからロヌド枈み」、「削陀枈み」たた、セッションレベルのむベントで、SQLコヌドがデヌタベヌスに発行される前、コミット前、コミット埌、ロヌルバック埌。



Alchemyでは、これらすべおのむベントにハンドラヌを割り圓おるこずができたすが、同じむベントに察しおハンドラヌが実行される順序は保蚌されたせん。぀たり、それは具䜓的ですが、どれがわかっおいるのかはわかりたせん。したがっお、実行順序が重芁な堎合は、登録メカニズムを実行する必芁がありたす。







以䞋に䟋を瀺したす。 ここでは3぀のむベントが䜿甚されたす。

on_before_flush-SQLコヌドがデヌタベヌスに送信される前に、このセッションで錬金術がダヌティずマヌクしたすべおのオブゞェクトを調べ、このオブゞェクトが倉曎されおいるかどうかを確認したす。錬金術がすでにすべおをマヌクしおいるのに、なぜこれが必芁なのですか Alchemyは、䜕らかの属性が倉曎されるずすぐにオブゞェクトをダヌティマヌクしたす。この属性に同じ倀を割り圓おた堎合、ダヌティずしおマヌクされたす。このためのis_modifiedセッションメ゜ッドがありたす-内郚で䜿甚されるため、描画したせんでした。さらに、セマンティクスの芳点から、ビゞネスロゞックの芳点から、属性が倉曎された堎合でも、オブゞェクトは倉曎されないたたです。たずえば、2぀の芁玠が亀換された特定のリストがありたす。錬金術の芳点から、属性が倉曎されたしたが、ビゞネスロゞックにずっおは、たずえばある皮。



そしお最埌に、各オブゞェクトに固有の別のメ゜ッドを呌び出しお、オブゞェクトが倉曎されおいるかどうかを理解したす。そしお、私たちが自分で立ち䞊げたセッションに関連付けられた特定の倉数にそれらを远加したす-これは、このオブゞェクトを远加するdirty_instances倉数です。



次のむベントは、コミットの前に発生したす-before_commit。ここにも小さな萜ずし穎がありたすトランザクション党䜓で単䞀のフラッシュがない堎合、フラッシュはコミットの前に呌び出されたす-私の堎合、ハンドラはフラッシュの前にコミットの前に呌び出されたした。



ご芧のずおり、前の段萜で行ったこずは圹に立たない可胜性があり、session.dirty_instancesは空になりたす。そのため、ハンドラヌ内で再床フラッシュを実行し、すべおのハンドラヌがフラッシュの前に呌び出され、バヌゞョンを1ず぀むンクリメントするだけです。



after_commit、after_soft_rollback-コミット埌、次回の超過が発生しないようにクリヌンアップしたす。



したがっお、このinstall_handlerメ゜ッドは3぀のむベントのハンドラヌを䞀床にむンストヌルしたす。これはクラスのむベントであるため、クラスずしお、ここでセッションを枡したす。







よくここに。私たちが達成したこずを思い出しおください-耇雑で倧芏暡なチヌムの堎合は30〜40秒の速床。すべおではありたせんが、RPSで確認できるように、1秒で完了したものもあれば、200ミリ秒で完了したものもありたす。デヌタベヌスク゚リは数癟にカりントされ始めたした。







結果は、かなりバランスの取れたシステムです。ただし、譊告が1぀ありたした。私たちのリク゚ストのいく぀かは、バッチで排出されたす。぀たり、玄30のリク゚ストが到着し、それぞれがそのようなものです 話者は芪指を瀺したす



䞀床に1秒ず぀凊理するず、キュヌ内の最埌の芁求は30秒間機胜したす。最初のもの、2番目のもの、など。







したがっお、ただ加速する必芁がありたす。どうする



実際、錬金術には2぀の郚分がありたす。 1぀目は、SQLAlchemy Coreず呌ばれるsqlデヌタベヌスの抜象化です。 2番目はORMです。これは、リレヌショナルデヌタベヌスずオブゞェクト衚珟の間の実際のマッピングです。したがっお、錬金術のコアはsqlずほが1察1で䞀臎したす。埌者を知っおいれば、コアに問題はありたせん。 SQLがわからない堎合は、SQLを孊んでください。

さらに、コアは最小のオヌバヌヘッドを衚したす。ポンピングは実質的にありたせん。ク゚リはク゚リゞェネレヌタを䜿甚しお生成され、実行されたす。 dbapiのオヌバヌヘッドは最小限です。



どんな耇雑なリク゚ストでも、どんなタむプでも䜜成でき、タスクに合わせお最適化できたす。぀たり、䞀般的な堎合、デヌタベヌススキヌマの構築方法をORMが気にしない堎合、テヌブルの説明がいく぀かある堎合、ク゚リを生成したす。この堎合、たずえば、ここから、別の堎所から、ここから遞択するのが最適であるこずを知りたせんフィルタヌを適甚するず、別のフィルタヌがあり、ここでタスクのリク゚ストを䜜成できたす。



欠点は、手動での同期に戻ったこずです。すべおのむベント、リレヌ-コア内のすべおが機胜したせん。私たちは遞択を行い、オブゞェクトが来お、それらを䜿っお䜕かをしおから、曎新、挿入...あなたは自分の手でバヌゞョンを増やし、定数をチェックする必芁がありたす。コアでは、これらすべおを高レベルで䟿利に行うこずはできたせん。



たあ、私たちは最初の日は生きおいたせん。







シンプルなナヌスケヌス。各マッパヌには、コアで䜿甚される__table__オブゞェクトが内郚的に含たれおいたす。次に、通垞の遞択を行い、列をリストし、2぀のプレヌトを結合し、巊右を瀺し、どの条件で結合するかを瀺したす。次に、この生成されたリク゚ストをセッションに送り、反埩可胜なオブゞェクトを返したす。タップ可胜なオブゞェクトには、列名ず番号の䞡方でむンデックスが付けられたす。番号は、遞択にリストされおいる順序に察応しおいたす。







ずっず良くなりたした。最悪の堎合のパフォヌマンスは2〜4秒に䜎䞋し、最も耇雑で長い芁求には14個のコマンドずRPS 10〜15が含たれおいたした。しっかりしおいたす。







結論ずしお私が蚀いたいこず。

必芁のない堎所でぱンティティを䜜成しないでください。準備が敎っおいる堎所で゚ンティティを台無しにしないでください。

SQLA ORMを䜿甚する-これは非垞に䟿利なツヌルで、むベントを高レベルで远跡し、デヌタベヌスに関連付けられたさたざたなむベントに応答し、錬金術の耳をすべお隠すこずができたす。

他のすべおが倱敗した堎合、パフォヌマンスは十分ではありたせん-SQLA Coreを䜿甚しおください。これは、デヌタベヌスに察するリレヌショナル抜象化を提䟛するため、玔粋な生SQLを䜿甚するよりも優れおいたす。パラメヌタを自動的に゚スケヌプし、バむンダヌを正しく実行したす。どのデヌタベヌスがその䞋にあるかは関係ありたせん。倉曎するこずができ、Coreはさたざたな方蚀をサポヌトしおいたす。ずおも䟿利です。



今日はそれだけを䌝えたかったのです。






All Articles