SQLite は端的に言うと以下の特徴を持つRDBMSです。
- フリー
Public Domain と呼ばれるライセンスで個人・商用利用問わず無償です。 - 環境に依存しない
APIや接続用のライブラリがあれば(システムへのインストール作業なしに)利用可能。 - 高速 = 単純
複雑な機能を有していない代わりに高速です。 - DB = ファイル
DB が1ファイルのため管理が容易です。 - INSERT, UPDATE, DELETE は ファイルロックされる
※ロック中は当該 DB への SELECT も不可になる。
SQLite は実運用で使うと、DB がロックされやすい性質があります。
その際の解決策としては、以下の2つがあります。
- SQLite のタイムアウト時間を長く設定する
すぐエラーを返さずに Wait してくれます。 - 高速な記憶装置上に置く
ロック時間はデバイス(ファイルシステム)に依存するので、SSD など高速な記憶装置に移動することで影響を小さくできます。
手元に高速な USBメモリがあったのでそこに当該 DB を移動して高速化を図ることにしました。
base on RUF2-S512-WH
SLCを採用し、且つ2チップ同時転送で高速化したUSB2.0メモリ
目次
Redmine 高速化
DB(SQLite)用に高速デバイス(今回は USBメモリ)を用意して、入れ替えます。
M/W | デバイス |
---|---|
DB | USBメモリ |
DB以外 | microSD |
USBメモリのフォーマット
パーティション作成
fdisk コマンドで領域を確保します。
$ sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.29.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x0ae2bbf1.
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-1003519, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-1003519, default 1003519):
Created a new partition 1 of type 'Linux' and of size 489 MiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
/dev/sda1 が作成されました。
$ lsblk /dev/sda
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 1 490M 0 disk
└─sda1 8:1 1 489M 0 part
ファイルシステム作成
今回は ext3 で作成しました。
$ sudo mkfs -t ext3 /dev/sda1
mke2fs 1.43.4 (31-Jan-2017)
Creating filesystem with 500736 1k blocks and 125488 inodes
Filesystem UUID: fe75bf02-90ed-4823-b319-437ffcf4b607
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
デバイスの属性を確認
UUID(場合によって PARATUUID)を確認します。
$ blkid /dev/sda1
/dev/sda1: UUID="fe75bf02-90ed-4823-b319-437ffcf4b607" SEC_TYPE="ext2" TYPE="ext3" PARTUUID="0ae2bbf1-01"
USBメモリのマウント
マウントするディレクトリを作成
$ ls /media/
$ mkdir /media/usb512
マウント情報を記述
/etc/fstab ファイルに記述した後「mount -a」でテストしておきます。
$ diff -u /tmp/fstab /etc/fstab
--- /tmp/fstab 2019-03-13 14:11:20.431494925 +0000
+++ /etc/fstab 2019-03-13 14:18:44.358482664 +0000
@@ -1,2 +1,3 @@
UUID=b065c39b-25c7-4379-9e17-0f511ae83aa4 / ext4 defaults,noatime,nodiratime,commit=600,errors=remount-ro 0 1
tmpfs /tmp tmpfs defaults,nosuid 0 0
+UUID=fe75bf02-90ed-4823-b319-437ffcf4b607 /media/usb512 ext3 defaults,noatime 0 1
$ sudo mount -a
$ mount | grep sda
/dev/sda1 on /media/usb512 type ext3 (rw,noatime)
DB移動
USBメモリに DB格納用ディレクトリを作成
SQLite ファイルを置くディレクトリを USBメモリに作成します。
※パーミッションはあとで www-data に置換します。
$ mkdir /media/usb512/redmine_sqlite3
$ ls -lhd /media/usb512/redmine_sqlite3/
drwxr-xr-x 2 root root 1.0K Mar 13 14:22 /media/usb512/redmine_sqlite3/
移動前にサービス停止
$ sudo systemctl stop apache2
DB 実ファイルを確認
設定ファイル(database.yml)で場所を確認して、実ファイルを念の為チェックしておきます。
$ cat /etc/redmine/default/database.yml | grep sqlite
adapter: sqlite3
database: /var/lib/dbconfig-common/sqlite3/redmine/instances/default/redmine_default
$ ls -lh /var/lib/dbconfig-common/sqlite3/redmine/instances/default/redmine_default
-rw-rw---- 1 root www-data 776K Mar 12 11:52 /var/lib/dbconfig-common/sqlite3/redmine/instances/default/redmine_default
DBファイル移動
USBメモリにデータを移動します。
- 移動
$ mv /var/lib/dbconfig-common/sqlite3/redmine/instances/default/redmine_default /media/usb512/redmine_sqlite3/
- 移動の確認
$ ls /media/usb512/redmine_sqlite3/
redmine_default
- シンボリックリンク作成
$ sudo ln -s /media/usb512/redmine_sqlite3/redmine_default /var/lib/dbconfig-common/sqlite3/redmine/instances/default/redmine_default
- シンボリックリンク確認
$ ls -lh /var/lib/dbconfig-common/sqlite3/redmine/instances/default/
total 0
lrwxrwxrwx 1 root root 45 Mar 13 14:26 redmine_default -> /media/usb512/redmine_sqlite3/redmine_default
権限変更
パーミッションを apacheユーザ(www-data)に変更します。
$ ls -lh /media/usb512/redmine_sqlite3/redmine_default
-rw-rw---- 1 root www-data 776K Mar 13 14:01 /media/usb512/redmine_sqlite3/redmine_default
$ sudo chown -R www-data:www-data /media/usb512
$ ls -lh /media/usb512/redmine_sqlite3/redmine_default
-rw-rw---- 1 www-data www-data 776K Mar 13 14:27 /media/usb512/redmine_sqlite3/redmine_default
サービス起動
$ sudo systemctl start apache2
稼働確認
稼働確認して問題ないことを確認します。
エラーになった場合は、ログを確認します。
$ cat /etc/apache2/apache2.conf | grep error
# configuration, error, and log files are kept.
# ErrorLog: The location of the error log file.
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
ErrorLog ${APACHE_LOG_DIR}/error.log
# LogLevel: Control the severity of messages logged to the error_log.
# error, crit, alert, emerg.
$ cat /etc/apache2/apache2.conf | grep APACHE_LOG_DIR
ErrorLog ${APACHE_LOG_DIR}/error.log
$ cat /etc/apache2/envvars | grep APACHE_LOG_DIR
export APACHE_LOG_DIR=/var/log/apache2$SUFFIX
$ ls /var/log/apache2/
access.log error.log other_vhosts_access.log
結果
きちんと測定したわけではありませんが、体感速度は倍以上UPしました。
最近は SLC の USBメモリは出回っていませんが、I/O を microSD(システム)と USB(SQLite)で分けるだけでも効果があるはずなので一考の価値ありではないでしょうか。