アーキテクチャの進化:「自己作成」サービスからHandlerSocketへ





今日は、Badooがロードされた「キーバリュー」サービスを設計するアプローチをどのように変えたかについてお話します。 このようなサービスが数年前に私たちによって作成されたスキーム(データベースをリポジトリとして使用し、特殊なデーモンをデータへのインターフェイスとして使用)、これで遭遇した困難、および結果としてどのアーキテクチャが出現し、出現した問題を解決するかについて学びます。



現代のインターネットプロジェクトは、キーによる値へのアクセスを許可する内部サービスを積極的に使用しています。 既製のソリューションまたは社内開発のいずれかです。 2006年以来、Badooのスペシャリストは、次のような多くのサービスを作成しています。





その多様性にもかかわらず、統一された設計アプローチが適用され、それに応じて、サービスは次のコンポーネントで構成される必要があります。

  1. データの参照バージョンを格納するリポジトリデータベース。
  2. データ要求を処理し、リポジトリデータベースと共に更新される高速のCまたはC ++デーモン。
  3. デーモンおよびリポジトリベースでの作業を提供するPHPクラス。


いずれのサービスでも多数の同時リクエストを処理できることが重要だったため、1つのMySQLのみに基づくソリューションは適切ではありませんでした。 ここから、追加のコンポーネントが高速デーモンの形で登場しました。これは、memcachedシステムで置き換えることができませんでした。 特定のデータインデックスを使用する必要がありました。



2010年の終わりに、 日本の職人によって書かれたHandlerSocket MySQLプラグインは、MySQLに保存されたデータへのインターフェースをNoSQLに提供しました。 すでに2011年春に、Badooのスペシャリストは、同社の「キーバリュー」サービスの開発とサポートを簡素化することを期待して、新しい技術に注意を向けました。



「最初の犠牲者」



新しい友達を検索するネットワークで、Badooは電子メールでさまざまな通知を受け取る膨大な数のユーザーを登録しました。 そして、これらの各ユーザーは、受け取りたい通知の種類を選択する機会があります。 したがって、メール設定をどこかに保存し、このデータへのアクセスを提供する必要があります。 それらに対する要求の99%以上が読み取り要求です。 主な「リーダー」は、スクリプトジェネレーターと電子メールの送信者です。これらは、これらのデータに基づいて、特定の種類の通信を特定のユーザーに送信する可能性または不能を決定します。 最初は、データベースのみがデータの保存に使用されていましたが、増え続ける読み取り要求に対処することはなくなりました。 この負荷を取り除くために、特別なデーモンが作成されました-EmailNotification。



「古い学校」サービスの実装



サービスの重要なコンポーネントはCデーモンで、これはすべての設定をメモリに保存し、TCPを介した最も単純なプロトコルを介して読み取りおよび書き込みアクセスを提供します。 さらに、このデーモンはヒット統計を収集し、その統計に基づいてグラフを作成しました。



最初は、サービスのアーキテクチャは非常にシンプルで、次のようになりました。





設定は常に1つのDBサーバー上のデータベースに保存され、Cデーモンは別のDBサーバーで機能していました。 開始時に、デーモンはデータベースからすべてのデータを選択し、それにインデックス( judy配列 )を構築しました。 初期化プロセスには約15分かかりましたが、この操作はサービスが存在する間数回しか必要なかったため、大きな欠点ではありませんでした。 このプロセスでは、クライアント(CLIスクリプト、Webおよびその他のサービス)は特別なAPIを介してデーモンにアクセスしました。たとえば、このユーザーにこのレターを送信できるかどうかを尋ね、デーモンは組み込みロジックを使用してメモリ内の設定を探し、回答を発行しました。 「ライタクライアント」は、特定のユーザーの特定の設定を変更するようデーモンに指示しました。



MySQLにデータを書き込むタスクは、完全にEmailNotification APIの責任でした。 同時に、たとえば、レコードがデータベースに正常に渡されたがデーモンには行かなかった場合、またはその逆の場合に、データ同期が発生する可能性があります。 しかし、このサービスはうまくいきました。 2007年まで、Badooには「小さなトラブル」がありました。つまり、第1から地理的に離れており、新世界のユーザーにサービスを提供するように設計された2番目のデータセンターが現れました。 新しいサイトでのアーキテクチャソリューションの通常の複製は不要であることがすぐに明らかになりました。 同じユーザーへの手紙は両方のサイトから送信できるため、両方のサービスが同じデータを操作する必要があります。



