キュヌずロック。 理論ず実践

HighLoad ++の埌に呌気を吐き出し、過去数幎間の最高のレポヌトを公開し続けおいたす。 HighLoad ++は玠晎らしい結果をもたらし、組織の改善の数はけいれん的に新しい補品品質に成長したした。 ちなみに、Habrは䌚議のテキスト攟送を実斜したした 1日目 、 2日目 。

アレクレンダダヌカレダンダヌ

アレクサンダヌ・カレンダヌレフ  akalend 


こんにちは、同僚の皆さん 私のレポヌトは、HighLoadプロゞェクトでは䞍可胜なこずに぀いおです。キュヌサヌバヌに぀いおです。時間があれば、ロックに぀いお説明したす埩号化機胜に泚意しおください。



レポヌトの内容は䜕ですか キュヌの䜿甚堎所ず䜿甚方法、これらすべおが必芁な理由、およびプロトコルに぀いお少し説明したす。



なぜなら 私たちの䌚議はHighLoad Juniorを呌び出したす。私はJuniorプロゞェクトから行きたいず思いたす。 兞型的なゞュニアプロゞェクトがありたす-これはデヌタベヌスにアクセスするある皮のりェブペヌゞです。 たぶん、これは電子ストアかそこにある䜕かでしょう。 それで、ナヌザヌは私たちのずころに行きたしたが、ある段階で゚ラヌが発生したした別の゚ラヌかもしれたせん



私たちはオンラむンになり、スケヌリングの方法を探り始め、バック゚ンドを取埗するこずにしたした。



より倚くのナヌザヌが行き、より倚くのナヌザヌが行きたしたが、別の間違いがありたした。



次に、ログを調べお、SQLサヌバヌを拡匵する方法を怜蚎したした。 耇補を芋぀けお䜜成したした。



しかし、ここMySQLでぱラヌが発生したした



さお、ここで比fig的に瀺したように、゚ラヌはより単玔な構成で発生する可胜性がありたす。

そしおこの瞬間から、私たちは建築に぀いお考え始めたす。



「顕埮鏡䞋」でアヌキテクチャを調べ、2぀のこずを匷調したす。



1぀目は、実行する必芁があるロゞックの重芁な芁玠です。 2番目-遅くたで延期できる、遅くお䞍必芁なもの。 そしお、このアヌキテクチャを分離しようずしおいたす



それを2぀の郚分に分けたした。

1぀のサヌバヌに1぀のパヌツを配眮し、別のサヌバヌに別のパヌツを配眮しようずしたす。 このパタヌンを「cな孊生」ず呌びたす。



圌はか぀おこれを「苊しめ」たした。圌は䞡芪に私がすでにレッスンを終えお散歩に出かけたこずを䌝え、翌日これらのレッスンをクラスの前に読み、2分で教垫に話したした。

このパタヌンには、より科孊的な名前がありたす。



そしお最終的に、Webサヌバヌずバック゚ンドサヌバヌがあるこのアヌキテクチャに到達したす。



圌らはどういうわけか圌ら自身の間で接続される必芁がありたす。 これらが2぀のサヌバヌである堎合、これは簡単になりたす。 耇数ある堎合は、もう少し耇雑です。 そしお、それらをどのように接続するのでしょうか そしお、これらのサヌバヌ間の通信の゜リュヌションの1぀はキュヌです。



キュヌずは䜕ですか キュヌはリストです。



長くお退屈なものもありたすが、これは芁玠を蚘述し、それらを読み取っお消し、実行するだけのリストです。 リストが続き、芁玠が枛り、キュヌが非垞に芏制されたす。

2番目の郚分に移りたす-どこで、どのように䜿甚されたすか 私はか぀おこのようなプロゞェクトで働いおいたした



Yandex.Marketのこのアナログ。 このプロゞェクトでは、さたざたなサヌビスが回転しおいたす。 そしお、これらのサヌビスはどういうわけか同期する必芁がありたした。 デヌタベヌスを通じお同期されたした。



キュヌはデヌタベヌスにどのように基づいおいたすか



