MySQLはもともとMariaDBを形成するためにフォークされて以来、オープンソースデータベースコミュニティの多くの聴衆によって広くサポートされ、すぐに採用されてきました。もともとはドロップインの代替品でしたが、MariaDBは、特にMariaDB 10.2のリリースにより、MySQLとの差別化を図り始めました。
ただし、MariaDBとMySQLは互換性があり、相互にネイティブに実行できるエンジンを備えているため、どちらにも明確な違いはありません。したがって、MariaDBセットアップのチューニングがMySQLのチューニングと同様のアプローチを採用していても驚かないでください。
このブログでは、MariaDBのチューニング、特にLinux環境で実行されているシステムについて説明します。
MariaDBハードウェアとシステムの最適化
MariaDBでは、ハードウェアを次の優先順位で改善することをお勧めします...
メモリは、サーバーシステム変数を調整できるため、データベースにとって最も重要な要素です。メモリが増えるということは、キーとテーブルのキャッシュが大きくなることを意味します。これらのキャッシュはメモリに保存されるため、ディスクがアクセスできるようになり、桁違いに遅くなります。
ただし、サーバー変数が追加の使用可能なメモリを使用するように設定されていない場合、メモリを追加するだけでは大幅な改善にはならない可能性があることに注意してください。
マザーボードでより多くのRAMスロットを使用すると、バス周波数が高くなり、RAMとCPUの間の遅延が大きくなります。これは、スロットごとに最大のRAMサイズを使用することが望ましいことを意味します。
最終的にはデータが存在する場所であるため、高速ディスクアクセスは重要です。重要な数値はディスクシーク時間(物理ディスクがデータにアクセスするために移動できる速度の測定値)であるため、シーク時間ができるだけ短いディスクを選択します。一時ファイルとトランザクションログ専用のディスクを追加することもできます。
インターネット帯域幅の適切な要件により、ファストイーサネットはクライアントの要求への応答を高速化できることを意味します。スレーブ間でバイナリログを読み取るためのレプリケーション応答時間、特にガレラでは応答時間の高速化も非常に重要です。ベースのクラスター。
CPU
ハードウェアのボトルネックは他の場所で発生することがよくありますが、プロセッサが高速であるほど計算をより迅速に実行でき、結果をより迅速にクライアントに送り返すことができます。プロセッサの速度に加えて、プロセッサのバス速度とキャッシュサイズも考慮すべき重要な要素です。
I / Oスケジューラは、ディスクアクセス要求を最適化する方法として存在します。 I/O要求をディスク上の同様の場所にマージします。これは、ディスクドライブが頻繁にシークする必要がなく、全体的な応答時間が大幅に改善され、ディスク操作が節約されることを意味します。 I / Oパフォーマンスの推奨値は、noopとdeadlineです。
noopは、他のスケジューラーの複雑なI/Oスケジューリングの決定がI/Oパフォーマンスの低下を引き起こしていないかどうかを確認するのに役立ちます。場合によっては、インテリジェントストレージとしてI / Oスケジューリングを行うデバイスや、SSDのように機械的な動きに依存しないデバイスに役立つことがあります。通常、これらのデバイスにはDEADLINE I / Oスケジューラが適していますが、オーバーヘッドが少ないため、NOOPは特定のワークロードでパフォーマンスを向上させる可能性があります。
期限については、レイテンシー指向のI/Oスケジューラーです。各I/Oリクエストには、期限が割り当てられています。通常、リクエストはセクター番号でソートされたキュー(読み取りと書き込み)に保存されます。 DEADLINEアルゴリズムは、要求が期限によってソートされる2つの追加のキュー(読み取りと書き込み)を維持します。リクエストがタイムアウトしていない限り、「セクター」キューが使用されます。タイムアウトが発生した場合、「期限」キューからの要求は、期限切れの要求がなくなるまで処理されます。一般に、アルゴリズムは書き込みよりも読み取りを優先します。
PCIeデバイス(NVMe SSDドライブ)の場合、高速サービスとともに独自の大きな内部キューがあり、I/Oスケジューラーを設定する必要はありません。明示的なスケジューラモード構成パラメータを設定しないことをお勧めします。
次のコマンドでスケジューラの設定を確認できます:
cat /sys/block/${DEVICE}/queue/scheduler
たとえば、次のようになります。
cat /sys/block/sda/queue/scheduler
[noop] deadline cfq
永続的にするには、/ etc / default / grub構成ファイルを編集し、変数GRUB_CMDLINE_LINUXを探して、次のようにエレベータを追加します。
GRUB_CMDLINE_LINUX="elevator=noop"
サーバーのパフォーマンスを向上させるには、クライアント接続、データベースファイル、およびログファイルの総数が、オペレーティングシステムのファイル記述子の最大制限(ulimit -n)を超えてはなりません。 Linuxシステムでは、1つのプロセスが開くことができるファイル記述子の数がプロセスごとに1,024に制限されています。アクティブなデータベースサーバー(特に本番サーバー)では、デフォルトのシステム制限に簡単に達する可能性があります。
これを増やすには、/ etc / security / Limits.confを編集して、以下を指定または追加します。
mysql soft nofile 65535
mysql hard nofile 65535
これには、システムの再起動が必要です。その後、以下を実行して確認できます:
$ ulimit -Sn
65535
$ ulimit -Hn
65535
オプションで、mysqld_safeを介してmysqldプロセスを開始する場合は、mysqld_safeを介してこれを設定できます。
[mysqld_safe]
open_files_limit=4294967295
sudo tee /etc/systemd/system/mariadb.service.d/limitnofile.conf <<EOF
[Service]
LimitNOFILE=infinity
EOF
sudo systemctl daemon-reload
LinuxforMariaDBでSwappinessを設定する
Linuxスワップは、データベースシステムで大きな役割を果たします。それはあなたの車のスペアタイヤのように機能し、厄介なメモリリークがあなたの仕事を妨げるとき、マシンは遅くなります...しかしほとんどの場合、割り当てられたタスクを完了するためにまだ使用可能です。
swappinessに変更を適用するには、実行するだけです
sysctl -w vm.swappiness=1
これは動的に発生し、サーバーを再起動する必要はありません。永続的にするには、/ etc / sysctl.confを編集して、行を追加します。
vm.swappiness=1
swappiness =0を設定するのはかなり一般的ですが、新しいカーネル(つまり、カーネル> 2.6.32-303)のリリース以降、変更が加えられたため、vm.swappiness=1を設定する必要があります。
MariaDBのファイルシステムの最適化
MariaDBを実行しているLinux環境で使用される最も一般的なファイルシステムは、ext4とXFSです。 ZFSとBRTFSを使用してアーキテクチャを実装するために利用できる特定のセットアップもあります(MariaDBのドキュメントで参照されています)。
これに加えて、ほとんどのデータベース設定では、ファイルアクセス時間を記録する必要はありません。ボリュームをシステムにマウントするときに、これを無効にすることをお勧めします。これを行うには、ファイル/ etc/fstabを編集します。たとえば、/ dev / md2という名前のボリュームでは、次のようになります。
/dev/md2 / ext4 defaults,noatime 0 0
innodb_buffer_pool_size
tmp_memory_table_size / max_heap_table_size
tmp_memory_table_size(tmp_table_size)の場合、大きな一時テーブルを処理する場合、これを高く設定すると、メモリに保存されるため、パフォーマンスが向上します。これは、GROUP BY、UNION、またはサブクエリを多用するクエリでよく見られます。 max_heap_table_sizeが小さい場合でも、下限が適用されます。テーブルが制限を超えると、MariaDBはそれをMyISAMまたはAriaテーブルに変換します。ステータス変数Created_tmp_disk_tablesとCreated_tmp_tablesを比較して、作成された合計のうち、ディスクに変換する必要のある一時テーブルの数を確認することで、増やす必要があるかどうかを確認できます。多くの場合、複雑なGROUPBYクエリが制限を超える原因になります。
max_heap_table_sizeの間、これはユーザーが作成したMEMORYテーブルの最大サイズです。この変数に設定された値は、新しく作成または再作成されたテーブルにのみ適用され、既存のテーブルには適用されません。 max_heap_table_sizeとtmp_table_sizeの小さい方も、内部メモリ内テーブルを制限します。最大サイズに達すると、それ以上データを挿入しようとすると、「テーブル...がいっぱいです」というエラーが発生します。 CREATE TEMPORARYで作成された一時テーブルは、内部一時テーブルで発生するようにAriaに変換されませんが、テーブルフルエラーも受け取ります。
innodb_log_file_size
join_buffer_size
場合によっては、クエリで適切なインデックスが使用されない傾向があるか、単にこのクエリを実行する必要がある場合があります。クライアントの観点から頻繁に呼び出されたり呼び出されたりしない限り、この変数の設定はセッションレベルで最適です。結合は常に最小サイズを割り当てるため、メモリの問題に注意してくださいが、インデックスを追加できない場合は、これを増やすと完全結合が高速になります。
max_allowed_packetを設定
MariaDBは、パケットを処理するときにMySQLと同じ性質を持っています。データをパケットに分割し、クライアントはmax_allowed_packet変数値を認識している必要があります。サーバーには、このmax_allowed_packet値に対応する最大サイズで本体を格納するためのバッファーがあります。クライアントがmax_allowed_packetサイズより多くのデータを送信すると、ソケットは閉じられます。 max_allowed_packetディレクティブは、送信できるパケットの最大サイズを定義します。
この値の設定が低すぎると、クエリが停止してクライアント接続が閉じられる可能性があります。これは、クエリ中にER_NET_PACKET_TOO_LARGEやMySQLサーバーへの接続が失われたなどのエラーを受け取るのが一般的です。理想的には、特に今日のほとんどのアプリケーションの要求で、これを512MiBに設定し始めることができます。需要の少ないタイプのアプリケーションの場合は、デフォルト値を使用し、送受信するデータがデフォルト値(MariaDB 10.2.4以降は16MiB)よりも大きい場合に必要な場合にのみ、セッションを介してこの変数を設定します。大きなパケットを処理する必要がある特定のワークロードでは、特にレプリケーションの場合、ニーズに応じてより高いパケットを調整する必要があります。スレーブでmax_allowed_packetが小さすぎると、スレーブもI/Oスレッドを停止します。
場合によっては、この調整は必要ないか、推奨されないことがあります。スレッドプールは、クエリが比較的短く、負荷がCPUバウンド(OLTPワークロード)である状況で最も効率的です。ワークロードがCPUにバインドされていない場合でも、データベースメモリバッファのメモリを節約するためにスレッドの数を制限することをお勧めします。
スレッドプールの使用は、特にシステムでコンテキストスイッチングが発生していて、これを減らしてクライアントの数よりも少ないスレッド数を維持する方法を見つけている場合に理想的なソリューションです。ただし、使用可能なCPUを最大限に活用したいので、この数も少なすぎないようにする必要があります。したがって、理想的には、マシン上のCPUごとに1つのアクティブなスレッドが存在する必要があります。
thread_pool_max_threads、thread_pool_min_threadsを、スレッドの最大数と最小数に設定できます。 MySQLとは異なり、これはMariaDBにのみ存在します。
テーブルを開くステータスとテーブルを閉じるステータスに関するプロセスリストで時折発生する場合は、テーブルキャッシュを増やす必要があることを示している可能性があります。 SHOW GLOBAL STATUS LIKE'Open%table%'を実行して、mysqlクライアントプロンプトからもこれを監視できます。ステータス変数を監視します。
max_connectionsの場合、アプリケーションで多数の同時接続が必要な場合は、これを500に設定し始めることができます。
table_open_cacheの場合、テーブルの総数になりますが、一時テーブルもキャッシュされるため、提供するクエリのタイプに応じてさらに追加することをお勧めします。たとえば、500個のテーブルがある場合は、1500から始めるのが妥当です。
table_open_cache_instancesを8に設定し始めます。これにより、セッション間の競合が減り、スケーラビリティが向上します。開いているテーブルキャッシュは、table_open_cache/table_open_cache_instancesのサイズのいくつかの小さなキャッシュインスタンスに分割できます。
InnoDBの場合、table_definition_cacheは、InnoDBデータディクショナリキャッシュ内の開いているテーブルインスタンスの数のソフト制限として機能します。定義する値は、定義キャッシュに保管できるテーブル定義の数を設定します。多数のテーブルを使用する場合は、大きなテーブル定義キャッシュを作成して、テーブルのオープンを高速化できます。テーブル定義キャッシュは、通常のテーブルキャッシュとは異なり、使用するスペースが少なく、ファイル記述子を使用しません。最小値は400です。デフォルト値は次の式に基づいており、上限は2000です。
MIN(400 + table_open_cache / 2, 2000)
開いているテーブルインスタンスの数がtable_definition_cache設定を超えると、LRUメカニズムはテーブルインスタンスにエビクションのマークを付け始め、最終的にデータディクショナリキャッシュから削除します。この制限は、次のサーバーの再起動まで、めったに使用されないテーブルインスタンスをキャッシュするために大量のメモリが使用される状況に対処するのに役立ちます。キャッシュされたメタデータを持つテーブルインスタンスの数は、table_definition_cacheで定義された制限よりも多くなる可能性があります。これは、外部キー関係を持つ親テーブルインスタンスと子テーブルインスタンスがLRUリストに配置されず、メモリからの削除の対象にならないためです。
table_open_cacheとは異なり、table_definition_cacheはファイル記述子を使用せず、はるかに小さいです。
クエリキャッシュの処理
できれば、すべてのMariaDBセットアップでクエリキャッシュを無効にすることをお勧めします。クエリキャッシュを完全に無効にするには、query_cache_type=OFFおよびquery_cache_size=0であることを確認する必要があります。 MySQLとは異なり、MariaDBは引き続きクエリキャッシュを完全にサポートしており、クエリキャッシュを使用するためのサポートを撤回する予定はありません。クエリキャッシュが依然としてパフォーマンス上の利点を提供すると主張する人もいます。ただし、Perconaからのこの投稿MySQLクエリキャッシュ:最悪の敵または親友は、クエリキャッシュを有効にすると、オーバーヘッドが発生し、サーバーのパフォーマンスが低下することを示しています。
クエリキャッシュを使用する場合は、SHOW GLOBAL STATUS LIKE'Qcache%';を実行してクエリキャッシュを監視してください。 Qcache_insertsには、クエリキャッシュに追加されたクエリの数が含まれ、Qcache_hitsには、クエリキャッシュを使用したクエリの数が含まれ、Qcache_lowmem_prunesには、メモリ不足のためにキャッシュから削除されたクエリの数が含まれます。やがて、クエリキャッシュの使用と有効化が断片化する可能性があります。 Qcache_total_blocksに比べて高いQcache_free_blocksは、断片化を示している可能性があります。デフラグするには、FLUSHQUERYCACHEを実行します。これにより、クエリを削除せずにクエリキャッシュが最適化されます。
MariaDBノードを適切に監視することは非常に重要です。無料のオープンソースツールを好む傾向がある場合は、一般的な監視ツール(Nagios、Zabbix、PMMなど)を利用できます。企業向けおよび完全にパックされたツールの場合、ClusterControlを試してみることをお勧めします。これは、監視を提供するだけでなく、システムパフォーマンスを改善し、最新の状態を維持するのに役立つパフォーマンスアドバイザー、アラート、およびアラームも提供するためです。サポートチームと連携する際の傾向。 ClusterControlを使用したデータベースの監視は無料で、CommunityEditionの一部です。
MariaDBセットアップの調整は、MySQLとほぼ同じアプローチですが、サポートするアプローチとバージョンの一部が異なるため、いくつかの違いがあります。 MariaDBは現在、データベースの世界では別のエンティティであり、FUDなしでコミュニティからすぐに信頼を得ています。このように実装する必要があるのには独自の理由があるため、これを調整してMariaDBサーバーを最適化する方法を知っていることが非常に重要です。