1 秒あたり数千の注文があるシナリオで、分散ロックの高同時実行性の最適化を実践します。

1 秒あたり数千の注文があるシナリオで、分散ロックの高同時実行性の最適化を実践します。

[[340470]]

この記事はWeChatの公開アカウント「Huperzineの建築に関するメモ」から転載されたもので、著者はHuperzine Chinaです。この記事を転載する場合は、Shi Shan の Architecture Notes 公開アカウントにご連絡ください。

背景

まず、この問題の背景を見てみましょう。

少し前、私の友人が社外で面接を受けていたのですが、ある日彼が私に話しかけてきてこう言いました。「国内に良い電子商取引会社があるんですが、面接官が彼にシナリオ形式の質問を投げかけました。

注文時に過剰販売を防ぐために分散ロックが使用されているが、注文が 1 秒あたり数千の注文がある高同時実行シナリオで行われる場合、このシナリオに対処するために、分散ロックを高同時実行向けに最適化するにはどうすればよいでしょうか。

彼は、その質問をしたことがなく、何も知らなかったため、その時点では答えられなかったと言いました。実際、私はこの面接の質問を聞いたとき、非常に興味深いと思いました。なぜなら、私が候補者を面接するなら、おそらくもっと幅広い範囲の質問をするだろうからです。

たとえば、インタビュー対象者に、電子商取引の高同時フラッシュセールシナリオにおける在庫過剰販売ソリューション、さまざまなソリューションの長所と短所、およびその実践について話してもらい、その後、分散ロックのトピックについて話してもらいます。

なぜなら、売られ過ぎ在庫の問題には、悲観的ロック、分散ロック、楽観的ロック、キューのシリアル化、Redis アトミック操作など、多くの技術的な解決策があるからです。

しかし、インタビュアーの兄弟は在庫過剰を解決するために分散ロックの使用を厳しく制限していたので、彼はただ1つの点を尋ねたかっただけだと思います。それは、高同時実行シナリオで分散ロックの同時パフォーマンスを最適化する方法です。

インタビュアーの質問の角度は受け入れられると思います。なぜなら、実際に本番環境に導入すると、分散ロックによってデータの正確性は確保されますが、その自然な同時実行能力は少し弱いからです。

偶然にも、私は以前、自分のプロジェクトの他のシナリオで、高同時実行シナリオ向けの分散ロック最適化ソリューションに取り組んだことがあります。したがって、私はこの友人の面接の質問を利用して、分散ロックの高並行性最適化のアイデアについてお話ししたいと思います。

在庫の過剰販売はどのようにして発生しますか?

まず、分散ロックが使用されていない場合、いわゆる電子商取引在庫の過剰販売が何を意味するのかを見てみましょう。次の図を見てみましょう。

この図は実は非常にわかりやすいです。注文システムが 2 台のマシンに展開されており、異なるユーザーが同時に 10 台の iPhone を購入したいと考え、各ユーザーが注文システムにリクエストを送信するとします。次に、各注文システムインスタンスがデータベースをチェックし、現在の iPhone の在庫が 12 台であることを確認しました。

2 人の兄弟はそれを見て大喜びしました。なぜなら、在庫が 12 個あり、購入したいと思っていた 10 個より多かったからです。したがって、各注文システム インスタンスは、データベースに SQL を送信して注文を行い、在庫を 10 単位減らしました。 1 つは在庫を 12 個から 2 個に減らし、もう 1 つは在庫を 2 個から -8 個に減らしました。

もう終わりです、在庫はマイナスです!泣けてくるよ。2人のユーザーに送るiPhoneが20台もないんだから!どうすればいいですか?

分散ロックを使用して在庫の売れ過ぎの問題を解決するにはどうすればよいでしょうか?

在庫過剰の問題を解決するために分散ロックをどのように使用すればよいでしょうか?実のところ、それは非常に簡単です。前回説明した分散ロックの実装原則を思い出してください。

