システムアーキテクチャの設計
分散タスクキューを実装する際、主要コンポーネントとしてワーカープロセス、メッセージブローカー、タスク管理モジュールを設計する必要があります。Redisをメッセージブローカーおよび結果ストレージとして選定した理由は、軽量なインストール要件とCeleryとの高い互換性にあります。システム要件として、タスクのライフサイクル管理、エラーハンドリング、実行状況の可視化機能を組み込みます。
環境セットアップの最適化
依存関係は以下の構成で管理します:
celery==5.3.0
redis==4.6.0
flower==1.2.0 # モニタリング用
Redisサーバーの起動後、Celeryアプリケーションの初期化を次のように実装します:
from celery import Celery
task_app = Celery(
'distributed_tasks',
broker='redis://localhost:6379/0',
backend='redis://localhost:6379/1'
)
task_app.conf.update(
task_track_started=True,
task_time_limit=300,
task_retry_backoff=5,
result_expires=3600
)
タスク処理の実装例
以下の3種類の非同期処理を実装します:
1. ユーザー通知処理
@task_app.task(bind=True, max_retries=3)
def send_notification(self, user_id, message):
try:
# 通知サービスの実装
NotificationService.deliver(user_id, message)
return {'status': 'success'}
except ConnectionError as e:
self.retry(exc=e, countdown=2 ** self.request.retries)
2. 画像変換処理
@task_app.task()
def resize_image(image_path, target_size=(800, 600)):
with Image.open(image_path) as img:
img.thumbnail(target_size)
output_path = f"resized_{os.path.basename(image_path)}"
img.save(output_path)
return output_path
3. バッチ分析処理
@task_app.task()
def run_data_analysis(dataset_id):
dataset = DatasetLoader.load(dataset_id)
processor = AnalysisPipeline()
processor.register_step(Normalizer())
processor.register_step(StatisticalModel())
return processor.execute(dataset)
実行状況の可視化
タスク進捗をリアルタイムで追跡するため、Redisに進捗状況を格納するメカニズムを実装します:
def update_progress(task_id, current, total):
redis_client.setex(
f"progress:{task_id}",
3600,
json.dumps({'current': current, 'total': total})
)
# タスク内での使用例
update_progress(self.request.id, 5, 10)
Flowerを用いたモニタリングダッシュボードを構築することで、キューの状態、ワーカー負荷、タスク履歴を確認可能です。特に重要なのは、失敗タスクの自動リトライメカニズムと、各タスクタイプを専用キューに割り当てることによるリソース分離です。
テスト戦略の設計
単体テストではCeleryのテストモードを活用し、非同期処理を同期的に検証します:
def test_image_resize():
with task_app.pool.acquire(block=True) as connection:
result = resize_image("test.jpg")
assert result.startswith("resized_test.jpg")
assert os.path.exists(result)
タスクのべき等性を確保するため、各実行にUUIDを付与し、重複実行を防止する仕組みを組み込みます。また、タイムアウト設定と適切なリトライ戦略の組み合わせにより、ネットワーク不安定時の処理を堅牢にしています。