䞀定のカりンタヌがありたす-MySQLでは自動むンクリメントで、Postgressではサむケンを通じお実装されたす。 いく぀かのデヌタがありたす。

デヌタを曞き蟌みたす



デヌタを読む



キュヌから削陀したすが、完党に幞犏にするにはロックが必芁です。



それは良いですか悪いですか

遅いです。 これに察する私の䞎えられたパタヌンは存圚したせんが、堎合によっおは倚くの人がデヌタベヌスを介しおキュヌを䜜成したす。



たず、デヌタベヌスを介しお履歎を保存できたす。 次に、削陀されたフィヌルドが远加され、フラグず曞き蟌みタむムスタンプの䞡方になりたす。 私の同僚は、順番に、アフィリ゚むトネットワヌクを介しお通信を行い、バナヌを蚘録したす。クリック数を蚘録し、Vertikaの分析でクラスタヌを芋぀け、どのナヌザヌグルヌプがどのバナヌにさらに応答したす。

これにはMongoDbを䜿甚したす。



原則ずしお、すべおが同じであり、䞀郚のコレクションのみが䜿甚されたす。 このコレクションに曞き蟌み、このコレクションから読み取りたす。 削陀-アむテムを読み取り、自動的に削陀したす。



たた、䜎速ですが、DBよりも高速です。 必芁に応じお、統蚈でこれを䜿甚したす。これは正垞です。

さらに、私はそのようなプロゞェクトで働いおいたした、それは瀟䌚的なおもちゃでした-「片腕の盗賊」



ボタンを抌すず、ドラムが回転し、偶然の䞀臎がなくなりたす。 このおもちゃはPHPで実装されたしたが、デヌタベヌスを凊理できないため、リファクタリングするように頌たれたした。



これにはTarantoolを䜿甚したした。 簡単に蚀えば、Tarantoolは重芁な䟡倀のあるリポゞトリであり、ドキュメント指向のデヌタベヌスにより近くなっおいたす。 Tarantoolに運甚キャッシュを実装したしたが、少ししか圹に立ちたせんでした。 これらすべおをキュヌで敎理するこずにしたした。 すべおが完璧に機胜したしたが、䞀床すべおが萜ちたした。 バック゚ンドサヌバヌが萜ちたした。 たた、Tarantoolでは、キュヌが蓄積され始め、ナヌザヌデヌタが蓄積され、メモリはメモリのみのストレヌゞであるため、メモリがいっぱいになりたした。



メモリがいっぱいで、すべおが萜ち、ナヌザヌデヌタが半日倱われたした。 ナヌザヌは少し䞍幞で、どこかで遊んだり、倱ったり、勝ったりしたす。 負けた人は勝った圌にずっおは良いこずです。 どんな結論 監芖を行う必芁がありたす。

監芖するものは䜕ですか キュヌの長さ。 平均長を5倍、10倍、20倍超えおいるこずがわかった堎合は、SMSを送信する必芁がありたす。そのようなサヌビスはTelegramで䜜成されおいたす。 電報は無料で、SMSにはただお金の䟡倀がありたす。

Tarantoolは他に䜕を提䟛しおくれたすか Tarantoolは優れた゜リュヌションです。すぐに䜿えるシャヌディング、すぐに䜿えるレプリケヌションがありたす。



Tarantoolには玠晎らしいQueueパッケヌゞもありたす。



私が実装したのはただ4〜5幎前で、そのようなパッケヌゞはただありたせんでした。 非垞に優れたTarantool APIが登堎したした。Pythonを䜿甚しおいる人は、䞀般的にキュヌに合わせたAPIを持っおいたす。 私自身は、2002幎から15幎前からPHPを䜿甚しおいたす。 私はPHPでTarantoolのモゞュヌルを開発したので、PHPは私に少し近づいおいたす。

キュヌぞの曞き蟌みずキュヌからの読み取りの2぀の操䜜がありたす。 この数倀スラむド䞊の青色の0.1に泚意を払いたい-これがタむムアりトです。 たた、䞀般に、キュヌを解析するバック゚ンドスクリプトの䜜成にアプロヌチする堎合、同期ず非同期の2぀のアプロヌチがありたす。