同じロック キーの場合、同時にロックを取得できるのは 1 つのクライアントのみです。他のクライアントはロックを取得しようと無期限に待機します。ロックを取得したクライアントのみが次のビジネス ロジックを実行できます。

コードはおおよそ上記のようになります。では、なぜこれによって在庫の過剰販売を回避できるのかを分析してみましょう。

上記のステップ番号に従えば、すぐに理解できるでしょう。上の図からわかるように、分散ロックを正常に追加できるのは 1 つの注文システム インスタンスのみであり、その後、この 1 つのインスタンスのみが在庫を確認し、在庫が十分かどうかを判断し、在庫を差し引く注文を出し、ロックを解除することができます。

ロックが解除された後、別の注文システムインスタンスをロックできます。次に在庫を確認すると、在庫は 2 個しかないことがわかります。在庫が不足しており購入できないため、注文が失敗します。在庫は -8 まで減少しません。

在庫過剰の問題を解決する他の解決策はありますか?

もちろんありますよ!たとえば、悲観的ロック、分散ロック、楽観的ロック、キューのシリアル化、非同期キューの分散、Redis アトミック操作などです。当社には、在庫の過剰販売に対する独自の最適化メカニズムがあります。

しかし、前述したように、この記事は分散ロックの同時実行の最適化に関するものであり、在庫の過剰販売の解決策に関するものではありません。在庫の過剰販売は単なるビジネスシナリオです。

同時実行性の高いシナリオにおける分散ロックソリューション

さて、次に、同時実行性の高いシナリオで分散ロック ソリューションがどのような問題を抱えているかを見てみましょう。

これは大きな問題です!兄さん、君がそれを理解したかどうかは分からないよ。分散ロックが追加されると、同じ製品に対する注文リクエストにより、すべてのクライアントが同じ製品の在庫ロック キーをロックすることになります。

たとえば、iPhone という商品を注文する場合、ロックキー「iphone_stock」を追加する必要があります。これにより、同じ製品に対する注文リクエストをシリアル化して 1 つずつ処理する必要が生じます。上の図を何度も見直すと、この問題を理解できるはずです。

ロック後、ロックを解除する前に、在庫を確認 -> 注文を作成 -> 在庫を減算すると仮定します。このプロセスのパフォーマンスは非常に高いです。全体のプロセスには 20 ミリ秒かかりますが、これは良好なはずです。

1 秒は 1000 ミリ秒なので、この製品を連続して処理するには 50 件のリクエストしか処理できません。たとえば、1 秒あたり 50 件のリクエストが届き、そのすべてが iPhone の注文である場合、各リクエストの処理には 20 ミリ秒かかります。リクエストが 1 件ずつ届いた場合は、最後の 1000 ミリ秒で 50 件のリクエストすべてを処理できます。

より深く理解するために、以下の画像をご覧ください。

したがって、これを読んだ後、誰もが少なくとも、過剰在庫の問題に対処するために分散ロックを単純に使用することの欠点を理解します。

不具合としては、複数のユーザーが同時に同じ商品を注文した場合、分散ロックに基づいて処理がシリアル化され、同じ商品に対する大量の注文要求を同時に処理できなくなるというものがあります。

このソリューションは、同時実行性が低く、フラッシュセールのない通常の小規模な電子商取引システムには適している可能性があります。同時実行性が非常に低く、1 秒あたり 10 件未満のリクエストで、単一の製品をフラッシュ販売する瞬間的な高同時実行性のシナリオがない場合、小規模な電子商取引システムではそのようなシナリオがないため、1 秒間に同じ製品に対して 1,000 件の注文を行うことは実際にはまれです。

高い同時実行性を実現するために分散ロックを最適化するにはどうすればよいでしょうか?

さて、ようやく本題に入りましたが、次は何をすればいいでしょうか?

面接官は「もう行き詰まっています」と言いました。在庫過剰は分散ロックによって解決され、1秒間にiPhoneの注文が数千件も入ります。どうすれば最適化できるでしょうか?

