etcdと分散ロックに関する記事

etcdと分散ロックに関する記事

[[400328]]

1. 分散ロックを実装するためのコンポーネント

分散システムでは、分散ロックを実装するために一般的に使用されるコンポーネントは、Redis、Zookeeper、etcd です。それぞれの特徴を比較すると次のようになります。

上の図は3つのコンポーネントの特性を示しています。その中でも、分散ロックにとって最も重要な点は CP 要件です。ただし、Redis クラスターは CP をサポートしていませんが、AP をサポートしています。公式の redlock ソリューションも提供されていますが、複数のインスタンスの展開 (インスタンスの半分以上が成功と見なされる) が必要なため、展開とメンテナンスが比較的複雑です。したがって、一貫性要件が高いビジネス シナリオ (電子商取引、銀行支払い) では、通常、zookeeper または etcd が選択されます。パフォーマンス、同時実行性、メンテナンスコストを考慮して、Zookeeper と etcd を比較します。 etcd は Go 言語で開発されているため、バイナリ実行ファイルに直接コンパイルされ、他のものに依存しないという利点があります。この記事では、etcd を取り上げ、特定の観点について説明します。

2. APが分散ロックに適さない理由

CAP 理論では、分散システムにおけるマルチノード通信は必然的にネットワーク遅延、パケット損失などの問題につながるため、ネットワーク パーティションが必然的に発生します。ネットワーク分割が発生した場合、通常は CP または AP の 2 つのオプションがあります。

① 分散ロックを実装するために AP モデルを選択した場合、クライアントはクラスターマスターノードのロックに成功した後、すぐにロック成功のフィードバックを受け取ります。このとき、マスター ノードがスレーブ ノードにデータを同期する前にダウンした場合、システムはスレーブ ノードからノードを新しいマスター ノードとして選択します。新しいマスター ノードには古いマスター ノードに対応するロック データがないため、他のクライアントが新しいマスター ノードで同じロックを取得できるようになります。このとき、複数のプロセス/スレッド/コルーチンが同じ重要なリソース データを操作するため、データの不整合などの問題が発生します。

②分散ロックを実装するためにCPモデルを選択します。マスター ノードがデータをスレーブ ノードの半分以上に同期した後にのみ、ロックが成功したと見なされます。このとき、何らかの理由でマスターノードがダウンした場合、システムはデータ損失などの問題を回避するために、スレーブノードからより新しいデータを持つスレーブノードを新しいマスターノードとして選択します。

したがって、分散ロックの場合、データに強力な一貫性要件が課されるシナリオでは、AP モデルは適切な選択ではありません。少量のデータ損失を許容できる場合は、メンテナンス コストなどの理由から、AP モデルの Redis が優先される場合があります。

3. 分散ロックの特徴と動作

分散ロックの場合、操作には次のものが含まれます。

  1. ロックを取得
  2. ロックを解除
  3. ビジネス処理中に、ロックを更新するために別のスレッド/コルーチンが開始されます。

4. etcdについて

公式ドキュメントは常に最高の学習教材です。 etcd の公式紹介には次のように書かれています:

  • 分散システムでは、構成管理、サービス検出、分散作業の調整のための一貫したキー値ストアとして etcd を使用します。多くの組織では、コンテナ スケジューラ、サービス検出サービス、分散データ ストアなどの運用システムを実装するために etcd を使用しています。 etcd を使用する一般的な分散パターンには、リーダー選出、分散ロック、マシン アクティビティの監視などがあります。
  • 分散システムでは、構成管理、サービス検出、分散作業の調整のための一貫したキー値ストアとして etcd を使用します。多くの組織では、コンテナ スケジューラ、サービス検出サービス、分散データ ストレージなどの実稼働システムを実装するために etcd を使用しています。 etcd を使用する一般的な分散パターンには、リーダー選出、分散ロック、マシンの活性状態の監視などがあります。
  • https://etcd.io/docs/v3.4/learning/why/

分散ロックは、etcd が実現できる多くの機能のうちの 1 つにすぎません。サービス登録と検出は、etcd でより多く使用されます。

当局者はまた、多くのコンポーネントを比較し、次のように分類しました。

比較してみると、それぞれの特徴が分かります。どちらを選択するかについては、あなた自身の心の中に答えがあるかもしれません。

5. etcdは分散ロックの関連インターフェースを実装する

