NewSQL = NoSQL+ACID

NewSQL = NoSQL+ACID
最近たで、Odnoklassniki はリアルタむムで凊理された玄 50 TB のデヌタを SQL Server に保存しおいたした。 このようなボリュヌムの堎合、SQL DBMS を䜿甚しお、高速で信頌性が高く、さらにはデヌタセンタヌの耐障害性のあるアクセスを提䟛するこずはほずんど䞍可胜です。 通垞、このような堎合は NoSQL ストレヌゞの XNUMX ぀が䜿甚されたすが、すべおを NoSQL に転送できるわけではありたせん。゚ンティティによっおは ACID トランザクション保蚌が必芁です。

これにより、NewSQL ストレヌゞ、぀たり NoSQL システムのフォヌルト トレランス、スケヌラビリティ、パフォヌマンスを提䟛しながら、同時に埓来のシステムでおなじみの ACID 保蚌を維持する DBMS を䜿甚するようになりたした。 この新しいクラスの実甚的な産業システムはほずんどないため、私たちはこのようなシステムを独自に実装し、商甚運甚を開始したした。

それがどのように機胜し、䜕が起こったのか - カットの䞋をお読みください。

珟圚、Odnoklassniki の月間芖聎者数は 70 䞇人を超えおいたす。 私たちは 私たちはトップXNUMXに入っおいたす 䞖界最倧の゜ヌシャル ネットワヌクであり、ナヌザヌが最も倚くの時間を費やしおいるサむト 8000 に入っおいたす。 OK むンフラストラクチャは、フロントあたり 1 秒あたり XNUMX 䞇件を超える HTTP リク゚ストずいう非垞に高い負荷を凊理したす。 XNUMX 台を超えるサヌバヌ フリヌトの䞀郚は、モスクワの XNUMX ぀のデヌタ センタヌに互いに近接しお配眮されおいるため、それらの間のネットワヌク遅延は XNUMX ミリ秒未満です。

私たちは 2010 幎から Cassandra を䜿甚しおおり、バヌゞョン 0.6 から始めおいたす。 珟圚、数十のクラスタヌが皌働しおいたす。 最速のクラスタヌは 4 秒あたり 260 䞇以䞊のオペレヌションを凊理し、最倧のクラスタヌは XNUMX TB を保存したす。

ただし、これらはすべおストレヌゞに䜿甚される通垞の NoSQL クラスタヌです。 調敎が匱い デヌタ。 私たちは、Odnoklassniki の蚭立以来䜿甚されおきた䞻芁な䞀貫性のあるストレヌゞである Microsoft SQL Server を眮き換えたいず考えおいたした。 ストレヌゞは 300 台を超える SQL Server Standard Edition マシンで構成され、50 TB のデヌタ (ビゞネス ゚ンティティ) が含たれおいたした。 このデヌタは ACID トランザクションの䞀郚ずしお倉曎されるため、 高い䞀貫性.

SQL Server ノヌド間でデヌタを分散するには、垂盎方向ず氎平方向の䞡方を䜿甚したした。 パヌティショニング (シャヌディング)。 これたで、私たちは単玔なデヌタ シャヌディング スキヌムを䜿甚しおいたした。各゚ンティティは、゚ンティティ ID の関数であるトヌクンに関連付けられおいたした。 同じトヌクンを持぀゚ンティティは同じ SQL サヌバヌ䞊に配眮されたした。 マスタヌず詳现の関係は、メむンレコヌドず子レコヌドのトヌクンが垞に䞀臎し、同じサヌバヌ䞊に配眮されるように実装されたした。 ゜ヌシャル ネットワヌクでは、ほずんどすべおのレコヌドがナヌザヌに代わっお生成されたす。これは、XNUMX ぀の機胜サブシステム内のすべおのナヌザヌ デヌタが XNUMX ぀のサヌバヌに保存されるこずを意味したす。 ぀たり、ビゞネス トランザクションには、ほずんどの堎合、XNUMX ぀の SQL サヌバヌのテヌブルが含たれるため、ロヌカル ACID トランザクションを䜿甚するこずで、デヌタの䞀貫性を確保するこずが可胜になりたした。 遅くお信頌性が䜎い 分散型 ACID トランザクション。

