Moodleは、オンラインコースを運営するための非常に人気のあるプラットフォームです。 2020年に見られる状況では、Moodleは、Zoomのようなコミュニケーターとともに、オンライン学習と在宅教育を可能にするサービスのバックボーンを形成しています。 Moodleプラットフォームへの需要は、前年に比べて大幅に増加しました。新しいプラットフォームが構築され、歴史的にはヘルパーツールとしてのみ機能していたプラットフォームに追加の負荷がかかり、現在は教育活動全体を推進することを目的としています。 Moodleをスケールアウトする方法は?このトピックに関するブログがあります。 Moodleのデータベースバックエンドをスケーリングする方法は?ええと、それは別の話です。特にMoodleが独自のちょっとしたひねりを加えている場合、データベースのスケールアウトは最も簡単なことではないので、それを見てみましょう。
エントリポイントとして、以前の投稿の1つで説明したアーキテクチャを使用します。 ProxySQLとKeepalivedを備えたMariaDBクラスター。
ご覧のとおり、ProxySQLを備えた3ノードのMariaDBクラスターがあります。ユーザーに基づいて、残りのトラフィックから安全な読み取りを分割します。
<?php // Moodle configuration file
unset($CFG);
global $CFG;
$CFG = new stdClass();
$CFG->dbtype = 'mysqli';
$CFG->dblibrary = 'native';
$CFG->dbhost = '192.168.1.222';
$CFG->dbname = 'moodle';
$CFG->dbuser = 'moodle';
$CFG->dbpass = 'pass';
$CFG->prefix = 'mdl_';
$CFG->dboptions = array (
'dbpersist' => 0,
'dbport' => 6033,
'dbsocket' => '',
'dbcollation' => 'utf8mb4_general_ci',
'readonly' => [
'instance' => [
'dbhost' => '192.168.1.222',
'dbport' => 6033,
'dbuser' => 'moodle_safereads',
'dbpass' => 'pass'
]
]
);
$CFG->wwwroot = 'http://192.168.1.200/moodle';
$CFG->dataroot = '/var/www/moodledata';
$CFG->admin = 'admin';
$CFG->directorypermissions = 0777;
require_once(__DIR__ . '/lib/setup.php');
// There is no php closing tag in this file,
// it is intentional because it prevents trailing whitespace problems!
上記のように、ユーザーはMoodle設定ファイルで定義されています。これにより、書き込みと、データの整合性を必要とするすべてのSELECTステートメントをライターノードに自動的かつ安全に送信しながら、一部のSELECTをMariaDBクラスターの残りのノードに送信できます。
- ProxySQLインスタンスがトラフィックに対応できない場合はどうすればよいですか?
- MariaDBクラスターがトラフィックに対応できない場合はどうすればよいですか?
ProxySQLインスタンスがオーバーロードされています
現在の環境では、トラフィックを処理できるProxySQLインスタンスは1つだけです。つまり、仮想IPが指すトラフィックです。これにより、スタンバイとして機能しているProxySQLインスタンスが残ります。つまり、稼働していますが、何にも使用されていません。アクティブなProxySQLインスタンスがCPUの飽和状態に近づいている場合は、実行したいことがいくつかあります。まず、明らかに、垂直方向にスケーリングできます。ProxySQLインスタンスのサイズを大きくすることが、より多くのトラフィックを処理できるようにする最も簡単な方法である可能性があります。 ProxySQLは、デフォルトで4つのスレッドを使用するように構成されていることに注意してください。
より多くのCPUコアを利用できるようにしたい場合は、これが設定も変更する必要があります。
または、水平方向にスケールアウトすることもできます。 VIPで2つのProxySQLインスタンスを使用する代わりに、ProxySQLをMoodleホストと併置することができます。次に、ローカルホスト上のProxySQLに接続するようにMoodleを再構成する必要があります。理想的にはUnixソケットを介して接続します。これはProxySQLに接続する最も効率的な方法です。 ProxySQLで使用する構成はそれほど多くないため、ProxySQLの複数のインスタンスを使用しても、オーバーヘッドが大きくなりすぎないようにする必要があります。必要に応じて、いつでもProxySQL Clusterをセットアップして、構成に関してProxySQLインスタンスの同期を維持することができます。
MariaDBクラスターがオーバーロードされています
今、私たちはもっと深刻な問題について話している。もちろん、通常どおり、インスタンスのサイズを大きくすると役立ちます。一方、「安全な読み取り」の制限により、水平方向のスケールアウトは多少制限されます。もちろん、クラスターにノードを追加することはできますが、それらは安全な読み取りにのみ使用できます。これによりどの程度スケールアウトできるかは、ワークロードによって異なります。純粋な読み取り専用ワークロード(コンテンツ、フォーラムなどを閲覧する)の場合、非常に見栄えがします:
MySQL [(none)]> SELECT hostgroup, srv_host, srv_port, status, queries FROM stats_mysql_connection_pool WHERE hostgroup IN (20, 10) AND status='ONLINE';
+-----------+---------------+----------+--------+---------+
| hostgroup | srv_host | srv_port | status | Queries |
+-----------+---------------+----------+--------+---------+
| 20 | 192.168.1.204 | 3306 | ONLINE | 5683 |
| 20 | 192.168.1.205 | 3306 | ONLINE | 5543 |
| 10 | 192.168.1.206 | 3306 | ONLINE | 553 |
+-----------+---------------+----------+--------+---------+
3 rows in set (0.002 sec)
これはほぼ1:20の比率です。ライターにヒットする1つのクエリに対して、残りのノードに分散できる20の「安全な読み取り」があります。一方、データの変更を開始すると、比率は急速に変化します。
MySQL [(none)]> SELECT hostgroup, srv_host, srv_port, status, queries FROM stats_mysql_connection_pool WHERE hostgroup IN (20, 10) AND status='ONLINE';
+-----------+---------------+----------+--------+---------+
| hostgroup | srv_host | srv_port | status | Queries |
+-----------+---------------+----------+--------+---------+
| 20 | 192.168.1.204 | 3306 | ONLINE | 3117 |
| 20 | 192.168.1.205 | 3306 | ONLINE | 3010 |
| 10 | 192.168.1.206 | 3306 | ONLINE | 6807 |
+-----------+---------------+----------+--------+---------+
3 rows in set (0.003 sec)
これは、いくつかの成績を発行し、フォーラムトピックを作成し、いくつかのコースコンテンツを追加した後の出力です。ご覧のとおり、このような安全/安全でないクエリの比率では、ライターはリーダーよりも早く飽和状態になるため、ノードを追加してスケールアウトすることは適切ではありません。
それについて何ができるでしょうか? 「レイテンシー」と呼ばれる設定があります。構成ファイルに従って、書き込み後にテーブルを安全に読み取ることができる時期を決定します。書き込みが発生すると、テーブルは変更済みとしてマークされ、「待機時間」の間、すべてのSELECTがライターノードに送信されます。 「レイテンシ」よりも長い時間が経過すると、そのテーブルからのSELECTが再度読み取りノードに送信される場合があります。 MariaDBクラスターでは、ライトセットがすべてのノードに適用されるのに必要な時間は通常、ミリ秒単位で非常に短いことに注意してください。これにより、Moodle設定ファイルでレイテンシーを非常に低く設定できます。たとえば、0.1秒(100ミリ秒)のような値はかなり問題ないはずです。もちろん、問題が発生した場合は、いつでもこの値をさらに増やすことができます。
テストするもう1つのオプションは、読み取りが安全である場合とそうでない場合を判断するために、MariaDBクラスターのみに依存することです。いくつかのアクセスパターン(読み取り、更新、挿入、削除、置換、およびSHOWコマンド)で因果関係チェックを強制するように構成できるwsrep_sync_wait変数があります。私たちの目的では、因果関係を強制して読み取りが実行されるようにするだけで十分なので、この変数を「1」に設定します。
すべてのMariaDBクラスターノードでこの変更を行います。また、以前のようにユーザーだけでなく、クエリルールに基づいて読み取り/書き込み分割用にProxySQLを再構成する必要があります。この設定では不要になったため、「moodle_safereads」ユーザーも削除します。
クエリに基づいてトラフィックを分散する、3つのクエリルールを設定しました。 SELECT…FORUPDATEはライターノードに送信され、すべてのSELECTクエリはリーダーに送信され、その他すべて(INSERT、DELETE、REPLACE、UPDATE、BEGIN、COMMITなど)もライターノードに送信されます。
これにより、すべての読み取りをリーダーノード全体に分散できるため、MariaDBクラスターにノードを追加することで水平方向のスケールアウトが可能になります。
これらのいくつかのヒントを使用して、Moodleデータベースバックエンドをはるかに簡単かつ大幅にスケールアウトできるようになることを願っています