先ほどの計算によれば、1秒間に処理できるiPhoneの注文は50件だけです。

実際、言うのは非常に簡単です。多くの人が Java の ConcurrentHashMap のソース コードと基本原理を読んでおり、その中心となるアイデアがセグメント化されたロックであることを知っているはずです。

データは多数のセグメントに分割され、各セグメントは個別のロックであるため、複数のスレッドが同時にデータを変更する場合、異なるセグメントのデータも同時に変更できます。同時に 1 つのスレッドだけが ConcurrentHashMap 内のデータを排他的に変更できるというわけではありません。

さらに、Java 8 では新しい LongAdder クラスが追加されました。これも Java 7 以前の AtomicLong の最適化です。これにより、CAS 操作が高並行性のシナリオで楽観的ロックの考え方を使用するため、多数のスレッドが長時間ループを繰り返すという問題が解決されます。

LongAdder も同様のセグメント化された CAS 操作を使用し、失敗した場合は自動的に次のセグメントに移行して CAS を実行します。

実際、分散ロックの最適化の考え方も同様です。私たちは以前、過剰在庫の問題ではなく、別のビジネス シナリオでこのソリューションを本番環境に実装しました。

ただし、売れ過ぎ在庫のビジネス シナリオはわかりやすく、わかりやすいので、このシナリオを使用して説明します。次の図を見てみましょう。

実際、これはセグメント化されたロックです。考えてみてください。iPhone に 1,000 個の在庫アイテムがある場合、それを 20 個の在庫セグメントに分割できます。必要に応じて、stock_01、stock_02 など、データベース テーブルに 20 個の在庫フィールドを作成できます。また、20 個のインベントリ キーを redis などの場所に置くこともできます。

つまり、1,000 個の在庫がセグメントに分割され、各セグメントに 50 個の在庫が含まれたことになります。たとえば、stock_01 は在庫 50 個に対応し、stock_02 は在庫 50 個に対応します。

すると、1 秒あたり 1,000 件のリクエストが届きます。素晴らしい!この時点で、実際に単純なランダム アルゴリズムを自分で記述することができます。各リクエストでは、ロックする 20 個のセグメント化されたインベントリからランダムに 1 つが選択されます。

ビンゴ!それでおしまい。最大 20 件の注文リクエストを同時に実行できます。各注文リクエストは在庫セグメントをロックします。そして、ビジネス ロジックでは、データベースまたは Redis 内のセグメント化された在庫に対して、在庫の確認 -> 在庫が十分かどうかの判断 -> 在庫の減算などの操作を行うことができます。

これは何に相当しますか?これは 20 ミリ秒に相当し、20 件の注文リクエストを同時に処理できます。したがって、1 秒間に、iPhone の 20 * 50 = 1000 件の注文リクエストを順番に処理できます。

特定のデータがセグメント化されると、誰もが注意しなければならない落とし穴があります。特定の注文リクエストがロックされ、このセグメントの在庫が不足していることが判明した場合、どうすればよいでしょうか。

このとき、自動的にロックを解除し、すぐに次のセグメント化された在庫に切り替えて、再度ロックをかけて処理を試みる必要があります。このプロセスを実装する必要があります。

分散ロック同時実行最適化ソリューションには欠点がありますか?

確かに欠点はいくつかありますが、最大の欠点に気づきましたか?非常に不便です!実装するには複雑すぎます。

まず、データをセグメントに保存する必要があります。元々良好な状態だった在庫フィールドを、20 個のセグメント化された在庫フィールドに分割する必要があります。

次に、在庫を処理するたびに、処理するセグメントをランダムに選択するための独自のランダム アルゴリズムを記述する必要があります。

最後に、特定のセグメントにデータが不十分な場合は、処理のために次のセグメント データに自動的に切り替える必要があります。