分散ロックの場合、etcd の対応する追加、削除、更新インターフェースが主に使用されます。

  1. // KV: キー値関連の操作
  2. タイプKVインターフェース{
  3. // ストレージ。
  4. Put(ctx context.Context、 key 、val string、opts ...OpOption) (*PutResponse、error)
  5. // 得る。
  6. Get(ctx context.Context、キー文字列、opts ...OpOption) (*GetResponse、エラー)
  7. // 消去。
  8. 削除(ctx context.Context、キー文字列、opts ...OpOption) (*DeleteResponse、エラー)
  9. // rev で指定されたバージョンより前の履歴データを圧縮します。
  10. Compact(ctx context.Context, rev int64, opts ...CompactOption) (*CompactResponse, error)
  11. // 操作セットを走査するために使用できる一般的な操作実行コマンド。 Put/Get/ Deleteも Do に基づいています。
  12. Do(ctx context.Context, op Op) (OpResponse, error)
  13. // トランザクションを作成します。If/ Then / Else / Commit操作のみをサポートします。
  14. Txn(ctx コンテキスト.コンテキスト) Txn
  15. }
  16.  
  17.  
  18. // リース: リース関連の操作
  19. リースインターフェース型{
  20. // リースを割り当てます。
  21. 許可(ctx context.Context、ttl int64) (*LeaseGrantResponse、エラー)
  22. // リースを解放します。
  23. 取り消し(ctx context.Context、id LeaseID) (*LeaseRevokeResponse、エラー)
  24. // 残りの TTL 時間を取得します。
  25. TimeToLive(ctx context.Context、id LeaseID、opts ...LeaseOption) (*LeaseTimeToLiveResponse、エラー)
  26. // すべてのリースを取得します。
  27. リース(ctx context.Context) (*LeaseLeasesResponse, エラー)
  28. // 更新は引き続き有効です。
  29. KeepAlive(ctx context.Context, id LeaseID) (<-chan *LeaseKeepAliveResponse, error)
  30. // アクティベーションを 1 回だけ更新します。
  31. KeepAliveOnce(ctx context.Context、id LeaseID) (*LeaseKeepAliveResponse、エラー)
  32. // 更新アクティベーション機能を無効にします。
  33. 閉じる()エラー
  34. }