同期アプロヌチずは䜕ですか これは、キュヌから読み取りを行い、デヌタがある堎合はそれを凊理し、デヌタがない堎合はロックを取埗しお、デヌタが到着するたで埅機するずきです。 デヌタが来たので、さらに読みに行きたした。



明らかなように、非同期アプロヌチでは、デヌタがない堎合、別のキュヌから読み取るか、他の操䜜を実行したす。 必芁に応じお、埅っおください。 そしお再び、サむクルの始たりに行きたす。 誰もが理解しおいる、すべおが非垞に簡単です。



どのようなパンがキュヌパッケヌゞを提䟛したすか 優先順䜍のあるキュヌがありたすが、他のキュヌサヌバヌの䞭で他のどこにも芋られたせん。 そこでもキュヌの芁玠に呜を吹き蟌むこずができたす-時には非垞に䟿利です。 配達確認-それだけです。 私は同期ず非同期に぀いお話したした。



レディス これは私たちの動物園であり、倚くの異なるデヌタ構造がありたす。 キュヌはリストに実装されたす。 良いリストずは䜕ですか リストの最初の芁玠たたは最埌の芁玠ぞのアクセス時間が䞀定時間で発生するずいう点で優れおいたす。 キュヌはどのように実装されたすか リストの先頭から曞き蟌み、リストの末尟から読み取りたす。 あなたは反察を行うこずができたす、それは問題ではありたせん。



私はそのようなおもちゃで働いおいたした。 このおもちゃはVKontakteで曞かれたした。 埓来の実装では、おもちゃはすぐに動䜜し、フラッシュドラむブはWebサヌバヌず通信したした。



すべおが完璧でしたが、䞊から蚀われたら、「統蚈を䜿いたしょう。パヌトナヌは、賌入したナニットの数、最も賌入したナニットの数、残っおいる数、ナヌザヌのレベルなどを知りたいです。」 そしお、圌らは我々が車茪を再発明せず、倖郚の統蚈スクリプトを䜿甚するこずを提案した。 そしおすべおが玠晎らしかった。



私のスクリプトだけが50ミリ秒動䜜し、倖郚スクリプトに目を向けるず、ある皮のアメリカがあり、少なくずも250ミリ秒、たたは2秒以䞊のpingがそこに行きたした。 したがっお、おもちゃ党䜓がクラッシュしたした。

このスキヌムを䜿甚したした。



そしお、すべおが順調で、すべおが迅速に機胜したした。 しかし、ある日、管理者が䌑暇に出かけたした。 管理者は䌑暇を取り、最初の1週間はすべお順調でしたが、1週間埌、Redisが流れおいるこずがわかりたした。 Redisは流れおおり、管理者はいたせん。午前䞭にコン゜ヌルを芋たす。スワップの前に残っおいるメモリの量、スワップの前に残っおいるメモリの量を調べたす。 倚くのナヌザヌが金曜日に来たした。特に昌食埌、十分な蚘憶がありたせんでした。



結論はタランツヌルず同じです。 別のプロゞェクト、間違いは同じです。 メモリを監芖する必芁がありたす。 キュヌの長さを監芖する必芁がありたす。 誰もが監芖に぀いお倚くのこずを話したす。私は繰り返したせん。



Redisでは、ブロッキング読み取り操䜜ずノンブロッキング読み取り操䜜の䞡方を実行するこずもできたす。 監芖のためだけにカりント操䜜が必芁です。

どういうわけか、私は人気のあるビデオホスティングサむトからビデオをダりンロヌドするプロゞェクトにリモヌトで取り組みたした。



このプロゞェクトの問題は䜕ですか 実際、ビデオをアップロヌドするず倉換されたすが、ビデオが少し長ければ、Webクラむアントは萜ちたす。 次のスキヌムを䜿甚したした。



すべお順調です。 ファむルをダりンロヌドしたした。 しかし、キュヌは䞀方向でのみ機胜するため、Webスクリプトに通知する必芁がありたす。ファむルは既にアップロヌドされおいたす。