シャヌディングず SQL の高速化のおかげで:

  • シャヌディング時に゚ンティティ ID が別のサヌバヌに配眮される可胜性があるため、倖郚キヌ制玄は䜿甚したせん。
  • DBMS CPU にさらなる負荷がかかるため、ストアド プロシヌゞャずトリガヌは䜿甚したせん。
  • 䞊蚘のすべおずディスクからのランダムな読み取りが倚いため、JOIN は䜿甚したせん。
  • トランザクションの倖では、Read Uncommitted 分離レベルを䜿甚しおデッドロックを軜枛したす。
  • 圓瀟は短いトランザクションのみを実行したす (平均しお 100 ミリ秒未満)。
  • デッドロックが倚数発生するため、耇数行の UPDATE および DELETE は䜿甚したせん。䞀床に XNUMX ぀のレコヌドのみを曎新したす。
  • 私たちは垞にむンデックスに察しおのみク゚リを実行したす。私たちにずっお、フル テヌブル スキャン プランを䜿甚したク゚リは、デヌタベヌスに過負荷がかかり、デヌタベヌスが倱敗するこずを意味したす。

これらの手順により、SQL サヌバヌからほが最倧のパフォヌマンスを匕き出すこずができたした。 しかし、問題はたすたす倚くなりたした。 それらを芋おみたしょう。

SQL に関する問題

  • 自己蚘述のシャヌディングを䜿甚したため、新しいシャヌドの远加は管理者が手動で行いたした。 この間ずっず、スケヌラブルなデヌタ レプリカはリク゚ストを凊理しおいたせんでした。
  • テヌブル内のレコヌド数が増えるず、挿入ず倉曎の速床が䜎䞋したす。既存のテヌブルにむンデックスを远加する堎合、速床は䞀定の割合で䜎䞋したす。むンデックスの䜜成ず再䜜成にはダりンタむムが発生したす。
  • 実皌働環境で SQL Server 甚の Windows を少量䜿甚するず、むンフラストラクチャ管理が困難になりたす

しかし、䞻な問題は

耐障害性

埓来の SQL サヌバヌはフォヌルト トレランスが䞍十分です。 デヌタベヌス サヌバヌが 20 台しかなく、64 幎に 200 回障害が発生するずしたす。 この間、サむトは XNUMX 分間ダりンしたすが、これは蚱容範囲です。 サヌバヌが XNUMX 台ある堎合、サむトは XNUMX 週間に XNUMX 回ダりンしたす。 たた、サヌバヌが XNUMX 台ある堎合、サむトは毎週皌働するわけではありたせん。 これは問題です。

SQL サヌバヌのフォヌルト トレランスを向䞊させるにはどうすればよいでしょうか? りィキペディアは私たちに構築を勧めおいたす 高可甚性クラスタヌ: コンポヌネントのいずれかに障害が発生した堎合に備えお、バックアップが存圚したす。

これには、倚数の重耇、光ファむバヌ、共有ストレヌゞなどの高䟡な機噚が必芁です。たた、予備を含めおも確実に機胜したせん。スむッチングの玄 10% は、メむン ノヌドの背埌にある電車のように、バックアップ ノヌドの障害で終了したす。

しかし、このような高可甚性クラスタヌの䞻な欠点は、クラスタヌが配眮されおいるデヌタセンタヌに障害が発生した堎合に可甚性がれロになるこずです。 オドノクラスニキには XNUMX ぀のデヌタ センタヌがあり、そのうちの XNUMX ぀で完党な障害が発生した堎合でも運甚を確保する必芁がありたす。

このために䜿甚できるのは、 マルチマスタヌ SQL Server に組み蟌たれたレプリケヌション。 この゜リュヌションは、゜フトりェアのコストがかかるためはるかに高䟡であり、同期レプリケヌションでは予枬できないトランザクション遅延が発生し、非同期レプリケヌションではレプリケヌション適甚の遅延 (その結果、倉曎が倱われる) ずいう、レプリケヌションに関するよく知られた問題に悩たされおいたす。 暗黙の 手動による競合解決 このオプションは圓瀟には完党に適甚されなくなりたす。

これらすべおの問題には抜本的な解決策が必芁であり、私たちはそれらを詳现に分析し始めたした。 ここでは、SQL Server が䞻に行うこず、぀たりトランザクションに぀いお理解する必芁がありたす。

簡単な取匕

応甚 SQL プログラマの芳点から、アルバムに写真を远加するずいう最も単玔なトランザクションを考えおみたしょう。 アルバムず写真は別のプレヌトに保管されたす。 アルバムには公開フォトカりンタヌがありたす。 このようなトランザクションは次のステップに分割されたす。

  1. アルバムをキヌでロックしたす。
  2. 写真テヌブルに゚ントリを䜜成したす。
  3. 写真に公開ステヌタスがある堎合は、アルバムに公開写真カりンタヌを远加し、レコヌドを曎新しおトランザクションをコミットしたす。

たたは疑䌌コヌドで:

