いつもお世話になっています。

この度Raftを用いた分散KVSを実装しているのですが、トランザクションの扱いで疑問があったので質問させていただきます。

https://qiita.com/kumagi/items/f9aee47b69ebdba5da17

以前kumagiさんのこちらの記事ACIDを達成するには最低限S2PLが必要という理解をしておりました。

しかし、Spanner alternativeであるところのTiDBは2PSを用いていると言ってます。

https://docs.pingcap.com/ja/tidb/stable/optimistic-transaction

これは以下のいずれかであると思っています。

・ Raftの層である程度の Durability やConsistency を保証しているから2PSで十分

・実際にはS2PLだが2PLと説明している

・Durability を一部諦めている(考えにくいですが)

そこで私は、「2PSとRaftの組み合わせであればACIDを達成できる」のでは?思いkumagiさんにお聞きしたく質問させていただきました。

こちらについてご意見をいただきたいです。

質問ありがとうございます。いくつか質問の内容がわからない所があったので少し考えていました。

TiDBの記事を読みましたが2PLとは書いておらず2PCとその内部での挙動に関する話でレイヤーが異なるようです。2 Phase Lock (2PL)と2 Phase Commit (2PC)は字面こそ大変良く似ていますが2PLはロックのComposabilityを応用したトランザクションの実現手法である一方で、2PCは故障を度外視したまま設計されたデータ複製に過ぎず、適用する対象も導入する目的もまるで異なるものです。

このTiDBの記事では事前書き込みリクエストを対象ノードすべてに送った後にコミットを改めて対象ノードすべてに送る2フェーズからなるので正しく2PCであるようです。そしてこれはロックの成長相と縮退相の2つから成るという点でも2PLでもあります。そして問題はこれがS2PLであるかどうかです。

Raftの層である程度の Durability やConsistency を保証しているから2PSで十分

Raft自体にDurabilityを保証する機能はありません。Raft自体がデータを永続化し続けるステートマシンを前提としているからです。2PSというのが何なのかわからないですが2PLだとしても2PCだとしてもRaftだから十分という話にはなりません。

実際にはS2PLだが2PLと説明している

これはこの文書に限らずとても良くあるパターンです。Strict 2PLと2PLをわざわざ分けて論じる必要がある時は永続性と一貫性に焦点を当てた話をする時であって、2PLと書かれている文章はおよそS2PLの事を指している事が多いです。

Durability を一部諦めている(考えにくいですが)

これは無さそうです。 TiDBの記事を読む限り「事前書き込み」が全部成功した場合に限り次のフェーズに進むそうですし、事前書き込みを永続化していないケースは無いのではないかと思います。S2PLはロックの解除前に永続化を済ませている事が条件なので「事前書き込み」が永続化されているならばこれは広義のS2PLと呼んで差し支えありません。

ここで問題になるのが何をもって「永続化」と呼ぶかという話で、直感的にはディスク書込の事を言うことがほとんどですが、もう少し考え方を拡張すると「システムが想定する範囲の障害があってもデータを失わない事」と言い換える事ができます。そもそもディスクに書き込んでもディスクごと吹き飛んだ(これはシステムが想定していない範囲の障害)ら意味がないですし、これまでは電源断からの復旧に耐えることをもって永続化と呼ぶケースが主でした。

Raftを用いた分散システムにおける「永続化」とはRaftが想定する範囲の障害つまり少数ノードの故障や離脱に耐える事であって必ずしもディスクに書き込むことを想定していない可能性もあります。TiDBはRaftで複製され永続性が保証されたストレージ(TiKV)の上に2PCなどのプロトコルを用いて複数データにまたがる一貫性を実現する構造になっていて、上下で役割を分担しています。そしてこの記事を読む限りは永続性に関してはTiKV側に任せていると取れるので実際の所S2PLに近いことが行われていると思われます。

10か月10か月更新

利用規約プライバシーポリシーに同意の上ご利用ください

熊崎 宏樹さんの過去の回答
    Loading...