以前のブログの1つで、MariaDB10.4でリリースされる新機能について説明しました。このバージョンに含まれるのは新しいGaleraClusterリリースであるとそこで述べました。このブログ投稿では、Galera Cluster 26.4.0(またはGalera 4)の機能を確認し、それらを簡単に見て、MariaDBGaleraClusterを使用するときにセットアップにどのように影響するかを調べます。
ストリーミングレプリケーション
Galera Clusterは、スタンドアロンMySQLのドロップイン代替品ではありません。ライトセット認定が機能する方法により、GaleraClusterへの移行機能が大幅に制限される可能性のあるいくつかの制限とエッジケースが発生しました。最も一般的な3つの制限は...
- 長いトランザクションの問題
- 大規模なトランザクションの問題
- テーブルのホットスポットに関する問題
すばらしいのは、Galera 4がストリーミングレプリケーションを導入していることです。これは、これらの制限を緩和するのに役立つ可能性があります。現在の状態をもう少し詳しく見てみましょう。
長時間実行トランザクション
この場合、私たちは時間的に話しているのですが、これはガレラでは間違いなく問題です。理解すべき主なことは、Galeraがトランザクションを書き込みセットとして複製することです。これらのライトセットはクラスターのメンバーで認定されており、すべてのノードが特定のライトセットを適用できるようになっています。問題は、ロックがローカルノードで作成され、クラスター全体に複製されないことです。したがって、トランザクションの完了に数分かかり、複数のGaleraノードに書き込みを行う場合、時間の経過とともに、ロックがオンになる可能性が高くなります。残りのノードの1つであるトランザクションは、実行時間の長いトランザクションで更新された行の一部を変更します。これにより、認証が失敗し、長時間実行されるトランザクションをロールバックする必要があります。つまり、クラスター内の複数のノードに書き込みを送信すると、トランザクションが長くなるほど、競合が原因で認証に失敗する可能性が高くなります。
ホットスポット
つまり、頻繁に更新される行を意味します。通常、これはある種のカウンターであり、何度も更新されています。問題の原因は、長いトランザクションの場合と同じです。行はローカルでのみロックされます。繰り返しになりますが、複数のノードに書き込みを送信すると、同じカウンターが複数のノードで同時に変更され、競合が発生して認証が失敗する可能性があります。
これらの問題の両方に対して、1つの解決策があります。クラスター全体に書き込みを分散するのではなく、1つのノードにのみ書き込みを送信できます。そのためにプロキシを使用できます-ClusterControlはHAProxyとProxySQLをデプロイします。どちらも、書き込みが1つのノードにのみ送信されるように構成できます。 1つのノードにのみ書き込みを送信できない場合は、認証の競合とロールバックが時々発生することを受け入れる必要があります。一般に、アプリケーションはデータベースからのロールバックを処理できる必要があります。これを回避する方法はありませんが、アプリケーションがGaleraClusterで動作する場合はさらに重要です。
それでも、トラフィックを1つのノードに送信するだけでは、3番目の問題を処理するのに十分ではありません。
大規模なトランザクション
覚えておくべき重要なことは、書き込みセットは、トランザクションが完了したときにのみ認証のために送信されるということです。次に、書き込みセットがすべてのノードに送信され、認証プロセスが実行されます。これにより、ライトセットを準備するときに、Galeraがメモリ内のバッファに格納するときに、単一のトランザクションの大きさに制限が生じます。トランザクションが大きすぎると、クラスターのパフォーマンスが低下します。そのため、2つの変数が導入されました。wsrep_max_ws_rowsはトランザクションあたりの行数を制限します(ただし、0に設定できます-無制限)。さらに重要なのは、wsrep_max_ws_sizeで最大2GBに設定できます。したがって、GaleraClusterで実行できる最大のトランザクションのサイズは最大2GBです。また、大規模なトランザクションの認証と適用にも時間がかかり、「ラグ」が発生することを覚えておく必要があります。書き込み後に読み取りを行うと、最初にトランザクションをコミットした場所以外のノードにヒットし、データが正しくなくなる可能性があります。トランザクションはまだ適用中です。
Galera 4には、これらすべての問題を軽減するために使用できるストリーミングレプリケーションが付属しています。主な違いは、書き込みセットを部分に分割できることです。データが複製される前に、トランザクション全体が終了するのを待つ必要がなくなります。これはあなたに不思議に思うかもしれません-そのような場合の認証はどのように見えるのですか?つまり、認証はオンザフライで行われます。各フラグメントが認証され、関連するすべての行がクラスター内のすべてのノードでロックされます。これは、Galeraの動作における重大な変更です。これまで、ロックはローカルで作成され、ストリーミングレプリケーションロックはすべてのノードで作成されます。これは、上記で説明した場合に役立ちます。トランザクションフラグメントが入ってくるときに行をロックすると、トランザクションをロールバックする必要がある可能性を減らすのに役立ちます。ローカルで実行される競合するトランザクションは、必要なロックを取得できず、複製トランザクションが完了して行ロックを解放するのを待つ必要があります。
ホットスポットの場合、ストリーミングレプリケーションを使用すると、行を更新するときにすべてのノードでロックを取得できます。同じ行を更新したい他のクエリは、変更を実行する前に、ロックが解放されるのを待つ必要があります。
大規模なトランザクションは、トランザクション全体が終了するのを待つ必要がなくなり、トランザクションサイズによって制限されなくなるため、ストリーミングレプリケーションのメリットが得られます。大規模なトランザクションは、フラグメントに分割されます。また、ネットワークをより有効に活用するのにも役立ちます。2GBのデータを一度に送信する代わりに、同じ2GBのデータをフラグメントに分割して、より長い期間にわたって送信することができます。
ストリーミングレプリケーションには2つの構成オプションがあります。フラグメントの大きさを示すwsrep_trx_fragment_size(デフォルトでは0に設定され、ストリーミングレプリケーションが無効になっていることを意味します)と、フラグメントの実際のサイズを示すwsrep_trx_fragment_unitです。デフォルトではバイトですが、「ステートメント」または「行」にすることもできます。これらの変数はセッションレベルで設定でき(そして設定する必要があります)、ユーザーがストリーミングレプリケーションを使用してレプリケートする特定のクエリを決定できるようにします。単位を「ステートメント」に設定し、サイズを1に設定すると、たとえば、ホットスポットを更新する単一のクエリに対してのみストリーミングレプリケーションを使用できます。
もちろん、主にクラスター内のすべてのノードでロックが取得されるようになったため、ストリーミングレプリケーションを実行することには欠点があります。大規模なトランザクションが何年にもわたってロールバックされている場合、そのようなトランザクションはすべてのノードでロールバックする必要があります。明らかに、ベストプラクティスは、ロールバックが完了するまでに数時間かかることを回避するために、トランザクションのサイズを可能な限り小さくすることです。もう1つの欠点は、クラッシュリカバリの理由から、各フラグメントから作成されたライトセットがすべてのノードのwsrep_schema.SRテーブルに格納されることです。これにより、一種のダブルライトバッファーが実装され、クラスターの負荷が増加します。したがって、ストリーミングレプリケーションを使用してレプリケートするトランザクションを慎重に決定する必要があります。また、実行可能である限り、小さな短いトランザクションを使用するか、大きなトランザクションを小さなバッチに分割するというベストプラクティスに固執する必要があります。
バックアップロック
最後に、MariaDBユーザーは、SSTのバックアップロックの恩恵を受けることができます。 (MariaDBの場合)mariabackupを使用して実行されるSSTの背後にある考え方は、データセット全体をオンザフライで転送し、REDOログをバックグラウンドで収集する必要があるというものです。次に、グローバルロックを取得して、書き込みが発生しないようにする必要があります。REDOログの最終的な位置を収集して保存する必要があります。歴史的に、MariaDBの場合、ロック部分は読み取りロック付きのフラッシュテーブルを使用して実行されていましたが、高負荷では取得が非常に困難でした。また、かなり重いです。トランザクションはロックが解放されるのを待つ必要があるだけでなく、データをディスクにフラッシュする必要もあります。現在、MariaDB 10.4では、データをフラッシュする必要がなく、ロックの期間中はコミットのみがブロックされる、邪魔にならないバックアップロックを使用できるようになります。これは、邪魔にならないSST操作を意味するはずです。 1つのノードでGaleraClusterを緊急モードで実行し、SSTがクラスターの動作に影響を与えないことを確認しなければならなかったすべての人は、この改善について聞いて喜んでいるはずです。
アプリケーションからの因果的読み取り
Galera 4は、アプリケーションでの因果的読み取りのサポートを追加することを目的とした3つの新しい関数を導入しました。WSREP_LAST_WRITTEN_GTID()は、クライアントによって行われた最後の書き込みのGTIDを返します。WSREP_LAST_SEEN_GTID()は、観測された最後の書き込みトランザクションのGTIDを返します。クライアントとWSREP_SYNC_WAIT_UPTO_GTID()によって、関数に渡されたGTIDがノードでコミットされるまでクライアントをブロックします。もちろん、Galeraで因果関係の読み取りを強制することはできますが、これらの関数を利用することで、Galeraの構成を変更することなく、アプリケーションの必要な部分で書き込み後に安全な読み取りを実装できます。
MariaDBGalera10.4へのアップグレード
Galera 4を試してみたい場合は、MariaDB10.4の最新リリース候補で利用できます。 MariaDBのドキュメントによると、現時点では、10.3ガレラから10.4へのライブアップグレードを行う方法はありません。 10.3クラスター全体を停止し、10.4にアップグレードしてから、再開する必要があります。これは深刻なブロッカーであり、この制限が次のバージョンの1つで削除されることを願っています。ライブアップグレードのオプションを用意することが最も重要であり、そのためには、MariaDB10.3とMariaDB10.4の両方が同じGaleraクラスターに共存する必要があります。別のオプションも適切な場合がありますが、古いガレラクラスターと新しいガレラクラスターの間に非同期レプリケーションを設定することです。
MariaDB 10.4 Galera Clusterの機能のこの短いレビューを楽しんでいただけたことを心から願っています。実際の実稼働環境で、ストリーミングレプリケーションが見られることを楽しみにしています。また、これらの変更がガレラの採用をさらに増やすのに役立つことを願っています。結局のところ、ストリーミングレプリケーションは、人々がガレラに移行するのを妨げる可能性のある多くの問題を解決します。