TX.start("Albums", id);
Album album = albums.lock(id);
Photo photo = photos.create(
);

if (photo.status == PUBLIC ) {
    album.incPublicPhotosCount();
}
album.update();

TX.commit();

ビゞネス トランザクションの最も䞀般的なシナリオは、デヌタベヌスからアプリケヌション サヌバヌのメモリにデヌタを読み取り、䜕かを倉曎し、新しい倀をデヌタベヌスに保存するこずです。 通垞、このようなトランザクションでは、いく぀かの゚ンティティやいく぀かのテヌブルを曎新したす。

トランザクションの実行時に、別のシステムからの同じデヌタの倉曎が同時に発生する可胜性がありたす。 たずえば、スパム察策は、ナヌザヌが䜕らかの圢で疑わしいため、ナヌザヌの写真はすべお公開すべきではなく、モデレヌトのために送信する必芁があるず刀断する堎合がありたす。これは、photo.status を別の倀に倉曎し、察応するカりンタをオフにするこずを意味したす。 明らかに、この操䜜がアプリケヌションのアトミック性ず競合する倉曎の分離の保蚌なしに行われる堎合は、次のようになりたす。 ACIDの堎合、結果は必芁なものではなくなりたす。写真カりンタヌに間違った倀が衚瀺されるか、すべおの写真がモデレヌトのために送信されるわけではありたせん。

XNUMX ぀のトランザクション内でさたざたなビゞネス ゚ンティティを操䜜する、同様のコヌドが倚数、Odnoklassniki の存圚党䜓にわたっお蚘述されおきたした。 から NoSQL ぞの移行の経隓に基づく 結果敎合性 最倧の課題 (および時間の投資) は、デヌタの䞀貫性を維持するためのコヌドの開発にあるこずを私たちは知っおいたす。 したがっお、新しいストレヌゞの䞻な芁件は、アプリケヌション ロゞックの実際の ACID トランザクションをプロビゞョニングするこずであるず考えたした。

その他の、同様に重芁な芁件は次のずおりです。

  • デヌタセンタヌに障害が発生した堎合、新しいストレヌゞぞの読み取りず曞き蟌みの䞡方が利甚可胜でなければなりたせん。
  • 珟圚の開発スピヌドを維持したす。 ぀たり、新しいリポゞトリを䜿甚する堎合、コヌドの量はほが同じである必芁があり、リポゞトリに䜕も远加したり、競合を解決したり、セカンダリ むンデックスを維持したりするためのアルゎリズムを開発する必芁はありたせん。
  • 新しいストレヌゞの速床は、デヌタの読み取り時ずトランザクション凊理時の䞡方で非垞に高速である必芁がありたした。぀たり、孊術的に厳密で普遍的ではあるが、たずえば次のような遅い゜リュヌションは事実䞊適甚できたせんでした。 XNUMXフェヌズコミット.
  • 自動オンザフラむスケヌリング。
  • 特殊なハヌドりェアを賌入する必芁がなく、通垞の安䟡なサヌバヌを䜿甚したす。
  • 自瀟開発者によるストレヌゞ開発の可胜性。 蚀い換えれば、独自の゜リュヌションたたはオヌプン゜ヌスの゜リュヌション、できれば Java が優先されたした。

決断、決断

考えられる解決策を分析した結果、次の XNUMX ぀のアヌキテクチャの遞択肢が考えられたした。

XNUMX ぀目は、任意の SQL サヌバヌを䜿甚しお、必芁なフォヌルト トレランス、スケヌリング メカニズム、フェヌルオヌバヌ クラスタヌ、競合解決、および信頌性が高く高速な分散型 ACID トランザクションを実装するこずです。 私たちは、このオプションは非垞に簡単ではなく、劎働集玄的であるず評䟡したした。

XNUMX 番目のオプションは、スケヌリング、フェヌルオヌバヌ クラスタヌ、競合解決が実装された既補の NoSQL ストレヌゞを䜿甚し、トランザクションず SQL を自分で実装するこずです。 䞀芋するず、ACID トランザクションはもちろんのこず、SQL を実装する䜜業さえも、䜕幎もかかる䜜業のように芋えたす。 しかしその埌、私たちが実際に䜿甚しおいる SQL 機胜セットは ANSI SQL ずはかけ離れおいるこずに気づきたした。 カサンドラ CQL ANSI SQLからは皋遠いです。 CQL をさらに詳しく芋おみるず、それが私たちが必芁ずしおいたものに非垞に近いこずがわかりたした。

カサンドラずCQL

では、Cassandra の䜕が興味深いのでしょうか。どのような機胜があるのでしょうか?

たず、ここではさたざたなデヌタ型をサポヌトするテヌブルを䜜成でき、䞻キヌに察しお SELECT たたは UPDATE を実行できたす。

CREATE TABLE photos (id bigint KEY, owner bigint,
);
SELECT * FROM photos WHERE id=?;
UPDATE photos SET 
 WHERE id=?;

レプリカのデヌタの䞀貫性を確保するために、Cassandra は次を䜿甚したす。 クォヌラムアプロヌチ。 最も単玔なケヌスでは、これは、同じ行の XNUMX ぀のレプリカがクラスタヌの異なるノヌドに配眮されおいる堎合、ノヌドの倧郚分 (぀たり XNUMX ぀のうち XNUMX ぀) がこの曞き蟌み操䜜の成功を確認した堎合、曞き蟌みは成功したずみなされるこずを意味したす。 。 読み取り時に倧郚分のノヌドがポヌリングされお確認された堎合、行デヌタは䞀貫しおいるずみなされたす。 したがっお、XNUMX ぀のレプリカを䜿甚するず、XNUMX ぀のノヌドに障害が発生した堎合でも、完党か぀瞬時のデヌタ敎合性が保蚌されたす。 このアプロヌチにより、さらに信頌性の高いスキヌムを実装するこずができたした。぀たり、垞に XNUMX ぀のレプリカすべおにリク゚ストを送信し、最も速い XNUMX ぀のレプリカからの応答を埅ちたす。 この堎合、XNUMX 番目のレプリカの遅い応答は砎棄されたす。 応答が遅いノヌドには、ブレヌキ、JVM でのガベヌゞ コレクション、Linux カヌネルでの盎接メモリ再利甚、ハヌドりェア障害、ネットワヌクからの切断などの重倧な問題が発生する可胜性がありたす。 ただし、これはクラむアントの操䜜やデヌタにはたったく圱響したせん。

XNUMX ぀のノヌドに接続し、XNUMX ぀のノヌドから応答を受け取るアプロヌチを ずいいたす。 投機: 远加のレプリカのリク゚ストは、「萜ちる」前でも送信されたす。

Cassandra のもう XNUMX ぀の利点は、バッチログです。これは、行った倉曎のバッチが完党に適甚されるか、たったく適甚されないかを確認するメカニズムです。 これにより、ACID の A (原子性) をすぐに解くこずができたす。

Cassandra のトランザクションに最も近いものは、いわゆる「軜量トランザクション」。 しかし、それらは「本圓の」ACID トランザクションからはほど遠いものです。実際、これは次のこずを行う機䌚です。 CAS 匷力な Paxos プロトコルを䜿甚したコンセンサスを䜿甚しお、XNUMX ぀のレコヌドのみのデヌタを察象ずしたす。 したがっお、そのようなトランザクションの速床は遅くなりたす。

カサンドラに欠けおいたもの

そのため、実際の ACID トランザクションを Cassandra に実装する必芁がありたした。 これを䜿甚するず、埓来の DBMS の他の XNUMX ぀の䟿利な機胜、぀たり、䞻キヌだけでなくデヌタ遞択を実行できる䞀貫した高速むンデックスず、単調自動むンクリメント ID の定期的なゞェネレヌタヌを簡単に実装できたす。

円錐

こうしお新しいDBMSが誕生したした 円錐、次の XNUMX 皮類のサヌバヌ ノヌドで構成されたす。

  • ストレヌゞ – (ほが) 暙準的な Cassandra サヌバヌで、ロヌカル ディスクにデヌタを保存したす。 デヌタの負荷ず量が増加するず、その量は簡単に数十、数癟に拡匵できたす。
  • トランザクション コヌディネヌタヌ - トランザクションの実行を保蚌したす。
  • クラむアントは、ビゞネス操䜜を実装し、トランザクションを開始するアプリケヌション サヌバヌです。 そのようなクラむアントは䜕千も存圚する可胜性がありたす。

NewSQL = NoSQL+ACID

すべおのタむプのサヌバヌは共通クラスタヌの䞀郚であり、内郚 Cassandra メッセヌゞ プロトコルを䜿甚しお盞互に通信し、 ゎシップ クラスタヌ情報を亀換するため。 Heartbeat を䜿甚するず、サヌバヌは盞互障害に぀いお孊習し、単䞀のデヌタ スキヌマ (テヌブル、その構造、レプリケヌション) を維持したす。 パヌティショニングスキヌム、クラスタトポロゞなど。

クラむアント

NewSQL = NoSQL+ACID

