ドキュメントをインデックスに登録してデータベースに挿入するPythonを使用してインデクサーを作成しています。それが単一プロセスになる前は、4つの並列プロセスを実行してマルチプロセッシングにしました。すべてのテキスト抽出の後、データベースに挿入してコミットします。
IO問題、メインIO問題は私のプロセスではなく、EXT4のjdb2、ジャーナリングシステムです。これは99.99%であり、CPUがIOすべてのMySQLコミットで。
多くの人がインターネット上でその問題を抱えているのを見ました。彼らの解決策は、barrier = 0を使用してマウントすることです。ジャーナリングを完全に無効にしますか?サーバーにUPSがあり、それを実行したいのですが、どうすればよいですか。
弾力性とパフォーマンスの間には常にトレードオフがあります。
MySQLでext4を使用すると、barriers = 1のデフォルトにより実際に速度が低下しますが、最初のアクションは、ジャーナリングを無効にすることや、data = writebackをオンにすることではありません。
まず、復元力が非常に重要である場合、バッテリバックアップRAIDは確かにその価値があります。
私が選択したマウントオプションは、特に非バッテリバックアップRAIDで次のとおりです。
/dev/mapper/vg-mysql--data /var/lib/mysql/data ext4 defaults,noatime,nodiratime,barrier=1,data=ordered 0 0
これは意図的にdata = writebackを使用していません。ファイルシステムが破損して「古いデータがクラッシュとジャーナルのリカバリ後にファイルに表示される」リスクを冒したくないためです(引用はman mount
から)。
I/O関連の設定を完全に復元するためのmy.cnfの理想的な構成は次のとおりです。
[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
パフォーマンスを向上させるために、次の一連のトレードオフを選択しました。
sync_binlog = 0
:これは、完全な復元力から変更した最初のMySQL構成です。これは、特にbinlog_format=row
(残念ながらJiraに必要)の場合に、パフォーマンスが大幅に向上するためです。クラスターで十分なMySQLレプリカを使用しているため、停電シナリオによってバイナリログが破損した場合、別のレプリカからバイナリコピーを実行します。innodb_flush_log_at_trx_commit = 2
:ACIDに完全に準拠するには値1が必要ですが、値2の場合、ログバッファーはコミットごとにファイルに書き出されますが、ディスクへのフラッシュ操作は実行されません。ただし、 、値が2の場合も、ログファイルのフラッシュは1秒に1回行われます。1秒に1回のフラッシュは、プロセスのスケジュールの問題により、毎秒100%発生することが保証されているわけではありません。」 (MySQLドキュメントからの引用)data=writeback
を使用するようにマウントオプションを更新します。これがルートファイルシステムの場合は、カーネルコマンドラインオプションも渡す必要があることに注意してください。 coderwall でいくつかのステップをまとめました。innodb_flush_method
のさまざまな値をテストします。 O_DIRECTは一部のワークロードでパフォーマンスを向上させることが示されていますが、これがご使用の環境で機能するとは限りません。innodb_io_capacity
を増やし、innodb_adaptive_flushing
、innodb_read_io_threads
、innodb_write_io_threads
、innodb_purge_threads
などの設定を調整する必要があります。その他の可能な設定。データベースを非ジャーナリングファイルシステムに配置します。少なくともより大きなサーバー(Oracle、SQLサーバー)には独自のジャーナル機能(トランザクションログ)があり、それに応じてIOを最適化します。ログとデータベースは別々のファイルシステムとディスクにあり、内部のデータベースに依存しています。不良IOを処理するための機能。ファイルが拡張されないため、とにかく書き込み日付を除いて(大きなセットアップ)ファイルシステムの変更はありません-それらは「最終的な」サイズで生成され(管理者はそれを変更できます)、変更は次のとおりです。私はデータベースレベルのトランザクションログによって追跡されると述べた。
また、ハードウェアレイヤーを教えてください。ほとんどの人は [〜#〜] iops [〜#〜] がデータベースの制限要因であることを過小評価しており、小さなディスクセットは大きなデータベースには適切な環境であると考えています。私たちの一部は、より多くのディスクを使用してデータベースに取り組んでいるため、より多くのIOPSをサポートする可能性があります。
これは古い質問ですが、先週新しい専用サーバーで同じ問題(高IO待機、ひどい挿入/更新速度))に直面しましたが、このソリューションはこの問題に直接対処しています。
tune2fs -O "^has_journal" /dev/<drive>
でジャーナリングを無効にすることは、JDB2プロセスのためにIO待機を排除するため、最も迅速な解決策でした。しかし、クラッシュ時にデータが失われるため、バッテリバックアップドライブ。MySQLで doublewrite
を有効にすると、InnoDBテーブルは安全です。ただし、.frm、ログなどのファイルは安全ではありません。これらのファイルを別のドライブ(特にbinログ)に移動しようとしましたが、jdb2 IO待機がまだ持続しているため、あまり快適ではありませんでした。
data=writeback,relatime,nobarrier
は、パーティション全体でジャーナリングを無効にするのと同じくらい、書き込み/読み取りを高速化するのに役立ちませんでした。 ext4のその他のオプションは EXT4 doc にあります。
私たちの場合の本当の犯人は sync_binlog
でした。私たちは1
の/etc/mysql/my.cnf
として設定し、それはkillingパフォーマンスでした。
Perconaはこれをここで検証します 。これをデフォルトの0
に設定すると、パフォーマンスが500%以上向上します。
I/Oバックエンドが負荷に十分に対応していない可能性があります。ファイルシステムがデータをジャーナリングしていないことを確認する必要があります。最初の迅速でダーティな最適化として、data=writeback,relatime,nobarrier
パラメータを使用してデータベースのデータパーティションにマウントすることをお勧めします。
また、症状から推測して、コントローラーで書き込みキャッシュを使用していないようです。コントローラーでバッテリーバックアップまたはフラッシュバックアップの書き込みキャッシュを使用していることを確認し、それを有効にする必要があります。これにより、データの損失や破損のリスクを大幅に増加させることなく、パフォーマンスが大幅に向上します。書き込みキャッシュを使用することに注意してくださいなしバッテリーまたはフラッシュバックアップデータの損失や破損のリスクが大幅に増加します-そうするだけこれは、テスト目的および/または損失をとることができる場合に使用します。
また、mysqlに直接関連していませんが、一部のHDは積極的な電源管理のためにext4に問題があります...その場合、マシンの負荷は明白なアクティビティなしに増加します。
それを無効にしてみてください。最初に(再起動せずに戻す必要がある場合は)持っている値を確認してから、無効にします。
現在の値を確認します。
hdparm -B /dev/sda
それを無効にする
hdparm -B 255 /dev/sda
(またはあなたのHDは何でも)そしてテストしてください。おそらくほとんどの問題には役立ちませんが、一部のユーザーには役立つかもしれません。再起動すると値がリセットされるか、手動で前の値の255が置き換えられます。
問題が解決しない場合は、/etc/default/hdparm
または/etc/hdparm.conf
ブート時に設定することにより、より永続的な設定を行います。
このデータを挿入するためにどのデータベースエンジンを使用していますか?
それがMyISAMの場合:書き込み中にテーブル全体をロックする必要があるため、同時挿入スレッドを実行すると、どんなに強力なシステムでも強制終了されます。
これらのテーブルにInnoDBを使用していることを確認してください。