sql >> データベース >  >> RDS >> Mysql

データベースプロキシのフェイルオーバー時間の比較-ProxySQL、MaxScale、HAProxy

    ClusterControlを使用して、可用性の高いレプリケーションセットアップをデプロイできます。 GTIDベースのMySQLまたはMariaDBレプリケーションセットアップのスイッチオーバーとフェイルオーバーをサポートします。 ClusterControlは、トラフィックルーティング用にさまざまなタイプのプロキシ(ProxySQL、HAProxy、MaxScale)をデプロイできます。これらは、フェイルオーバーまたはスイッチオーバーに関連するトポロジー変更を処理するために統合されています。このブログ投稿では、これがどのように機能し、各プロキシに何が期待できるかを見ていきます。

    まず、いくつかの定義と用語を見ていきましょう。 ClusterControlは、障害が発生したレプリケーションマスターのリカバリを実行するように構成できます。これにより、スレーブを新しいマスターに昇格させ、必要なトポロジ変更を行い、セットアップ全体の書き込みを受け入れる機能を復元できます。これを「フェイルオーバー」と呼びます。 ClusterControlはマスタースイッチを実行することもできます。マスターを変更する必要がある場合もあります。典型的なシナリオは、スキーマの大幅な変更であり、ローリング方式で実行する必要があります。手順の終わりに向かって、古いマスターで変更を実行する前に、すでに変更が適用されているスレーブの1つを昇格させる必要があります。

    「フェイルオーバー」と「スイッチオーバー」の主な違いは、フェイルオーバーは、定義上、マスターがすでに使用できない緊急事態であるということです。一方、スイッチオーバーは、ClusterControlが完全に制御できるより制御可能なプロセスです。フェイルオーバーについて話している場合、マスターのクラッシュのためにアプリケーションがすでに接続を失っているため、フェイルオーバーを適切に処理する方法はありません。そのため、使用するプロキシに関係なく、アプリケーションは常に再接続する必要があります。

    したがって、アプリケーションはトランザクションの失敗を処理して再試行できる必要があります。フェイルオーバーについて話すときのもう1つの重要なことは、データベースサーバーの状態をチェックするプロキシの機能です。ヘルスチェックがないと、プロキシはサーバーのステータスを知ることができないため、トラフィックのフェイルオーバーを決定できません。 ClusterControlは、プロキシをデプロイするときにこれらのヘルスチェックを自動的に構成します。

    フェイルオーバー

    ProxySQL

    アプリケーションの観点から、フェイルオーバーがどのように見えるかを見てみましょう。まず、ProxySQLバージョン1.4.6を使用してデータベースに接続します。

    [email protected]:~# while true  ;do time sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --max-requests=0 --time=3600 --mysql-host=10.0.0.105 --mysql-user=sbtest --mysql-password=pass --mysql-port=6033 --tables=32 --report-interval=1 --skip-trx=on --table-size=10000 --db-ps-mode=disable run ; done
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    Threads started!
    
    [ 1s ] thds: 4 tps: 29.51 qps: 585.28 (r/w/o: 465.27/120.01/0.00) lat (ms,95%): 196.89 err/s: 0.00 reconn/s: 0.00
    [ 2s ] thds: 4 tps: 44.61 qps: 784.77 (r/w/o: 603.28/181.49/0.00) lat (ms,95%): 116.80 err/s: 0.00 reconn/s: 0.00
    [ 3s ] thds: 4 tps: 46.98 qps: 829.66 (r/w/o: 646.74/182.93/0.00) lat (ms,95%): 121.08 err/s: 0.00 reconn/s: 0.00
    [ 4s ] thds: 4 tps: 49.04 qps: 886.64 (r/w/o: 690.50/195.14/1.00) lat (ms,95%): 112.67 err/s: 0.00 reconn/s: 0.00
    [ 5s ] thds: 4 tps: 47.98 qps: 887.64 (r/w/o: 689.72/197.92/0.00) lat (ms,95%): 106.75 err/s: 0.00 reconn/s: 0.00
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'UPDATE sbtest8 SET k=k+1 WHERE id=5019'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:461: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'DELETE FROM sbtest6 WHERE id=4957'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:490: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'SELECT SUM(k) FROM sbtest23 WHERE id BETWEEN 4986 AND 5085'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:435: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'DELETE FROM sbtest21 WHERE id=5218'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:490: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    
    real    0m5.903s
    user    0m0.092s
    sys    0m1.252s
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 6033, aborting...
    FATAL: error 2003: Can't connect to MySQL server on '10.0.0.105' (111)
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 6033, aborting...
    FATAL: error 2003: Can't connect to MySQL server on '10.0.0.105' (111)
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 6033, aborting...
    FATAL: error 2003: Can't connect to MySQL server on '10.0.0.105' (111)
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 6033, aborting...
    FATAL: error 2003: Can't connect to MySQL server on '10.0.0.105' (111)
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: Threads initialization failed!
    
    real    0m0.021s
    user    0m0.012s
    sys    0m0.000s
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    Threads started!
    
    [ 1s ] thds: 4 tps: 0.00 qps: 55.81 (r/w/o: 55.81/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 2s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 3s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 4s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 5s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 6s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 7s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 8s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 9s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 10s ] thds: 4 tps: 0.00 qps: 3.00 (r/w/o: 0.00/3.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 11s ] thds: 4 tps: 58.99 qps: 1026.91 (r/w/o: 792.93/233.98/0.00) lat (ms,95%): 9977.52 err/s: 0.00 reconn/s: 0.00

    上記からわかるように、新しいマスターはクラッシュから約11秒以内に使用可能になりました。この間、ClusterControlはスレーブの1つを新しいマスターに昇格させ、書き込みに使用できるようになりました。

    HAProxy

    以下は、HAProxy経由で接続しているときにフェイルオーバーが発生したときのsysbenchアプリケーションの出力からの抜粋です。 HAProxyはバージョン1.5.14でデプロイされました。

    [email protected]:~# while true  ;do date ; time sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --max-requests=0 --time=3600 --mysql-host=10.0.0.105 --mysql-user=sbtest --mysql-password=pass --mysql-port=3307 --tables=32 --report-interval=1 --skip-trx=on --table-size=10000 --db-ps-mode=disable run ; done
    Mon Mar 26 13:24:36 UTC 2018
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    Threads started!
    
    [ 1s ] thds: 4 tps: 38.62 qps: 748.66 (r/w/o: 591.21/157.46/0.00) lat (ms,95%): 204.11 err/s: 0.00 reconn/s: 0.00
    [ 2s ] thds: 4 tps: 45.25 qps: 797.34 (r/w/o: 619.37/177.97/0.00) lat (ms,95%): 142.39 err/s: 0.00 reconn/s: 0.00
    [ 3s ] thds: 4 tps: 46.04 qps: 833.66 (r/w/o: 647.51/186.15/0.00) lat (ms,95%): 155.80 err/s: 0.00 reconn/s: 0.00
    [ 4s ] thds: 4 tps: 38.03 qps: 698.50 (r/w/o: 548.39/150.11/0.00) lat (ms,95%): 161.51 err/s: 0.00 reconn/s: 0.00
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'INSERT INTO sbtest26 (id, k, c, pad) VALUES (5019, 4641, '59053342586-08172779908-92479743240-43242105725-10632773383-95161136797-93281862044-04686210438-11173993922-29424780352', '31974441818-04649488782-29232641118-20479872868-43849012112')'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:491: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'INSERT INTO sbtest5 (id, k, c, pad) VALUES (4990, 5016, '24532768797-67997552950-32933774735-28931955363-94029987812-56997738696-36504817596-46223378508-29593036153-06914757723', '96663311222-58437606902-85941187037-63300736065-65139798452')'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:491: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'DELETE FROM sbtest25 WHERE id=4996'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:490: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    FATAL: mysql_drv_query() returned error 2013 (Lost connection to MySQL server during query) for query 'UPDATE sbtest16 SET k=k+1 WHERE id=5269'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:461: SQL error, errno = 2013, state = 'HY000': Lost connection to MySQL server during query
    
    real    0m4.270s
    user    0m0.068s
    sys    0m0.928s
    
    ...
    
    Mon Mar 26 13:24:47 UTC 2018
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 3307, aborting...
    FATAL: error 2013: Lost connection to MySQL server at 'reading initial communication packet', system error: 0
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 3307, aborting...
    FATAL: error 2013: Lost connection to MySQL server at 'reading initial communication packet', system error: 2
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 3307, aborting...
    FATAL: error 2013: Lost connection to MySQL server at 'reading initial communication packet', system error: 2
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: unable to connect to MySQL server on host '10.0.0.105', port 3307, aborting...
    FATAL: error 2013: Lost connection to MySQL server at 'reading initial communication packet', system error: 2
    FATAL: `thread_init' function failed: /usr/local/share/sysbench/oltp_common.lua:352: connection creation failed
    FATAL: Threads initialization failed!
    
    real    0m0.036s
    user    0m0.004s
    sys    0m0.008s
    
    ...
    
    Mon Mar 26 13:25:03 UTC 2018
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    Threads started!
    
    [ 1s ] thds: 4 tps: 50.58 qps: 917.42 (r/w/o: 715.10/202.33/0.00) lat (ms,95%): 153.02 err/s: 0.00 reconn/s: 0.00
    [ 2s ] thds: 4 tps: 50.17 qps: 956.33 (r/w/o: 749.61/205.72/1.00) lat (ms,95%): 121.08 err/s: 0.00 reconn/s: 0.00

    合計で、プロセスには12秒かかりました。

    MaxScale

    MaxScaleがフェイルオーバーを処理する方法を見てみましょう。 MaxScaleはバージョン2.1.9で使用しています。

    [email protected]:~# while true ; do date ; time sysbench /root/sysbench/src/lua/oltp_read_write.lua --threads=4 --max-requests=0 --time=3600 --mysql-host=10.0.0.106 --mysql-user=myuser --mysql-password=pass --mysql-port=4008 --tables=32 --report-interval=1 --skip-trx=on --table-size=100000 --db-ps-mode=disable run ; done
    Mon Mar 26 15:16:34 UTC 2018
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    Threads started!
    
    [ 1s ] thds: 4 tps: 34.82 qps: 658.54 (r/w/o: 519.27/125.34/13.93) lat (ms,95%): 137.35 err/s: 0.00 reconn/s: 0.00
    [ 2s ] thds: 4 tps: 35.01 qps: 655.23 (r/w/o: 513.18/142.05/0.00) lat (ms,95%): 207.82 err/s: 0.00 reconn/s: 0.00
    [ 3s ] thds: 4 tps: 39.01 qps: 696.16 (r/w/o: 542.13/154.04/0.00) lat (ms,95%): 139.85 err/s: 0.00 reconn/s: 0.00
    [ 4s ] thds: 4 tps: 40.91 qps: 724.41 (r/w/o: 557.77/166.63/0.00) lat (ms,95%): 125.52 err/s: 0.00 reconn/s: 0.00
    FATAL: mysql_drv_query() returned error 1053 (Server shutdown in progress) for query 'UPDATE sbtest28 SET k=k+1 WHERE id=49992'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:461: SQL error, errno = 1053, state = '08S01': Server shutdown in progress
    FATAL: mysql_drv_query() returned error 1053 (Server shutdown in progress) for query 'UPDATE sbtest14 SET k=k+1 WHERE id=59650'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:461: SQL error, errno = 1053, state = '08S01': Server shutdown in progress
    FATAL: mysql_drv_query() returned error 1053 (Server shutdown in progress) for query 'UPDATE sbtest12 SET k=k+1 WHERE id=50288'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:461: SQL error, errno = 1053, state = '08S01': Server shutdown in progress
    FATAL: mysql_drv_query() returned error 1053 (Server shutdown in progress) for query 'UPDATE sbtest25 SET k=k+1 WHERE id=50105'
    FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:461: SQL error, errno = 1053, state = '08S01': Server shutdown in progress
    
    real    0m5.043s
    user    0m0.080s
    sys    0m1.044s
    
    
    Mon Mar 26 15:16:53 UTC 2018
    sysbench 1.1.0-651e7fd (using bundled LuaJIT 2.1.0-beta3)
    
    Running the test with following options:
    Number of threads: 4
    Report intermediate results every 1 second(s)
    Initializing random number generator from current time
    
    
    Initializing worker threads...
    
    Threads started!
    
    [ 1s ] thds: 4 tps: 46.82 qps: 905.61 (r/w/o: 710.34/195.27/0.00) lat (ms,95%): 101.13 err/s: 0.00 reconn/s: 0.00

    フェイルオーバーの概要

    これは科学的なベンチマークではないことを明確にすることが重要です。ほとんどの場合、ClusterControlはフェイルオーバーを実行するために使用します。プロキシは通常、トポロジの変更を検出するのに最大で数秒かかります。アプリケーションとしてsysbenchを使用しました。自動コミットされたトランザクションを実行するように構成されているため、明示的なトランザクションもプリペアドステートメントも使用されていません。 Sysbenchの読み取り/書き込みワークロードは非常に高速です。長時間実行されるトランザクションまたはクエリがある場合、フェイルオーバーのパフォーマンスは異なります。私たちのシナリオを最良のケースとして見ることができます。

    切り替え

    前述したように、スイッチオーバーを実行すると、ClusterControlはマスターをより詳細に制御できます。状況によっては(トランザクションがない、書き込みが長時間実行されていないなど)、プロキシがこれをサポートしている限り、正常なマスタースイッチを実行できる場合があります。残念ながら、現時点では、ClusterControlによってデプロイ可能なプロキシはどれも正常なスイッチオーバーを処理できません。以前は、ProxySQLにこの機能があったため、詳細を調査して、ProxySQLの作成者であるRenéCannaòと連絡を取ることにしました。調査中に、ProxySQLの次のリリースで修正する必要があるリグレッションを特定しました。それまでの間、ProxySQLの動作を紹介するために、ソースからコンパイルした小さな回避策がパッチされたProxySQLを使用しました。

    [ 16s ] thds: 4 tps: 39.01 qps: 711.11 (r/w/o: 555.09/156.02/0.00) lat (ms,95%): 173.58 err/s: 0.00 reconn/s: 0.00
    [ 17s ] thds: 4 tps: 49.00 qps: 879.06 (r/w/o: 678.05/201.01/0.00) lat (ms,95%): 102.97 err/s: 0.00 reconn/s: 0.00
    [ 18s ] thds: 4 tps: 42.86 qps: 768.57 (r/w/o: 603.09/165.48/0.00) lat (ms,95%): 176.73 err/s: 0.00 reconn/s: 0.00
    [ 19s ] thds: 4 tps: 28.07 qps: 521.26 (r/w/o: 406.98/114.28/0.00) lat (ms,95%): 235.74 err/s: 0.00 reconn/s: 0.00
    [ 20s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 21s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 22s ] thds: 4 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
    [ 23s ] thds: 4 tps: 13.98 qps: 249.59 (r/w/o: 193.68/55.91/0.00) lat (ms,95%): 4055.23 err/s: 0.00 reconn/s: 0.00
    [ 24s ] thds: 4 tps: 81.06 qps: 1449.01 (r/w/o: 1123.79/325.23/0.00) lat (ms,95%): 62.19 err/s: 0.00 reconn/s: 0.00
    [ 25s ] thds: 4 tps: 52.02 qps: 923.42 (r/w/o: 715.32/208.09/0.00) lat (ms,95%): 390.30 err/s: 0.00 reconn/s: 0.00
    [ 26s ] thds: 4 tps: 59.00 qps: 1082.94 (r/w/o: 844.96/237.99/0.00) lat (ms,95%): 164.45 err/s: 0.00 reconn/s: 0.00
    [ 27s ] thds: 4 tps: 50.99 qps: 900.75 (r/w/o: 700.81/199.95/0.00) lat (ms,95%): 130.13 err/s: 0.00 reconn/s: 0.00

    ご覧のとおり、クエリは4秒間実行されませんが、アプリケーションにエラーは返されません。この一時停止後、トラフィックは再び流れ始めます。

    要約すると、ClusterControlをProxySQL、MaxScale、またはHAProxyと併用すると、10〜15秒のダウンタイムでフェイルオーバーを実行できることを示しました。計画されたマスタースイッチに関しては、書き込み時にエラーなしで手順を処理できるプロキシはありません。ただし、次のProxySQLバージョンでは、アプリケーションにエラーが表示されることなく、数秒の切り替えが可能になると予想されます。


    1. libpq.5.dylibの間違ったコピーにリンクしているRuby'pg'gem(OSX上)

    2. SQLServerでの内部結合と左結合のパフォーマンス

    3. Oracleでユーザーに付与されている特権と役割を見つける方法は?

    4. OracleのBFILE列からBLOBを取得する