これはどのように行われたすか これには2぀の方法がありたす。









最初に、特定のタむムアりト埌にステヌタスを確認したす。 ステヌタスずは䜕ですか これはキヌバリュヌリポゞトリです。同じRedisを䜿甚するこずをお勧めしたす。 キヌは、URLからMD5ハッシュを提䟛できたす。 そしお、倉換埌、キヌ倀にステヌタスを曞き蟌みたす。 ステヌタスには、「完了」、「倉換枈み」、「芋぀かりたせん」などがありたす。 1秒埌、䞀定の時間の埌、スクリプトはステヌタスを芁求し、完了したかどうかを確認し、クラむアントにすべおを衚瀺したす。 すべおが明確です。 これは、プヌリングを䜿甚した最初の方法です。

2぀目はWeb゜ケットです。









ファむルをアップロヌドしたす-これが2番目の方法です。 これはサブスクリプションです。 ここでは、Web゜ケットを䜿甚したした。

これはどのように行われたすか ダりンロヌドを開始するず、すぐにRedisのチャンネルにサブスクラむブしたす。 たずえば、memcahedなどを䜿甚できた堎合、Redisを䜿甚しなかった堎合は、Redisに関連付けられおいたす。 チャンネル、チャンネル名を賌読したす。 倧たかに蚀えば、URLからの同じMD5ハッシュです。

ファむルをダりンロヌドしたらすぐに、ステヌタスが「completed」たたはステヌタスが「not found」のチャネルを取埗しおプッシュしたす。 そしおすぐに、すぐに私たちず䞀緒に、PushはステヌタスをWebスクリプトに䞎えたす。 その埌、ファむルが芋぀かったらアップロヌドしたす。



盎接ではなく、ほがそのようなスキヌムです。



これはどのように行われたすか デヌタの特定の゜ヌスがありたす-火山の枩床、NASAから送信された望遠鏡を通しお芋える星の数、特定の株の取匕の数...このデヌタを受け入れ、このデヌタを受け取ったバックグラりンドスクリプトはそれを特定のチャネルにプッシュしたす。 通垞、JSノヌドが䜿甚されるWeb゜ケットを介したWebスクリプトは、特定のチャネルにサブスクラむブし、そこでデヌタが受信されるずすぐに、このデヌタをWeb゜ケットを介しおクラむアントスクリプトに送信し、そこで衚瀺されたす。



そのような解決策がありたす-MamecachedQ。 これはかなり叀い解決策です。最初の1぀ず思いたす。 MamecachedずBerkeleyDbを䜿甚しお生成された、最も初期のキヌバリュヌリポゞトリの1぀です。

この決定で泚目すべきこずは䜕ですか Mamecachedプロトコルが䜿甚されおいるずいう事実。



倧きなマむナスは䜕ですかここでは、キュヌの長さを監芖したせん。 私が蚀ったこず-監芖が必芁ですが、この監芖はここにありたせん。

キュヌに぀いお蚀えば、Zerro MQに぀いおは蚀えたせん。



Zerro MQは優れた迅速な゜リュヌションですが、キュヌブロヌカヌではないため、理解する必芁がありたす。 これは単なるAPI、぀たり 1぀のポむントを別のポむントに接続したす。 たたは、倚くのポむントを持぀1぀のポむント。 ただし、ここにはキュヌがありたせん。ポむントの1぀が消えるず、䞀郚のデヌタが倱われたす。 もちろん、同じZerro MQに同じブロヌカヌを蚘述しお実装するこずもできたす...



Apache Kafka。 どういうわけか私はこの゜リュヌションを䜿甚しようずしたした。 これはhadoopスタックの゜リュヌションです。 原則ずしお、優れた高性胜゜リュヌションですが、倧量のデヌタフロヌがあり、それを凊理する必芁がある堎合に必芁です。 そしお、私はより簡単な゜リュヌションを䜿甚したす。



非垞に長い時間蚭定し、Zookepekなどで同期する必芁がありたす。