このプロセスは、コードを記述して手動で実装する必要があり、それでも少し手間がかかり、面倒です。

ただし、一部のビジネス シナリオでは分散ロックを使用するため、ロックの同時実行性を最適化し、さらにセグメント化されたロックの技術的ソリューションを使用する必要があります。効果はもちろん非常に良好で、同時実行パフォーマンスを一度に数十倍向上させることができます。

この最適化スキームのその後の改良

この記事で説明した在庫の売れ過ぎのシナリオを例に挙げてみましょう。このようにプレイすると、自分自身が非常に惨めになります。

<<:  クラウド用に生まれた QingStor 分散ストレージが完全にアップグレードされました。

>>:  クラウドコンピューティングは必ずしもリモートワーカーに最適とは限らない

推薦する

ローカルポータルコミュニティの運営においてウェブマスターが直面する障害について議論する

合理的なウェブマスターであれば、どのようなタイプのサイトを運営する前にも、徹底的な分析、自身の利点の...

Kubectl Foreach 複数のクラスターで Kubectl コマンドを実行します

先週、K8s マルチクラスター トラフィック スケジューリングのデモ部分を書いていたとき、複数のクラ...

Linode-13周年、VPS価格は据え置き、メモリは「なんとも言えないほど」倍増

Linode.com は、今年で 13 周年を迎えたと発表しました。これまでとは異なり、同社はお金を...

shuhost: 香港 Huawei ブティック専用回線\bgp\cn2 回線、30M 帯域幅、独立サーバー最低 315 元

Shuhost(Shumai Technology)の香港データセンターは現在、Huawei Clo...

チェン・ユー: 2012 年 Web マスター年次会議記録 - 登場人物

著者は、ウェブマスター年次会議の協力メディアゲストとして、2012 年第 7 回中国インターネット ...

UiPathはシリーズDの資金調達で5億6800万ドルを獲得し、評価額は70億ドルを超える

最近、世界をリードするロボティック・プロセス・オートメーション(RPA)プラットフォームであるUiP...

CN2/CUII/CMIN2などの回線を含む、2018年最速の香港VPSのおすすめ

高速香港 VPS / 高速香港 VPS、今年最も速い香港 VPS はどれですか?最速の香港 VPS ...

licloud: 月額 39 ドル、香港物理サーバー、30M 帯域幅、e3-1230v3/16G メモリ/1T ハードディスク

licloud からの公式ニュース: 現在、香港データセンターの約 100 台の物理マシン (香港サ...

2018 年のクラウド コンピューティングの 4 つの意外なトレンド

2018 年は成長が加速する年となり、仮想製品によってデータ漏洩が増加し、クラウド コンピューティン...

クラシックバーチャルホスト: eleven2 - バーチャルホストが 30% オフ

13 年の歴史を持つウェブ ホスティング会社 eleven2 がプロモーションを実施しています。ウェ...

アプリランキングの呪いを解く10のマーケティングプロモーションスキル

それぞれのビジネスモデルの出現は、実生活の延長です。感情的にも地理的にも、人々の日常生活で失われつつ...

天一クラウドは、技術革新を通じて、セキュリティ、信頼性、ユビキタス性、包括性に向けたクラウド開発を推進しています。

5月17日は世界電気通信デーです。中国電信天一クラウドは「赤い雲天一、安全で包括的」をテーマに、オン...

顧客を知る: 2億8,500万ドルの企業からの3つのヒント

テクノロジーは、今日の起業家がビジネス、チーム、業界とつながりを保つ方法を変えています。その中で、よ...

ハイブリッドクラウド環境におけるSASEの3つの大きな課題

ハイブリッド クラウド環境では、新しいセキュリティ保護ツールと新しいネットワーク セキュリティ保護方...

ウェブサイトを盲目的に修正しないでください。いくつかの原則に従う必要があります。

この記事は、ブログ記事「Web サイトの再設計を中止すべきでないとき」の翻訳です。内容は以下のとおり...