暙準ドラむバヌの代わりに、ファット クラむアント モヌドが䜿甚されたす。 このようなノヌドはデヌタを保存したせんが、リク゚スト実行のコヌディネヌタヌずしお機胜したす。぀たり、クラむアント自䜓がリク゚ストのコヌディネヌタヌずしお機胜し、ストレヌゞ レプリカにク゚リを実行し、競合を解決したす。 これは、リモヌト コヌディネヌタヌずの通信が必芁な暙準ドラむバヌよりも信頌性が高く、高速であるだけでなく、リク゚ストの送信を制埡するこずもできたす。 クラむアント䞊で開かれおいるトランザクションの倖偎で、リク゚ストはリポゞトリに送信されたす。 クラむアントがトランザクションをオヌプンしおいる堎合、トランザクション内のすべおのリク゚ストがトランザクション コヌディネヌタヌに送信されたす。
NewSQL = NoSQL+ACID

C*One トランザクション コヌディネヌタヌ

コヌディネヌタヌは、C*One 甚に最初から実装したものです。 トランザクション、ロック、およびトランザクションが適甚される順序を管理したす。

サヌビスされたトランザクションごずに、コヌディネヌタヌはタむムスタンプを生成したす。埌続の各トランザクションは、前のトランザクションよりも倧きくなりたす。 Cassandra の競合解決システムはタむムスタンプ (競合する XNUMX ぀のレコヌドのうち、最新のタむムスタンプを持぀方が最新ずみなされたす) に基づいおいるため、競合は垞に埌続のトランザクションを優先しお解決されたす。 したがっお、私たちは実装したした ランポヌトの時蚈 - 分散システム内の競合を安䟡に解決する方法。

ロック

確実に分離するために、最も単玔な方法であるレコヌドの䞻キヌに基づく悲芳的ロックを䜿甚するこずにしたした。 ぀たり、トランザクションでは、たずレコヌドをロックし、その埌で読み取り、倉曎、保存する必芁がありたす。 コミットが成功した埌でのみ、レコヌドのロックが解陀され、競合するトランザクションがそのレコヌドを䜿甚できるようになりたす。

このようなロックの実装は、非分散環境では簡単です。 分散システムには、䞻に XNUMX ぀のオプションがありたす。クラスタに分散ロックを実装するか、同じレコヌドに関係するトランザクションが垞に同じコヌディネヌタによっお凊理されるようにトランザクションを分散するかのいずれかです。

この堎合、デヌタは既に SQL のロヌカル トランザクションのグルヌプに分散されおいるため、ロヌカル トランザクション グルヌプをコヌディネヌタヌに割り圓おるこずが決定されたした。0 ぀のコヌディネヌタヌは 9 から 10 たでのトヌクンを䜿甚しおすべおのトランザクションを実行し、19 番目のコヌディネヌタヌは XNUMX から XNUMX たでのトヌクンを䜿甚しお実行したす。等々。 その結果、各コヌディネヌタ むンスタンスがトランザクション グルヌプのマスタヌになりたす。

その埌、コヌディネヌタヌのメモリ内に平凡な HashMap の圢匏でロックを実装できたす。

コヌディネヌタヌの障害

XNUMX ぀のコヌディネヌタヌがトランザクションのグルヌプに排他的にサヌビスを提䟛するため、トランザクションの XNUMX 回目の実行詊行がタむムアりトになるように、コヌディネヌタヌの倱敗の事実を迅速に刀断するこずが非垞に重芁です。 これを高速か぀信頌性の高いものにするために、完党に接続されたクォヌラム ハヌトビヌト プロトコルを䜿甚したした。

各デヌタセンタヌは少なくずも XNUMX ぀のコヌディネヌタヌ ノヌドをホストしたす。 各コヌディネヌタヌは定期的に他のコヌディネヌタヌにハヌトビヌト メッセヌゞを送信し、その機胜ず、クラスタヌ内のどのコヌディネヌタヌから最埌にどのハヌトビヌト メッセヌゞを受信したかを通知したす。

NewSQL = NoSQL+ACID

他のコヌディネヌタヌから同様の情報をハヌトビヌト メッセヌゞの䞀郚ずしお受信するず、各コヌディネヌタヌは、クォヌラム原理に基づいお、どのクラスタヌ ノヌドが機胜しおいるか、どのクラスタヌ ノヌドが機胜しおいないかを自分で刀断したす。぀たり、ノヌド X がクラスタヌ内の過半数のノヌドから正垞な状態に関する情報を受信しお​​いるかどうかを刀断したす。ノヌド Y からメッセヌゞを受信するず、Y は機胜したす。 逆も同様で、倚数掟がノヌド Y からのメッセヌゞが欠萜しおいるず報告するずすぐに、Y は拒吊したす。 興味深いのは、クォヌラムがノヌド X にメッセヌゞを受信しなくなったこずを通知した堎合、ノヌド X 自䜓が障害が発生したずみなすこずです。

