2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
リンクをコピー
記事をブックマーク
水戸部章生氏:(スライドを指して)こちらのバッチクライアント側からTiKVに、Raft側に処理を流して、Raftは受け取ったデータをそれぞれしっかりとコピーして整合性を保つとされていますが、本日はこのトランザクションについて紹介しようと思っています。
TiDBのトランザクションはもちろん、MVCC(MultiVersion Concurrency Control)で実現している分散型のデータベースです。このMVCCを実現するための技術キーポイント5つを紹介します。
先ほど名前が出ていましたが、1つ目がGoogle Percolatorと呼ばれる技術、2つ目がTimestamp Oracleです。3つ目はかなり前から提唱されているTwo Phase Commit、4つ目と5つ目はCompare And SwapとTime To Liveです。TiDBのトランザクションは、この5つで支えられています。
簡単なトランザクションの流れです。(スライドを指して)こちらは、私のPCで実際にやったものです。1つ目にMySQLと書いてありますが、TiDBです。先ほどMySQLのインターフェイスを持っていると紹介しましたが、このようなかたちで普通のBEGIN、select、updateと、同じコマンドが叩けます。
今回は、BEGINの後ろに楽観を意味するoptimisticをつけていますが、selectをしたあとupdateをして、commitする簡単なトランザクションの流れを実施しています。このトランザクションを実施すると、フィジカルの部分では実際にどのようなやり取りになっているかを、次のスライドに書いています。
(スライドを指して)左から右がトランザクションの流れです。まず、TiDBからstart_tsというかたちでBEGINを発行すると、Placement DriverからStart TSOと呼ばれるタイムスタンプを取得します。この取得が終わると、selectをする時にRaftを使っているので、どこにデータがあるかをPlacement Driverから取得します。
この取得が終わると、タイムスタンプを使ってスナップショットされたデータ、自分の位置がどこにあるかを確認した上でデータの読み込みが始まります。
本当はselectなどがありますが、updateしてデータを書き込むと、TiDBのメモリバッファ内にすべて書き込んだあと、バッチ処理するために必要なキーをまとめあげるなどして、次のcommitの処理に備えます。
次はcommitの処理です。先ほど1文でcommitと書きましたが、commitとしてはTwo Phase Commitを採用しています。分散型だと必須かと思いますが、最初にprewriteが発行されます。このprewrite時に、まずCAS(Compare And Swap)と呼ばれるメモリにスナップショットしたデータを配置します。そのあと、PercolatorによるSnapshot isolationとTTLを設定します。TTLを設定することによって、トランザクションが生きている間にTTLを延長します。トランザクションが消失した際にはTTLが無効になり、ほかのトランザクションが読み込みにいけるような設定になっています。
(スライドを指して)prewriteですが、すべてのキーに対してprewriteでロックを取得できると、次のcommitのフェーズに移れます。ただし、ロックを取得できないと、この時点でデータのロールバックが始まります。
無事にそれぞれのロックが取得できた際には、commitフェーズに移ります。commitフェーズは、さらにTSOタイムスタンプをPlacement Driverから取得し、取得したTSOを使って、それぞれのデータを書き込んでいきます。(スライドを指して)ここにCASによるデータのチェックと書いていますが、こちらは特に楽観処理の時に使います。のちほどスライドで詳しく紹介するので、ここでは割愛します。
最後にPrimaryKeyのロックの解除が終わるとcommitが完了し、クライアントに処理が戻るのが、一般的なTiDBのトランザクションの流れです。
本日は、詳細というより、全体の流れの中でどのような技術が使われてるかを紹介しようと思っています。(スライドを指して)少しわかりづらいと思うので、右上にトランザクション処理の中の、どの部分に位置するか書いています。この数字は最初にあったキー技術のどの番号かを意味しています。
1つ目はGoogle Percolatorによるスナップショット作成です。Google検索インデックスの更新に使用されるようなアーキテクチャーですが、TiDBの場合はこちらを使用しています。使用しているColumn Familyと呼ばれるそれぞれのcolumnを用意し、役割を持たせてスナップショットを取得するようなアーキテクチャーですが、TiKVではData、Lock、Writeの3つを使用しています。
(スライドを指して)こちらが、特定のキーのデータの持ち方です。まず、Keyと呼ばれる主となるキーがあります。Keyの次にDataとあります。のちほど紹介しますが、こちらのTSOというタイムスタンプで、それぞれData、Lock、Writeというかたちで1つのレコードを作っていきます。
今は$10というデータが存在していますが、この2つ目がcommitした際に出てくるデータです。commitすると5番目が今確定しているようなデータになっています。ほかのトランザクションがデータを読みにくる時には5番が確定しているので、10番を読み込みにいくような流れになります。
一番上がprewriteしている状態です。先ほどprewriteの際にはロックを取得する必要があると紹介しましたが、このロックの部分にprimary、もしくはほかのセカンダリであればprimaryのキー名を書いてロックを取得します。ロックがある時はまだprewriteが行われている状態で、それぞれのisolationレベルを分けてデータを持つような構造になっています。
この下で1つ特徴を挙げれば、CF_LockにTTLを入れるようになっています。このTTLものちほど紹介するので、ここではこのようなデータが入っていることを理解してもらえればと思います。また、CF_Writeのステータス情報も使って、ステータス情報の管理をしています。
2つ目はTSOです。commitの時に取得したTSO(Timestamp Oracle)はデータ不整合が起こるケースをすべてサポートするために、タイムスタンプを採用しています。先ほどGoogle Percolatorによるスナップショットと取得を紹介しましたが、スナップショットで不整合の起こるパターンのどこをサポートしているかと言うと、Dirty WriteやFuzzy Read、Lost Updateです。これらのケースに関してはサポートできています。
ただ、Write Skewと呼ばれるデータ不整合は、時系列で管理しないと発生してしまうので、これをサポートするためにTimestamp Oracleラインナブルの制御を入れています。
先ほどの基本的なトランザクションの処理にもありましたが、TiDBとPDでタイムスタンプを取得して、タイムスタンプにしたがって先ほどのスナップショットのレコードを作っていきます。Timestamp Oracleの番号は、Int64のシステム全体でユニーク値を必ず発行する仕組みになっています。
3つ目は、Two Phase Commitです。やはりGoogle Percolatorでは必須と思われるTwo Phase Commitも実装しています。先ほど紹介したとおり、例えば Bobが3ドル送り、Joeから9ドルにするという、BobからJoeに7ドル送るようなトランザクションがあった時、まずprewriteを実施します。(スライドを指して)こちらはprewriteの状態ですが、ノードが別々になっているので、ノード間でしっかりとデータの整合性を保つことが必要です。
まず、BobではTSO7(タイムスタンプ7を取得した)として、7ではデータ3を入れ込むとLockでprewrite状態です。Writeにはまだ何も書いていない状態です。Joeの状態に関しても9ドルを入れます。LockにはPrimary@Bob balと書いてありますが、Bobをprimaryとしたロックを取得し、7はない状態でprewriteが完了します。
ロックがすべて取得できれば、次のcommit処理にいきます。ロックがすでに1つでも取られている場合はロールバックというかたちになります。(スライドを指して)実際このcommit処理を行うと、次はどのような処理になるかがこちらの絵ですが、commitのTSOを再度取得して8番目のcommit処理に走ります。
prewriteが終わったあとには、commitがほぼ確定で走るようになっています。こちらに8、8とありますが、7が最新のデータとして、7番が記録されます。
(スライドを指して)こちらのJoeのところにもTSO7が最新のデータとして書き込まれ、この下のTSO7のPrimary Lockが消えるようになっています。primaryのLockだけ最初に削除して、Lockが終わるとTiDBはcommit処理が終わったとして返します。後ろに関しては、のちほど処理をするような流れです。
4つ目は、スナップショットのCAS(Compare And Swap)という機能です。スナップショットを取る際のデータをCASと呼ばれるOSの命令に入れるようになっています。(スライドを指して)こちらではkey=Bob, Data=5となっていますが、スナップショットを取った段階では同じデータです。基本的には、TiDBのデータ自体はオンメモリ上で更新します。
メモリ上で更新すると、トランザクション1とトランザクション2のどちらが更新したかがわからなくなります。その際に、CASの中でデータを入れ込みます。CASはマルチスレッド対応であり、一度データを書き込むと、次に書き込もうとしたトランザクションにエラーを返すような仕組みになっています。
先にデータがcommitされていると、次にデータが来た時、すでにそのデータは書き込まれている状態になります。楽観Lockでデータを持ってきても、ほかのトランザクションがすでにcommit処理していることに気づけるので、その時点でロールバックします。TiDBの場合はリトライ1になっているので、楽観Lockならもう一度commit処理(データのやり直し)をするのがCASの機能です。
5つ目は、TTLによるトランザクション制御です。トランザクションがTTLを確認して、ノードダウン時などに検知する仕組みです。先ほど紹介したPercolatorのロックのところに入っているTTLですが、heartbeatでTTLのexpireを伸ばす処理をします。このexpireが切れると、すでにLockがなくなっていると判断し、ほかのトランザクションがデータを更新できるような仕組みになっています。
(次回につづく)
関連タグ:
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.10
職場であえて「不機嫌」を出したほうがいいタイプ NOと言えない人のための人間関係をラクにするヒント
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み
PR | 2024.11.22
「闇雲なAI導入」から脱却せよ Zoom・パーソル・THE GUILD幹部が語る、従業員と顧客体験を高めるAI戦略の要諦
PR | 2024.11.26
なぜ電話営業はなくならない?その要因は「属人化」 通話内容をデータ化するZoomのクラウドサービス活用術