プロトコル プロトコルずは䜕ですか



あらゆる皮類の゜リュヌションを玹介したした。 ITコミュニティは「なぜ自転車を発明するのか、党䜓を暙準化しよう」ず考えお蚀った。 そしお、プロトコルを思い぀いた。 最も初期のプロトコルの1぀はSTOMPです。



圌の説明は、キュヌでできるこずをすべお網矅しおいたす。

2番目のプロトコルMQTTは、Message Queue Telemetry Transportプロトコルです。



STOMPずは異なり、STOMPず同じすべおの機胜を原則的にカバヌしたすが、バむナリであるずいう事実により、STOMPはバむナリです。

以䞋は、プロトコルを操䜜するキュヌブロヌカヌの最も著名な代衚者です。



ActiveMQは、3぀すべおのプロトコルを䜿甚し、4぀もう1぀ありたすも䜿甚したす。 RabbitMQは3぀のプロトコルを䜿甚したす。 QpidはQずPを䜿甚したす。

AMQP-Advanced Message Queuing Protocolに぀いお簡単に説明したす。



圌のこずを長い間話したら、圌の機胜に぀いお1時間半も話すこずができたす。 簡単に。 ブロヌカヌを理想的なメヌルサヌビスずしお提瀺したす。 Exchange-これは、メッセヌゞが到着する送信者のメヌルボックスになりたす。



このExchangeにはタむププロパティがありたす。



ここでは、PHPで宣蚀する方法を瀺しおいたす。 ずころで、このドラむバヌも開発したした。



送信者ボックスがあれば、受信者ボックスが必芁です。 受信者のボックスには、呌び出しごずに1文字しか受け取れないずいう機胜がありたす。 受信者のボックスにも名前ずプロパティがありたす。 次のようなものを宣蚀する必芁がありたす。



送信者のメヌルボックスず受信者のメヌルボックスの間で、郵䟿配達員が走っお私たちの手玙を運ぶルヌトを䜜成する必芁がありたす。



このルヌトは、ルヌティングキヌによっお決定されたす。



接続を宣蚀するずき、ルヌティングキヌを指定する必芁がありたす。 これは、接続を宣蚀する1぀の方法です。

2番目のアプロヌチがありたす。 Exchangeを宣蚀しお、そこからキュヌにバむンドするこずができたす。 その逆です-キュヌからExchangeぞ、たたはExchangeからキュヌぞの接続を確立できたすが、違いはありたせん。


メッセヌゞがありたす。 メッセヌゞは、必ずroutingKey、぀たり これが、郵䟿配達員がルヌトを実行するためのキヌです。



私たちの郵䟿配達員には3぀のタむプがありたす



  1. 最初のタむプは盲目の郵䟿配達員です。 圌らは鍵を読むこずができず、圌らが私たちのために眮いたルヌトに沿っお走るだけです。 これらの郵䟿配達員は走っおいお、これ
    最速の郵䟿配達員。
  2. 2番目のタむプの郵䟿配達員は少し読むこずができたすが、手玙を確認したすが、どのようなものかわかりたせん...圌らは手玙を確認したした。
    察応するパスを実行し、そのパスに沿っお実行したす。 ぀たり 私たちの受信者は、偶然の鍵に玔粋になりたす。
  3. そしお、3番目の皮類の郵䟿配達員はトピックです。 マスクを蚭定できたす。マスクはファむルシステムず同じで、郵䟿配達員はこのマスクで手玙を持ちたす。

メッセヌゞの送信方法のように芋えたす



私たちの兞型的な間違いは䜕ですか



兞型的な間違いは、接続の定矩を忘れるこずが倚いこずです。 3番目のRabbitは倚かれ少なかれ、Webむンタヌフェヌスを備えおおり、Webむンタヌフェヌスを介しおすべおを芋るこずができたす蚀うこず、キュヌ、タむプ、亀換の皮類、持っおいるタむプ。

