現在のコードを書き換えることなく、ブローカー(キューの保存先)だけを SQLite から Redis へ差し替える手順です。
これにより、SQLiteの「database is locked」問題が完全に解消され、メモリ消費も最小限に抑えられます。
ステップ1:Redis本体のインストール
まずはホストOS(Ubuntu)にRedisサーバーをインストールして起動します。
sudo apt update
sudo apt install redis-server -y
sudo systemctl enable --now redis-server
ステップ2:PythonのRedisライブラリをインストール
仮想環境に入り、django-q2 が Redis と通信するためのライブラリをインストールします。
# 仮想環境を有効化(パスはご自身の環境に合わせてください)
source /venv/bin/activate
# redisパッケージをインストール
pip install redis
ステップ3:Django側の設定(settings.pyの修正)
プロジェクトの settings.py を開き、Q_CLUSTER の設定を書き換えます。
SQLiteを使用する設定('orm': 'default')を削除し、redis の接続情報を追記します。
Q_CLUSTER = {
\'name\': \'q_cluster\',
\'workers\': 2, # CPUコア数やメモリに合わせて2〜4程度に制限(重要)
\'recycle\': 500, # メモリリーク防止のため、500回タスクを処理したらワーカーを再起動
\'timeout\': 60, # タスクのタイムアウト(秒)
\'retry\': 120, # 失敗時の再試行までの時間(秒)
\'queue_limit\': 50, # メモリに展開するタスク数の上限
\'bulk\': 10, # 一度に処理するタスク数
# ここから下がRedisブローカーの設定(\'orm\': \'default\' は削除すること)
\'redis\': {
\'host\': \'127.0.0.1\',
\'port\': 6379,
\'db\': 0, # データベース番号(0〜15)
\'password\': None,
\'socket_timeout\': None
}
}
ステップ4:孤児プロセスの完全キル(超重要)
現在裏で暴走している古いクラスター群を、OSレベルで一度すべてキルします。これをやらないと、古いプロセスがいつまでもSQLiteを見に行ってしまいます。
sudo pkill -f qcluster
# 何も表示されなければ全員死んでいます
ps -ef | grep qcluster
ステップ5:Systemdサービスファイルの修正(孤児化対策)
前回の暴走を二度と起こさないため、Systemdのサービスファイル(例: /etc/systemd/system/q-qcluster.service など)を開き、[Service] セクションに KillMode=mixed を追記します。
[Unit]
Description=Django-Q2 Worker
After=network.target redis-server.service
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/q-tools
ExecStart=python manage.py qcluster
# ===== 孤児プロセスを許さない設定 =====
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=10
# ======================================
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
ステップ6:反映と起動確認
Systemdの設定をリロードし、ワーカーを起動します。
sudo systemctl daemon-reload
sudo systemctl restart q-qcluster.service
起動したら、正しくRedisに繋がってタスクを待機しているか、以下のコマンドでモニター画面を開いて確認します。
python manage.py qmonitor
エラーが出ず、プロセス数が settings.py で設定した workers の数(上記設定なら親1つ、ワーカー2つなど)で安定していれば、Redisへの完全移行は成功です。

コメント