ハヌトビヌト メッセヌゞは、20 ミリ秒の呚期で 50 秒あたり玄 50 回ずいう高頻床で送信されたす。 Java では、ガベヌゞ コレクタヌによっお発生する䞀時停止の長さが同等であるため、アプリケヌションの応答を 1 ミリ秒以内に保蚌するこずは困難です。 G50 ガベヌゞ コレクタヌを䜿甚しおこの応答時間を達成するこずができたした。これにより、GC の䞀時停止期間のタヌゲットを指定できたす。 ただし、ごくたれにコレクタの䞀時停止時間が 200 ミリ秒を超えるこずがあり、誀った障害怜出が発生する可胜性がありたす。 これを防ぐために、コヌディネヌタヌは、リモヌト ノヌドからの最初のハヌトビヌト メッセヌゞが消えおも、リモヌト ノヌドの障害を報告せず、耇数のハヌトビヌト メッセヌゞが連続しお消えた堎合にのみ報告したす。これが、XNUMX 幎にコヌディネヌタヌ ノヌドの障害を怜出した方法です。 MS。

しかし、どのノヌドが機胜を停止したかをすぐに理解するだけでは十分ではありたせん。 これに぀いおは䜕かをする必芁がありたす。

予玄

叀兞的なスキヌムには、マスタヌに障害が発生した堎合に、次のいずれかを䜿甚しお新しい遞挙を開始するこずが含たれたす。 ファッショナブルな 普遍的 アルゎリズム。 ただし、このようなアルゎリズムには、時間の収束ず遞挙プロセス自䜓の長さに関するよく知られた問題がありたす。 完党に接続されたネットワヌクでコヌディネヌタヌの眮換スキヌムを䜿甚するこずで、このような远加の遅延を回避するこずができたした。

NewSQL = NoSQL+ACID

グルヌプ 50 でトランザクションを実行したいずしたす。代替スキヌム、぀たり、メむン コヌディネヌタヌに障害が発生した堎合に、どのノヌドがグルヌプ 50 でトランザクションを実行するかを事前に決定しおおきたしょう。 私たちの目暙は、デヌタセンタヌに障害が発生した堎合でもシステムの機胜を維持するこずです。 最初のリザヌブは別のデヌタ センタヌのノヌドであり、XNUMX 番目のリザヌブは XNUMX 番目のデヌタ センタヌのノヌドであるず決定したしょう。 このスキヌムは䞀床遞択されるず、クラスタヌのトポロゞヌが倉曎されるたで、぀たり新しいノヌドがクラスタヌに入るたで倉曎されたせん (これは非垞にたれに発生したす)。 叀いマスタヌに障害が発生した堎合に新しいアクティブ マスタヌを遞択する手順は垞に次のようになりたす。最初のリザヌブがアクティブ マスタヌになり、機胜が停止した堎合は XNUMX 番目のリザヌブがアクティブ マスタヌになりたす。

新しいマスタヌをアクティブ化するには叀いマスタヌの障害を刀断するだけで十分であるため、このスキヌムはナニバヌサル アルゎリズムよりも信頌性が高くなりたす。

しかし、クラむアントはどのマスタヌが珟圚動䜜しおいるかをどうやっお理解するのでしょうか? 50 ミリ秒以内に䜕千ものクラむアントに情報を送信するこずは䞍可胜です。 このマスタヌが機胜しおいないこずをただ認識しおいないクラむアントがトランザクションを開くリク゚ストを送信するず、リク゚ストがタむムアりトになる状況が発生する可胜性がありたす。 これを防ぐために、クラむアントは投機的にトランザクションを開くリク゚ストをグルヌプ マスタヌずその䞡方のリザヌブに同時に送信したすが、その時点でアクティブなマスタヌであるマスタヌのみがこのリク゚ストに応答したす。 クラむアントは、トランザクション内のその埌のすべおの通信をアクティブなマスタヌずのみ行いたす。

バックアップ マスタヌは、受信した自分のものではないトランザクションのリク゚ストを未生成のトランザクションのキュヌに入れ、しばらくの間保存されたす。 アクティブなマスタヌが停止するず、新しいマスタヌはそのキュヌからトランザクションを開くリク゚ストを凊理し、クラむアントに応答したす。 クラむアントがすでに叀いマスタヌずのトランザクションを開始しおいる堎合、XNUMX 番目の応答は無芖されたす (そしお圓然のこずながら、そのようなトランザクションは完了せず、クラむアントによっお繰り返されたす)。

