Lu Jingshang、Apache ShardingSphereコミッター、SphereExインフラストラクチャR&Dエンジニア、オープンソースおよびデータベーステクノロジーが大好きで、現在はApacheShardingSphereトランザクションモジュールの開発に注力しています。
バックグラウンド
ビジネスの急速な発展、データの継続的な拡大、およびトラフィック負荷の増加に伴い、ビジネスシステムは大きな課題に直面し、データベースシステムのスケーラビリティに対する強い要求を提起しました。Oracle、MySQL、SQL Server、PostgreSQLの従来のスタンドアロンデータベースのオンライン拡張の問題はますます顕著になっています。拡張の問題を解決するために、水平方向にスケーラブルな分散データベースが登場したため、分散トランザクションの問題は直面しなければならない問題になっています。
このコンテキストでは、ShardingSphereは、分散データベース拡張コンピューティングエンジンのセットを提供し、プラグ可能なアーキテクチャを介してデータベースに基づいてエコシステムを構築し、分散トランザクションの機能を提供します。
事業紹介
トランザクションセマンティクス
トランザクションセマンティクスは、原子性、耐久性、一貫性、および分離という4つのプロパティを定義します。
アトミシティ
分散シナリオでは、トランザクションの操作が複数の物理ノードに分散され、複数のノードでの操作が成功するかどうかが保証されます。
耐久性
トランザクションがコミットされた後は、電源がオフになっていてもトランザクションの操作は有効です。
一貫性
注:これはCAP理論のCではありません。CAPのCは、複数のコピー間のデータの一貫性の問題を指します。ここでは、さまざまなレベルの抽象化があります。
ユーザーの観点からは、データはある状態から別の状態に転送され、両方の状態が特定の制約を満たします。例えば:
銀行口座データ、口座Aは500元、口座Bは500元、合計金額は1,000です。トランザクションでは、AとBの転送操作が実行された後、AとBの合計口座は1,000のままです。
隔離
トランザクションが同時に実行される場合、同時実行中にデータの正確性が保証されます。たとえば、2つのトランザクションが同時にデータを変更して、2つのトランザクションが特定の順序で実行されるようにし、データが正しい状態に保たれるようにします。
課題
スタンドアロントランザクションと比較して、分散トランザクションは次の課題に直面します。
-
Atomicity、単一マシントランザクションの場合、undoログとREDOログを使用すると、すべてのコミットまたはすべてのロールバックを保証できます。分散トランザクションには複数の物理ノードが含まれ、各ノードの状況は異なります。一部のノードログは正常に書き込まれ、一部のノードログは正常に書き込まれません。
-
ネットワークが不安定です。1台のマシンの場合、通信は安定しており、成功または失敗に関係なく、すべての操作に応答できます。分散シナリオでは、ネットワークが不安定で、操作に応答できない可能性があります。分散トランザクションの可用性を確保する方法(異常なトランザクションのクリーニングと回復など)が問題になります。
-
MVCCの出現により、同時実行制御は、線形化可能な操作が厳格な要件になりました。スタンドアロンデータベースでは、グローバルに単調に増加するトランザクション数を簡単に生成できますが、分散シナリオでは生成できません。
解決
アトミックコミット
アトミック性とネットワークの不安定性については、現在の主流のソリューションは2PCであり、TM(トランザクションマネージャー)とRM(リソースマネージャー)の2つの役割を定義しています。
分散シナリオでは、トランザクションの操作が複数のノードに分散される場合があり、トランザクション全体が2つのフェーズに分割されます。
-
最初の段階では、RMは関連するリソースをロックして特定の操作を実行し、成功または失敗をTMに返します。
-
第2段階では、TMは第1段階でRMから返された結果を比較します。すべてが成功した場合は、最後のコミット操作(トランザクション状態の変更、ロック状態の削除など)を実行し、障害が発生した場合はロールバックします。 。
注:もちろん、複数のノードを含まないトランザクションの1フェーズコミットへの変換など、いくつかの最適化ポイントがあります。
注:2フェーズ・コミット・プロトコルは、コミットが成功したかどうかにかかわらず、コミットの問題を解決するだけであり、部分的な成功の中間状態はありません。トランザクション分離レベルとは何の関係もありません。
同時実行制御
同時実行制御は、特定の分離レベルで同時に実行されるトランザクションを保証するための実行戦略です。マルチバージョン管理(MVCC)の登場以来、主流のデータベースは以前の2フェーズロックモデルを大幅に放棄してきました。
同時実行制御の本質は、データの読み取りと書き込みの同時実行を制御することです。同時実行制御の戦略によって分離レベルが決まり、同時実行制御は2つの問題を解決する必要があります。
-
MySQLに行ロック(粒度は1行)、テーブルロック(粒度は1テーブル)など、同時実行性の粒度を決定します。
-
3つの同時シナリオの動作:
a。データの変更が含まれないため、読み取りと読み取りの同時実行性。特別な処理は必要ありません。
b。書き込みと書き込みを同時に行うことはできません。同時に行うことはできません。そうしないと、データの混乱が発生します。
c。読み取りと書き込みの同時実行性、パフォーマンスの最適化は主にここで行われ、さまざまな同時実行性制御メカニズムがあり、マルチバージョン同時実行性制御(MVCC)が基本的に選択されます。
MVCC同時実行制御モデル
2つの既存の主流の実装方法があります:
- トランザクションIDとReadViewに基づく
各トランザクションは、トランザクションIDを取得し、トランザクションの開始シーケンスを識別し、アクティブなトランザクションリストからスナップショットを取得し、トランザクションIDをバージョンとして複数のデータを格納して、同時実行制御の効果を実現します。MySQL、Postgres-XLはすべてこのスキームを採用しています。
- タイムスタンプに基づく
タイムスタンプの導入、データへのタイムスタンプ関連の属性の追加、およびデータのcommitT(コミットタイムスタンプ)とスナップショットタイムスタンプを比較することによる可視性の判断により、線形化可能な同時実行制御効果を実現します。スパナのアプローチ。
上記の2つのソリューションは、グローバルトランザクション番号の生成と切り離せません。一般的なグローバルトランザクション番号生成メカニズムには、TrueTime(Spannerで使用)、HLC(CockroachDBでエラーのあるHLC)、およびTSO(Timestamp Oracle)があります。詳細な原則については、を参照してください。参照。
ShardingSphereトランザクション設計
ShardingSphereトランザクション関数は、ストレージDBのローカルトランザクションに基づいて構築され、LOCAL、XA、およびBASEの3つのトランザクションモードを提供します。ユーザーは、ネイティブトランザクションモード(開始/コミット/ロールバック)を使用するだけで、3つのモードを使用できます。 。パフォーマンスとの適切なトレードオフを行います。
ローカル
LOCALモードは、ストレージDBのローカルトランザクションに直接基づいており、特定のアトミックな問題が発生します。もちろん、パフォーマンスは最高です。この問題が許容できる場合は、これが適切な選択です。
シャー
XAモードのXAプロトコルは、2PCによって定義されたインタラクティブプロトコルのセットであり、xa start / prepare / end / commit / rollbackなどのインターフェイスを定義します。一般的に使用される実装にはNarayanaとAtomicsが含まれます。ShardingSphereは、NarayanaとAtomicsのXA実装を統合します。
-
アプリはプロキシに接続し、プロキシはセッションオブジェクトを作成して、この接続にバインドします。
-
アプリはbeginを実行し、プロキシは現在のセッションにバインドされているNarayanaTMを介して新しい論理トランザクションを作成します。
-
アプリは特定のSQLを実行し、セッションはストレージDBへの接続を確立し、Transaction.enlistResource()インターフェイスを介してトランザクションへの接続を登録し、XA START {XID}を実行してトランザクションを開始し、ルーティングリライト後のSQL。
-
アプリはcommitコマンドを実行し、トランザクションに登録されている接続はDB接続を保存し、それぞれxa prepareを実行します。すべての接続がokに戻ったら、トランザクションステータスをpreparedに更新し、各接続はxa commitを実行し、okを返してトランザクションを更新します。ステータスがコミットされ、送信が成功しました。プロセスの準備部分が失敗した場合、ユーザーはrollbackコマンドを使用してロールバックを開始でき、処理されていない場合はバックグラウンドプロセスでクリーンアップします。
-
アプリはrollbackコマンドを実行し、トランザクションに登録された接続はDB接続を保存し、それぞれxarollbackを実行してロールバックします。
ベース
基本(基本的に利用可能、ソフト状態、結果整合性)モード、BASEトランザクションはCAP理論におけるCとAの間のトレードオフの結果であり、SeataのATモードはBaseトランザクションの実装であり、ShardingSphereはSeataのAT実装を統合します。
-
アプリはプロキシに接続し、プロキシはセッションオブジェクトを作成して、この接続にバインドします。
-
アプリはbeginを実行し、プロキシはSeata TMを介して新しい論理トランザクションを作成し、それを現在のセッションにバインドして、SeataServerに登録します。
-
アプリは論理SQLを実行し、セッションはストレージDBへの接続を確立する責任があります。各接続はSeataのConnectionProxyのインスタンスです。ルートが書き換えられた後、実際のSQLを解析し、何らかのインターセプトを実行します。これは変更操作であり、ローカルロックの取得を開始し、SQLを実行し、コミットを実行してローカルロックを解放し、ブランチトランザクションの結果をSeataServerに報告します。
-
アプリはcommitコマンドを実行します。プロキシ内のSeataTMがSeataServerに通知した後、アプリに直接戻ります。SeataServerはプロキシと非同期で対話して、トランザクションログを削除します。
-
アプリはロールバックコマンドを実行します。プロキシ内のSeataTMがSeataServerに通知した後、アプリに直接戻ります。SeataServerはプロキシと非同期で対話し、補正操作を実行し、トランザクションログを削除します。
詳しくは、シータの公式サイトをご覧ください。
使用例
インストールパッケージの準備
紹介する例として、より優れたXAをサポートし、Narayanaを統合する実装を取り上げます。Narayanaのライセンスの問題により、インストールパッケージに直接パッケージ化することはできず、追加の依存関係を追加する必要があります。
公式Webサイトに従ってインストールパッケージをダウンロードし、それを$ {ShardingSphere}ディレクトリに抽出し、次のjarパッケージを$ {ShardingSphere}/libディレクトリに追加します。(ダウンロードアドレス:https ://mvnrepository.com/ )
jta-5.12.4.Final.jar
arjuna-5.12.4.Final.jar
common-5.12.4.Final.jar
jboss-connector-api_1.7_spec-1.0.0.Final.jar | ------------------------------------------------------------------------------------------------------------------------------------
jboss-logging-3.2.1.Final.jar | ------------------------------------------------------------------------------------------------------------------------------------
jboss-transaction-api_1.2_spec-1.0.0.Alpha3.jar | ------------------------------------------------------------------------------------------------------------------------------------
jboss-transaction-spi-7.6.0.Final.jar
mysql-connector-java-5.1.47.jar | ------------------------------------------------------------------------------------------------------------------------------------
narayana-jts-integration-5.12.4.Final.jar
shardingsphere-transaction-xa-narayana-5.1.1-SNAPSHOT.jar
MySQLインスタンスの準備
-
2つのMySQLインスタンス、127.0.0.1:3306、127.0.0.1:3307を準備します。
-
2つのMySQLインスタンスは、それぞれパスワード12345678でユーザーrootを作成します。
-
2つのMySQLインスタンスがそれぞれテストライブラリを作成します。
ShardingSphere-プロキシ構成
server.yamlトランザクション構成を変更します
rules:
- !AUTHORITY
users:
- root@%:root
- sharding@:sharding
provider:
type: ALL_PRIVILEGES_PERMITTED
- !TRANSACTION
defaultType: XA
providerType: Narayana
conf/conf-sharding.yamlを変更します
dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false
username: root
password: 12345678
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
ds_1:
url: jdbc:mysql://127.0.0.1:3307/test?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false
username: root
password: 12345678
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
rules:
- !SHARDING
tables:
account:
actualDataNodes: ds_${0..1}.account${0..1}
tableStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: account_inline
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
defaultDatabaseStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: database_inline
defaultTableStrategy:
none:
shardingAlgorithms:
database_inline:
type: INLINE
props:
algorithm-expression: ds_${id % 2}
account_inline:
type: INLINE
props:
algorithm-expression: account${id % 2}
keyGenerators:
snowflake:
type: SNOWFLAKE
props:
worker-id: 123
ShardingSphere-Proxyを起動します
プロキシを起動するには、次のコマンドを参照してください。
cd ${ShardingSphere}
./bin/start.sh
ShardingSphere-Proxyの使用
MySQLクライアントを使用してShardingSphere-Proxyに接続し、テストします。次のコマンドを参照してください。
mysql -h127.0.0.1 -P3307 -uroot -proot
mysql> use sharding_db;
Database changed
mysql> create table account(id int, balance float ,transaction_id int);
Query OK, 0 rows affected (0.12 sec)
mysql> select * from account;
Empty set (0.02 sec)
mysql> begin;
Query OK, 0 rows affected (0.09 sec)
mysql> insert into account(id, balance, transaction_id) values(1,1,1),(2,2,2);
Query OK, 2 rows affected (0.53 sec)
mysql> select * from account;
+------+---------+----------------+
| id | balance | transaction_id |
+------+---------+----------------+
| 2 | 2.0 | 2 |
| 1 | 1.0 | 1 |
+------+---------+----------------+
2 rows in set (0.03 sec)
mysql> commit;
Query OK, 0 rows affected (0.05 sec)
mysql> select * from account;
+------+---------+----------------+
| id | balance | transaction_id |
+------+---------+----------------+
| 2 | 2.0 | 2 |
| 1 | 1.0 | 1 |
+------+---------+----------------+
2 rows in set (0.02 sec)
将来の計画
現在、ShardingSphereの分散トランザクションは、原子性保証を提供するサードパーティの2PC実装スキームを統合しています。分離は、ストレージDBの分離保証に依存し、使用可能なトランザクション機能を提供します。将来的には、MVCCはグローバルタイムスタンプに基づいて実装され、2PCと組み合わされて、トランザクション分離セマンティクスのサポートが向上します。ShardingSphereの成長に注目してください。
Apache ShardingSphereについて質問や提案がある場合は、GitHubの問題リストに送信するか、中国のコミュニティにアクセスして議論することができます。
GitHubの問題:https ://github.com/apache/shardingsphere/issues
寄稿ガイド:https ://shardingsphere.apache.org/community/cn/contribute/
中国のコミュニティ:https ://community.sphere-ex.com/
参照
1.ACID wiki:https ://en.wikipedia.org/wiki/ACID
2.ANSI分離レベル:https ://renenyffenegger.ch/notes/development/databases/SQL/transaction/isolation-level
3.《分散トランザクションは悪である》:https ://wiki.c2.com/?DistributedTransactionsAreEvil
4.《分散トランザクションと注意すべき理由》:https ://towardsdatascience.com/distributed-transactions-and-why-you-should-care-116b6da8d72
5.《インターネット規模でのフォールトトレラントストリーム処理》:http ://static.googleusercontent.com/media/research.google.com/en/us/pubs/archive/41378.pdf
6.《 Oracle Two Phase Commit 2PCのヒント》:http ://www.dba-oracle.com/t two phase commit 2pc.htm
7.《 2PC:データベースシステムにおける同時実行制御と回復》:https ://courses.cs.washington.edu/courses/cse551/09au/papers/CSE550BHG-Ch7.pdf
8.《インメモリマルチバージョン同時実行制御の実証的評価》:https ://15721.courses.cs.cmu.edu/spring2018/papers/05-mvcc1/wu-vldb2017.pdf
9.《データベースシステムにおける同時実行制御と回復》:https ://courses.cs.washington.edu/courses/cse551/09au/papers/CSE550BHG-Ch7.pdf
10.《楽観的同時実行制御》:https://15721.courses.cs.cmu.edu/spring2018/slides/04-occ.pdf)
11.《塩基:酸の代替物》:https ://queue.acm.org/detail.cfm?id = 1394128
12.《ジェプセン:CockroachDBベータ-20160829》:https ://jepsen.io/analyses/cockroachdb-beta-20160829
13.《スパナ:Googleのグローバル分散データベース》:https ://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf