2023/06/17 RockyLinux 9.2





PostfixAdminでSQLiteを使用した場合のパフォーマンスについて

1.PostfixAdminのインストール
2.PostfixAdminで PostfixとDovecotを管理する
3.PostfixAdminでクォータ管理をする
4.PostfixAdminでSQLiteを使用した場合のパフォーマンスについて


PostfixAdminのバックエンドデータベースにSQLiteを選択すると、手軽に構築できてサーバ更改なども容易になります。
ですがSQLiteを使用した場合、引き換えとなるパフォーマンスやサイジングも気になります。
SQLiteを使用した場合の検証と対策を考えて見ました。

SQLiteは読み出しは高速で、複数読み出しにも対応していると謳われています。
実際、数千件のユーザーアカウントを登録してもクエリは一瞬で応答します。メールサーバの送受信パフォーマンスとして不満はないでしょう。
一方書き込みが弱い、というのがSQLiteの特徴です。

SQLiteとPostfixAdminのPHPとの組み合わせで気づいた課題について解説しました。

・コマンドからユーザー登録を一括して行うと、遅かったり早かったり、エラーが表示される
 →SQLiteのジャーナルモードを変更しましょう。

・一括作成をすると、ようこそメールが送信されない
 →Postqueueコマンドで再送します

・SQLiteで運用できるユーザー数はどのくらいまで?
 →300〜800アカウントといったところでしょう。




一括作成をするとエラーが表示されることがある

PostfixAdminをSQLiteで構築し、PostfixAdminコマンドからユーザーを一括作成すると、いくつかの問題に気付き ます。

・作成中、それまで順調だったユーザー作成処理が突然遅くなり、1、2分するとまた順調に戻る。
・DBロックにともなうアカウント作成のエラーメッセージが表示される。
・一括登録作業をしながら、ウェブ画面でユーザー登録をすると、完了まで時間がかかる。

これはDBロックを原因にした挙動らしく、エラーメッセージもPHP処理の中で生成されたもので、実際のユーザーは正常に登録されています。
おおざっぱに言えば、DBの書き込みがすぐに終わらず、次の処理を続けて書き込むからと言えます。
作成コマンドごとに2秒の遅延を挟んでみましたが、結果はあまり変化ありませんでした。
そんな単純な話ではないようです。

SQLiteはデフォルトでジャーナルモードがDeleteに設定されており、アップデートの度に大きな情報が行われることが原因と思われま す。
SQLiteのジャーナルモードを変更すればエラーが発生せずユーザー登録できます。
#cd /srv/postfixadmin/database
#sqlite postfixadmin.db

sqlite> pragma journal_mode;
delete   ※ジャーナルはdeleteモード
sqlite> pragma journal_mode=wal;   ※ジャーナルモードをwalへ変更
sqlite> .exit
ジャーナルを変更したことユーザーの一括登録が素早く進みますし、Webからの登録処理もスムーズにできるようになりました。

モードを変更したことでデータ欠損の怖れが高くなるのでは? との懸念があります。
walは、deleteよりはデータ損失の可能性は高まっていますが、walはジャーナルといっても登録は「永続化されている」ので(公式ド キュメントより)、あまり心配しなくていいようです。
試しに1500件のユーザー登録直後に、検証サーバを「電源オフ」で停止させてみましたが登録したユーザーは失われていませんでした。

このユーザー作成に伴うDBの遅延ですが、PHPを介した読み出しでも同様に遅延が誘発されます。
一方、大量のDB書き込みをしている場合でも、同じくDBを読みだしているはずのメール送受信は遅延しませんでした。
DovecotやPostfixなど、直接SQLクエリを呼び出している処理には影響しないようです。
(実際、ユーザー作成をしながらSQLiteから直接クエリを実行しても遅延はないが、PostfixAdminから情報を読み出すとユー ザー作成遅延が急増することから、やはりPostfixAdminのPHPが関連しているようです)

walへジャーナルが変更されると、ジャーナルファイルが目につくようになります。
#cd /srv/postfixadmin/database
#ls
postfixadmin.db  postfixadmin.db-shm  postfixadmin.db-wal
時間経過とともにデータベースロックが終わったり、OSを再起動したりすると結合されて、shmやwalファイルは消えます。時間経過に関し ては1時間くらい経っても消えないこともありますが、データが反映されていれば神経質にならないほうがいいでしょう。




ようこそメールの送信に失敗する

 ユーザー一括作成時にようこそメールを送信するオプションを付けると、けっこうな確率でメール送信がdefferします。
 DBへのユーザー登録と同時に、DBのユーザー情報を参照しようとしているためだと思いますが、defferしないこともあるので、タイミ ングの問題のように思われます。

 ちなみこの症状はSQLiteを使っているから、というわけでもなくMySQLを使用しても発生します。ただ発生頻度は、SQLiteのほ うが圧倒的に多い気がします。

 defferした場合でも、Postfixはデフォルト300秒で再送を試みるので、放っておけば解決します。
 すぐに再送処理をしたいのなら、以下コマンドを実行すれば、溜まっているメールが再送されます。
#postqueue -f




SQLiteで運用できるユーザー数はどのくらいまで?

SQLiteでユーザーを作成していくと、徐々にPostfixAdminのユーザー一覧の表示に時間がかかるようになっていきます。

登録ユーザーが300くらいならストレスありません。
600〜800ユーザー辺りから、画面遷移のタイムラグを感じます。
1000アカウントだと画面遷移に5秒ほどかかるようになり、ストレスに感じます。
1500アカウントだと20秒ほど、2000アカウントだとタイムアウトするのかServiceUnavailableが表示されます。
300は快適、1000アカウントあたりは運用に支障があり、2000アカウントは運用できない、と言えます。

一番頻度の高い操作のため、このパフォーマンスについては構築前に考慮すべきです。
これはSQLiteのときのみ発生するようで、MySQLの環境ではユーザー1500件の表示でも画面が遅くなることはまったくありませんで した。

またPostfixAdminのユーザー一覧表示が遅くなっても、他の画面やメール送受信の速度には影響ありません。

当初はSQLiteの速度のせいかと思いましたが、SQLiteに直接クエリを問い合わせると2000アカウントでもユーザー表示は一瞬で終 了します。
ですのでSQLite側が原因ではないと分かります。

画面遷移の度に、php-fpmのCPUが100%になっているので、これが原因のようです。
割り当てCPUを増やしてみましたが、処理は結局シングルスレッドなのでマルチコアにしても症状は改善しませんでした。

検証環境「Intel Core i5-4590 1コア/SSD」の仮想OSでは、300から500ユーザーが快適な範囲のようです。1コアあたりの性能が良いサーバーなら、1000ユーザーでもストレスなく画面遷移す るのかもしれません。
それでも1コアあたりの限界ユーザー数に達したら、それ以上の拡張や対策は難しいでしょう。
別DBへの乗り換えをお勧めします。

なお、ユーザーを数百単位で作ったり減らしたりを何度繰り返しても、最終的に300ユーザーだったら表示速度は速いままだったので、DBのフ ラグメンテーションについてはあまり心配しなくてよさそうです。





prev.gif