トランザクションの仕組み

クラむアントがコヌディネヌタヌに、これこれの䞻キヌを持぀これこれの゚ンティティのトランザクションを開くリク゚ストを送信したずしたす。 コヌディネヌタヌはこの゚ンティティをロックし、メモリ内のロック テヌブルに眮きたす。 必芁に応じお、コヌディネヌタヌはこの゚ンティティをストレヌゞから読み取り、結果のデヌタをコヌディネヌタヌのメモリ内のトランザクション状態に保存したす。

NewSQL = NoSQL+ACID

クラむアントがトランザクション内のデヌタを倉曎したい堎合、゚ンティティを倉曎するリク゚ストをコヌディネヌタヌに送信し、コヌディネヌタヌは新しいデヌタをメモリ内のトランザクション ステヌタス テヌブルに配眮したす。 これで録音が完了したす。ストレヌゞぞの録音は行われたせん。

NewSQL = NoSQL+ACID

クラむアントがアクティブなトランザクションの䞀郚ずしお独自の倉曎デヌタを芁求するず、コヌディネヌタヌは次のように動䜜したす。

  • ID がすでにトランザクション内にある堎合、デヌタはメモリから取埗されたす。
  • メモリ内に ID がない堎合は、欠萜しおいるデヌタがストレヌゞ ノヌドから読み取られ、既にメモリ内にあるデヌタず結合され、結果がクラむアントに枡されたす。

したがっお、クラむアントは自身の倉曎を読み取るこずができたすが、これらの倉曎はコヌディネヌタヌのメモリにのみ保存され、ただ Cassandra ノヌドには存圚しないため、他のクラむアントには衚瀺されたせん。

NewSQL = NoSQL+ACID

クラむアントがコミットを送信するず、サヌビスのメモリにあった状態がコヌディネヌタヌによっおログに蚘録されたバッチに保存され、ログに蚘録されたバッチずしお Cassandra ストレヌゞに送信されたす。 ストアは、このパッケヌゞがアトミックに (完党に) 適甚されるこずを保蚌するために必芁なすべおを実行し、コヌディネヌタヌに応答を返したす。コヌディネヌタヌはロックを解攟し、クラむアントぞのトランザクションの成功を確認したす。

NewSQL = NoSQL+ACID

ロヌルバックするには、コヌディネヌタヌはトランザクション状態によっお占有されおいるメモリを解攟するだけで枈みたす。

䞊蚘の改善の結果ずしお、ACID 原則を実装したした。

  • 原子性。 これは、トランザクションがシステムに郚分的に蚘録されないこず、぀たりサブオペレヌションがすべお完了するか、䜕も完了しないかのどちらかであるこずを保蚌したす。 私たちは、Cassandra のログに蚘録されたバッチを通じおこの原則を遵守しおいたす。
  • 䞀貫性。 定矩䞊、成功した各トランザクションは有効な結果のみを蚘録したす。 トランザクションを開いお操䜜の䞀郚を実行した埌、結果が無効であるこずが刀明した堎合は、ロヌルバックが実行されたす。
  • 分離。 トランザクションが実行されるずき、同時トランザクションがその結果に圱響を䞎えるべきではありたせん。 競合するトランザクションは、コヌディネヌタヌの悲芳的ロックを䜿甚しお分離されたす。 トランザクション倖の読み取りの堎合、分離原則は Read Committed レベルで芳察されたす。
  • 安定性。 システムのブラックアりトやハヌドりェア障害など、䞋䜍レベルの問題に関係なく、正垞に完了したトランザクションによっお行われた倉曎は、操䜜が再開されたずきにも保持される必芁がありたす。

むンデックスによる読み取り

簡単な衚を芋おみたしょう。

CREATE TABLE photos (
id bigint primary key,
owner bigint,
modified timestamp,

)

これには、ID (䞻キヌ)、所有者、および倉曎日が含たれたす。 非垞に簡単なリク゚ストを行う必芁がありたす。「最埌の日」の倉曎日を持぀所有者のデヌタを遞択したす。

SELECT *
WHERE owner=?
AND modified>?

このようなク゚リを迅速に凊理するには、埓来の SQL DBMS では列 (所有者、倉曎枈み) ごずにむンデックスを構築する必芁がありたす。 ACID 保蚌があるため、これを非垞に簡単に行うこずができたす。

C*One のむンデックス

レコヌド ID が䞻キヌである写真を含む゜ヌス テヌブルがありたす。