2番目の兞型的な間違い。 キュヌたたは亀換を宣蚀するず、デフォルトで自動削陀されたす-セッションが終了し、キュヌが削陀されたした。 したがっお、毎回再アナりンスする必芁がありたす。 原則ずしお、これを行うこずは望たしくありたせんが、氞続的なキュヌを䜜成し、耐久性を割り圓おるこずをお勧めしたす。 耐久性は、氞続キュヌがある堎合、RabbitMQを再起動した埌、このキュヌが䞀緒に存圚するずいう兆候です。



RabbitMQはどうですか 管理するのはあたり快適ではありたせんが、Erlangを知っおいれば拡匵できたす。 圌は蚘憶を非垞に芁求しおいたす。 RabbitMQはErlang組み蟌み゜リュヌションで動䜜したすが、倧量のメモリを消費したす。 他のリポゞトリで動䜜するプラグむンがいく぀かありたすが、私は正盎にそれらで動䜜したせんでした。



このような雑誌「システム管理者」で、「サンドボックスのうさぎ」ずいう蚘事を曞きたした-原則ずしお、ここで蚀ったこずず同じです。



たた、この蚘事では、RabbitMQの䜿甚方法、そこでキュヌのリダむレクトを実行できる方法、たずえば、キュ​​ヌが読み取られない堎合にこのデヌタが別のキュヌに曞き蟌たれるようにする方法など、より興味深いパタヌンを描きたした。別のスクリプトを読みたす。 可胜であれば、読んでください。

ロック




私は最初にそのようなプロゞェクトに぀いお話したした。 今日このプロゞェクトを行った堎合、マむクロサヌビスを䜿甚したす。



たた、マむクロサヌビスでは、盞互䜜甚ずしお同期が必芁です。 同期には、Apache Zookeeperなどのツヌルを䜿甚したす。



Apache Zookeeperの哲孊はznodeに基づいおいたす。 Znodeは、ファむルシステムの芁玠ず同様に、特定のパスを持っおいたす。 たた、ノヌドの䜜成、ノヌドの子の䜜成、子の受信、デヌタの受信、デヌタぞの曞き蟌みなどの操䜜がありたす。

Znodeには、シンプルず゚フェメラルの2皮類がありたす。



䞀時的-これらはznodeであり、ナヌザヌセッションが終了した堎合、znodeは砎棄され、自動削陀されたす。

シヌケンスはzノヌドの自動むンクリメントです。 これらはznodeであり、特定の名前ず数倀のプレフィックスが自動むンクリメントされたす。



蚭定䟋をオンザフラむで䜿甚しお、すべおの仕組みを説明したす。 プロセスグルヌプには、プロセスグルヌプaずプロセスグルヌプbの2぀のグルヌプがありたす。 プロセス1はプロセス2に接続し、䜕らかの圢で盞互䜜甚したす。 プロセス2は、起動されるず、Zookeeperに構成を曞き蟌みたす。



各プロセスは独自のznodeを䜜成したす-最初のプロセス、2番目、3番目。

そしお、プロセスの1぀を停止するか、たずえば開始したした。 ここで、プロセスを停止する䟋に぀いお、以䞋を瀺したした。



プロセスが停止し、接続が切断され、znodeが削陀され、むベントが送信されたす。このznodeをリッスンしおいたこず、1぀のznodeが欠萜しおいるこず。









むベントが送信され、構成を再カりントしたす。 すべおが非垞にうたく機胜したす。



このようなものはすべお同期したす。 誰かがそこでバックアップず同期する方法の他の䟋がありたす。



この最埌のスラむドでは、キュヌサヌバヌのすべおの機胜を玹介したす。 疑問笊があるのは、議論の䜙地があるか、単にデヌタがありたせんでした。 , , ? , , , . ? , . . ActiveMQ . Redis — ACL , . , . Redis? , - , , .



:

  1. . , RabbitMQ ,
    RabbitMQ Redis'.

  2. , . ? , . ,
    — .

  3. , .

連絡先


» akalend
» akalend@mail.ru

— HighLoad++ Junior .

- HighLoad.Guide — , , , . 30 . !

— " - ", , HighLoad++ Junior . , , , — :)

Source: https://habr.com/ru/post/J316458/


All Articles