6. etcd分散ロックコードの例

  1. パッケージメイン
  2.  
  3. 輸入 (
  4. "コンテクスト"  
  5. 「fmt」  
  6. 「go.etcd.io/etcd/clientv3」  
  7. "時間"  
  8.  
  9. var conf clientv3.Config
  10.  
  11. // ロック構造
  12. EtcdMutex 構造体型 {
  13. Ttl int64 //リース時間
  14.  
  15. Conf clientv3.Config //etcd クラスター構成
  16. キー文字列//etcdキー 
  17. キャンセルcontext.CancelFunc //更新関数を閉じる
  18.  
  19. txn クライアントv3.Txn
  20. リースクライアントv3.リース
  21. リースID クライアントv3.リースID
  22. }
  23.  
  24. // ロックを初期化する
  25. func (em *EtcdMutex) init() エラー {
  26. var err エラー
  27. var ctx コンテキスト.コンテキスト
  28.  
  29. クライアント、エラー:= clientv3.New(em.Conf)
  30. err != nil の場合 {
  31. エラーを返す
  32. }
  33.  
  34. em.txn = clientv3.NewKV(クライアント).Txn(コンテキスト.TODO())
  35. em.lease = clientv3.NewLease(クライアント)
  36. リース応答、エラー := em.lease.Grant (context.TODO()、em.Ttl)
  37.  
  38. err != nil の場合 {
  39. エラーを返す
  40. }
  41.  
  42. ctx、em.cancel = context.WithCancel(context.TODO())
  43. em.leaseID = リース応答ID
  44. _, エラー = em.lease.KeepAlive(ctx, em.leaseID)
  45.  
  46. エラーを返す
  47. }
  48.  
  49. // ロックを取得する
  50. func (em *EtcdMutex) Lock() エラー {
  51. エラー:= em.init()
  52. err != nil の場合 {
  53. エラーを返す
  54. }
  55.  
  56. // ロック
  57. em.txn.If(clientv3.Compare(clientv3.CreateRevision( em.Key ), "=" , 0))。
  58. 次に、 (clientv3.OpPut(em.Key , " " , clientv3.WithLease(em.leaseID))) を実行します。それ以外()
  59.  
  60. txnResp、エラー:= em.txn。専念()
  61. err != nil の場合 {
  62. エラーを返す
  63. }
  64.  
  65. // txn.if 条件が真かどうかを判定する
  66. !txnResp.Succeeded の場合 {
  67. return fmt.Errorf( "ロックを取得できませんでした" )
  68. }
  69.  
  70. ゼロを返す
  71. }
  72.  
  73. //ロックを解除する
  74. func (em *EtcdMutex) UnLock() {
  75. // リースは自動的にすぐに期限切れになります
  76. // cancel は更新をキャンセルし、 revoke即時に期限切れになります
  77. em.キャンセル()
  78. リース。取り消し(context.TODO()、em.leaseID)
  79.  
  80. fmt.Println( "ロックが解除されました" )
  81. }
  82.  
  83. // グラウチン1
  84. try2lock1()関数{
  85. eMutex1 := &EtcdMutex{
  86. 会議: 会議、
  87. 合計: 10,
  88. キー 「ロック」
  89. }
  90.  
  91. エラー:= eMutex1.Lock()
  92. err != nil の場合 {
  93. fmt.Println( "groutine1 はロックを取得できませんでした" )
  94. 戻る 
  95. }
  96. eMutex1.UnLock() を延期する
  97.  
  98. fmt.Println( "groutine1 はロックを正常に取得しました" )
  99. 時間.スリープ(10 *時間.)
  100. }
  101.  
  102. // グルーティン2
  103. try2lock2()関数{
  104. eMutex2 := &EtcdMutex{
  105. 会議: 会議、
  106. 合計: 10,
  107. キー 「ロック」
  108. }
  109.  
  110. エラー:= eMutex2.Lock()
  111. err != nil の場合 {
  112. fmt.Println( "groutine2 はロックを取得できませんでした" )
  113. 戻る 
  114. }
  115.  
  116. eMutex2.UnLock() を延期する
  117. fmt.Println( "groutine2 はロックを正常に取得しました" )
  118. }
  119.  
  120. // テストコード
  121. EtcdRunTester()関数 {
  122. conf = クライアントv3.Config{
  123. エンドポイント: []string{ "127.0.0.1:2379" },
  124. ダイヤルタイムアウト: 5 *時間 2番
  125. }
  126.  
  127. // ロックを競うために2つのコルーチンを開始する
  128. try2lock1() を実行する
  129. try2lock2() を実行する
  130.  
  131. 時間.スリープ(300 *時間.)
  132. }

要約する

分散ロック機能を提供できるコンポーネントは多数ありますが、それぞれに独自の性質と個性があります。どのコンポーネントを選択するかは、ビジネスにとってのデータの重要性に応じて異なります。データに強力な一貫性が必要な場合は、CP をサポートする etcd と zookeeper が推奨されます。少量のデータ損失が許容され、強力な一貫性が要求されない場合は、AP をサポートする Redis が推奨されます。

<<:  Centos8にVDOをインストールして設定し、ストレージスペースを最適化する

>>:  フランスは、GoogleとMicrosoftのクラウドサービスが機密データを処理できると述べている

推薦する

企業に利益をもたらすクラウドコンピューティングの利点とは

クラウド コンピューティングは成長を続けており、中小企業に多くの機能を提供しています。クラウド コン...

spartanhost-2.5USD/KVM/シアトル/512MB RAM/Windows/無料 DDoS 保護

少しニッチな安価な KVM 仮想 VPS をお探しの場合は、シアトル データ センター、1 Gbps...

SEOウェブサイトを再設計する際にSEO担当者が知っておくべきこと

最近、自分のウェブサイトの見栄えが悪く、改修が必要だと感じる学生もいます。Wangqi SEO は、...

リンク構築の失敗の理由を分析する

「なぜ私のリンク構築はいつも失敗するのか?」「なぜ私の SEO 最適化は成功しないのか?」このような...

extravm: シンガポール VPS - 60% オフ、月額 5 ドルから、Ryzen 9 7900 + 10Gbps 帯域幅 + 無制限の高防御、モバイル回線に最適

現在、extravmのシンガポールデータセンターのVPS再入荷が40%オフで販売されています。新しい...

下流市場:テンセントが7位、ピンドゥオドゥオが4位

「沈む」というのは無力な選択であり、誰も「沈む」ことを望んでいません。これは、私が7歳のときに尊敬し...

NodePacket - $4 / 256M RAM / 15G SSD / 500G

NodePacket LLC は 20013 年に設立されたホスティング会社で、VPS およびサーバ...

QQグループのプロモーション戦略の手順とガイドラインは非常に効率的です

前に書かれた言葉:ウェブサイトを立ち上げた後、最も重要なのは良質なコンテンツに基づいたプロモーション...

アプリ成長レポート: 1月のゲーム業界の購入傾向と嗜好の分析

2018 年を迎え、ゲーム配信にはどのような新しいトレンドや変化があるのでしょうか? 業界の配信トレ...

ウェブサイトのデザイン: ウェブフローチャートの描き方ガイド

編集者注: この記事の著者はデザイナーの Felix Ding、Ding Yu です。著者がフローチ...

DingTalk 6.0 製品エクスペリエンス: 削減と個人のユーザーエクスペリエンスの重視

[51CTO.comよりオリジナル記事] DingTalkは先日、バージョン6.0を正式にリリースし...

簡単な分析: Baidu 入札ランディング ページ効果分析

数日前、私は「Baidu 入札の単位原価計算」と「Baidu 入札の図解分析: 期間分析」という 2...

Momoが参入、Toutiaoが出資比率を引き上げ、オンライン読書トラフィックを競う

トラフィックが低迷しているオンライン読書市場には、 Momoが参入し、 Toutiaoがさらなる投資...

ウィトキー産業の「不十分な」発展を4つの視点から分析する

中国のインターネットユーザー数が5億人に達したため、中国のインターネットの発展は新たなレベルに達しま...

PIAYUN:国慶節特別オファー、香港\米国クラウドサーバー、CN2回線、月額20元から、時間は2倍

今年の国慶節に向けて、Piayunは香港クラウドサーバーと米国クラウドサーバーの限定版をリリースしま...