幸いなことに、特にそのような場合には、会社にはCPQイベントのシステム(CPQ-クロスプラットフォームキュー、クロスプラットフォームキュー-おおよその作成者)があります。 その結果、2つのサイトで、サービスアーキテクチャは次の形式を取りました。





これで、書き込み要求はローカルサイトのベースとCデーモンだけでなく、CPQにも送信されました。 CPQはリクエストを別のサイトの隣接するキューに送信し、同じサイトのEmailNotification APIを介して録音リクエストを既に再生しました。



システムはより複雑になりましたが、それでも数年間安定して動作し続けました。 また、サイトにデータの不一致がなければ、すべてうまくいきます。 利用可能なサイトの2つのベースには、異なる数の設定がありました。 そして、その差は0.1%未満でしたが、「清潔さとセキュリティ」という感覚はなくなりました。 さらに、違いはサイトのベース間だけでなく、同じサイト内のベースとC-demonの間にも存在することがわかりました。 サービスの信頼性を高める方法について考えなければなりませんでした。



新しいアプローチ



最初は、EmailNotificationサービスには2つの基本的な要件がありました。1つ目は、読み取り要求の処理速度が高速で、Cデーモンが非常にうまく機能したことです。 2番目は、問題が発生した両方のサイトのデータのIDです。 同期に苦労する代わりに、単純化のパスに従って、サービスのアーキテクチャを完全にやり直すことにしました。





まず、HandlerSocketプラグインをMySQLに接続し、APIを使用してデータベースを操作するように教えました。 これにより、C-demonの使用を拒否することができました。 次に、APIを簡素化して、CPQサービスをスキームから削除し、サイト間で確立された「マスター/マスター」レプリケーションに置き換えました。 その結果、非常にシンプルで信頼性の高い回路が得られ、次の利点があります。

  1. レプリケーションは透過的であり、内部CPQサービスで機能するコードは必要ありません。 同時に、サイト間の更新の転送の遅延は、数秒から数分の1秒に減少しました。
  2. 原子データの記録(最終的に!)。 HandlerSocketに書き込むためのEmailNotification APIリクエストが正常に完了した場合、タスクは完了し、記録は別のサイトに正確に複製されます。他のコンポーネントに通知する必要はありません。


新しいスキームへの切り替えに問題がありましたか? 深刻なものはありません。 AUTO_INCREMENTはHandlerSocketプラグインですでにサポートされており、複合インデックスも機能し、ENUMも同様に、タイムスタンプフィールドの1つに対してCURRENT_TIMESTAMPデフォルト値を放棄する必要がありました。



ご存じのように、HandlerSocketの利点は作業速度にありません-印象的というよりは許容範囲内ですが、単位時間あたりの多数のリクエストの下で安定して動作する能力にあります。 現在、このサービスは1つのサイトで1秒あたり2〜2.5千のリクエストのみを処理することを考慮すると、大きな安全マージンがあります。



しかし、HandlerSocketプラグインの速度に特に関心がある人のために、3つのコマンドの平均実行時間のグラフを示します。HandlerSocketへの接続、インデックスのオープン、およびそのデータの選択(ミリ秒単位のY軸の値):





最後の言葉



過去1年間、BadooはHandlerSocketを永続的なデータストレージを備えた「キーバリュー」リポジトリとして使用する傾向がありました。 これにより、よりシンプルで理解しやすいコードを記述でき、Cプログラマーが簡単な作業を行う必要がなくなり、サポートが大幅に簡素化されます。 そして、すべてがこの方向への動きが続くと言います。



しかし、Badoo内でHandlerSocketを使用するのは最も単純なタスクに限定されるとは思わないでください。 たとえば、録音機能の優位性に関する問題を解決するためにこれを使用した豊富な経験があり、多くのニュアンスが非常に重い負荷の下で表示されます。 詳細に興味がある場合は、コメント、質問をしてください。新しいトピックでこのトピックを継続します。



よろしくお願いします!



All Articles