## SQLiteはProductionで使えない?!
よくSQLiteは遊びだけということ言われますが、実は結構SQLiteだけで行けます。
少なくとも趣味で作るサイトだと、そもそもそんなにトラフィックも来ないですし。
今ちょっとしたRailsのジョブバックエンドのGemを作っていて(Belated), そしてこのGemはSQLiteで使えて、かつRedisなくても簡単に誰でも使えるようにしようとしています。
ですが、今簡単な負荷テストをやっていて、そこで
ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked
というエラーが発生してしまいました。これはライトしている時にリードしようとしたからです。
しょうがない、PostgreSQLにするか・・・とも思ってしまいがちですが、実はSQLiteは同時にライトとリードを可能にするWALモードがあります。別ファイルに先にコミットされる内容を書いて、またそこからDBに入れることで、今までエラーになっている箇所でエラーは発生しなくなりました。
注意点として、起動時に毎回このWALモードにしないといけないことがあります。
# config/initializers/sqlite.rb
# Rails 7だと以下はActiveRecord::Base.connection_db_config.adapterに変更してください
if ::ActiveRecord::Base.connection_config[:adapter] == 'sqlite3'
if c = ::ActiveRecord::Base.connection
# see http://www.sqlite.org/pragma.html for details
# Setting of the "synchronous" flag, "NORMAL" means sync less often but still more than none
c.execute 'PRAGMA main.synchronous=NORMAL;'
# Journal mode for database, WAL=write-ahead log
c.execute 'PRAGMA main.journal_mode=WAL;'
end
end
これでパフォーマンスが全然違います!
エラーがでなくなり、処理できないリクエストはかなり減りました。
激安インスタンスで
Digital Oceanの一番安いインスタンスでサイトを運用していますので、できるだけ負荷少なくしたいです。
RubyのメモリーもMallocではなくJemallocをしようすることでかなり安定もしていて、全然余裕で月5ドルでRailsを走らせることができています。
ちなみにこのサイトです:
wasurechatta.com
リマインダーが送れるサイトを今構築していて、ただほぼGemの更新の方しかまだやってなくてPV数ぐらいしか今表示されないです。
負荷テスト
PV数はもう80万PVまで行っていますが!
以下コマンドのおかげです:
$ wrk -t14 -c400 -d10s https://wasurechatta.com
wrkはすごく便利に負荷テストができ、インストールも簡単です。sudo apt install wrk
かbrew install wrk
ですぐインストールできて試せます!
このSQLiteのチューニングをやるまえは負荷テストの時にアクセスできなくなることも多かったですが、今だとアクセスできなくはなりますが、システムのリソースが足りないだけですので、大丈夫かと!
## 結論
SQLiteはRailsのメインブランチで使うとProductionでは使わない方がいいかもしれないよ!というワーニングも出るぐらいですが、ちょっとした遊びのRailsのプロジェクトをデプロイすることにはProduction環境でもいいかと思っています。そこまで人気もでないでしょうし、本当に複数インスタンスにスケールしないといけない時などに不便にはなりますが、遊び程度のプロジェクトでそうなれば逆にラッキーですので、またその時の楽しみでいいかと思っています。
もっとチューニングしたい方は以下のサイト見てみてください!
https://phiresky.github.io/blog/2020/sqlite-performance-tuning/