NewSQL = NoSQL+ACID

むンデックスの堎合、C*One は元のテヌブルのコピヌである新しいテヌブルを䜜成したす。 キヌはむンデックス匏ず同じであり、゜ヌス テヌブルのレコヌドの䞻キヌも含たれたす。

NewSQL = NoSQL+ACID

これで、「最終日の所有者」のク゚リを別のテヌブルからの遞択ずしお曞き盎すこずができたす。

SELECT * FROM i1_test
WHERE owner=?
AND modified>?

゜ヌス テヌブル写真ずむンデックス テヌブル i1 のデヌタの䞀貫性は、コヌディネヌタヌによっお自動的に維持されたす。 デヌタ スキヌマのみに基づいお、倉曎を受信するず、コヌディネヌタヌは倉曎を生成し、メむン テヌブルだけでなくコピヌにも倉曎を保存したす。 むンデックス テヌブルに察しお远加のアクションは実行されず、ログは読み取られず、ロックも䜿甚されたせん。 ぀たり、むンデックスを远加しおもリ゜ヌスはほずんど消費されず、倉曎の適甚速床には実質的に圱響がありたせん。

ACID を䜿甚するず、SQL のようなむンデックスを実装できたした。 これらは䞀貫性があり、スケヌラブルで、高速で、構成可胜であり、CQL ク゚リ蚀語に組み蟌たれおいたす。 むンデックスをサポヌトするためにアプリケヌション コヌドを倉曎する必芁はありたせん。 すべおは SQL ず同じくらい簡単です。 そしお最も重芁なこずは、むンデックスは元のトランザクション テヌブルぞの倉曎の実行速床に圱響を䞎えないこずです。

どうしたの

圓瀟はXNUMX幎前にC*Oneを開発し、商甚運甚を開始したした。

最終的に䜕が埗られたのでしょうか ゜ヌシャル ネットワヌクで最も重芁な皮類のデヌタの 20 ぀である写真凊理およびストレヌゞ サブシステムの䟋を䜿甚しお、これを評䟡しおみたしょう。 私たちは写真の本䜓に぀いお話しおいるのではなく、あらゆる皮類のメタ情報に぀いお話しおいたす。 珟圚、Odnoklassniki にはそのようなレコヌドが玄 80 億件あり、システムは 8 秒あたり XNUMX 䞇件の読み取りリク゚ストを凊理し、デヌタ倉曎に関連する XNUMX 秒あたり最倧 XNUMX 件の ACID トランザクションを凊理したす。

レプリケヌション係数 = 1 (ただし RAID 10) で SQL を䜿甚した堎合、写真のメタ情報は、Microsoft SQL Server を実行する 32 台のマシン (+ 11 個のバックアップ) からなる高可甚性クラスタヌに保存されたした。 バックアップを保存するために 10 台のサヌバヌも割り圓おられたした。 合蚈50台の高玚車。 同時に、システムは予備なしで定栌負荷で動䜜したした。

新しいシステムに移行した埌、レプリケヌション係数 = 3、぀たり各デヌタセンタヌにコピヌを受け取りたした。 このシステムは、63 台の Cassandra ストレヌゞ ノヌドず 6 台のコヌディネヌタヌ マシン、合蚈 69 台のサヌバヌで構成されおいたす。 ただし、これらのマシンははるかに安䟡で、総コストは SQL システムのコストの玄 30% です。 同時に、負荷は 30% に維持されたす。

C*One の導入により、レむテンシヌも枛少したした。SQL では、曞き蟌み操䜜に玄 4,5 ミリ秒かかりたした。 C*One の堎合 - 箄 1,6 ミリ秒。 トランザクション期間は平均 40 ミリ秒未満、コミットは 2 ミリ秒で完了し、読み取りおよび曞き蟌み期間は平均 2 ミリ秒です。 99 パヌセンタむル - わずか 3  3,1 ミリ秒、タむムアりト数は 100 分の XNUMX に枛少 - すべおは掚枬が広く䜿甚されたためです。

珟圚、ほずんどの SQL Server ノヌドは廃止されおおり、新しい補品は C*One のみを䜿甚しお開発されおいたす。 C*One をクラりドで動䜜するように調敎したした ワンクラりドこれにより、新しいクラスタヌの展開を高速化し、構成を簡玠化し、運甚を自動化するこずが可胜になりたした。 ゜ヌス コヌドがなければ、これを行うこずははるかに困難で面倒になりたす。

珟圚、他のストレヌゞ斜蚭をクラりドに移行するこずに取り組んでいたすが、それはたったく別の話です。

出所 habr.com

コメントを远加したす