Pythonにバックアップソリューションを実装したいのですが、バックアップサーバーが複数の仮想サーバーと物理サーバーでバックアップを開始します(1サーバー= 1バックアップタスク)。実際のバックアップタスクの詳細は無視します。今のところ、スケジューリング/マルチプロセッシングの部分に関心があります。
私が持っている制約は:
Pythonでのマルチプロセッシングの経験があまりないので、最適なPythonソリューションが何であるかを考えています。以下が私の頭に浮かびました:
threading.BoundedSemaphore
を使用すると、2つだけが同時に実行されます。より多くのセマフォ/条件を使用して、複数のスレッドが同じ物理マシン上の2つのサーバーをバックアップしないようにします。Queue.PriorityQueue
追加の制約を追加します。私は2番目のオプションに傾いていますが、キューが複数の作業スレッドにタスクを渡すのに適切なデータ構造であるかどうかはわかりません。実行時にキューにタスクを追加する必要はありません(キューで許可されています)。線形順序でタスクを処理するだけでなく、タスクを渡すための少しのロジックが必要です。これにはより良い(標準の)データ構造がありますか?
より経験豊富なプログラマからの意見を聞いていただければありがたいです。
物理マシンごとにキューがあります。
したがって、バックアッププロセスは最大でN = 2のタスクを実行し、別のタスクがすでに実行されているキューからタスクを選択しないようにします。
(Nは必要に応じて簡単に調整できます。)
人生をはるかに簡単にし、定型コードをはるかに少なくするために、 Advanced Python Scheduler
を確認することをお勧めします
作業を開始するのは非常に簡単で、キュー、スレッド、およびスケジューリングの管理の時間と手間をすべて省きます。
マルチプロセスまたはスレッドモードで実行できます。簡単な設定で一度に実行するタスクの数を制限できます。 ここの例を参照
それはさらに良くなり、すでに前のタスクがまだ実行されている場合は同じタスクを再度実行せず、max_instances: 1
を設定して終了するまで待機します。
状態が必要な場合は、ジョブストアを使用してタスクを永続化できます。
コード例:
from pytz import utc
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.jobstores.mongodb import MongoDBJobStore
from apscheduler.jobstores.redis import RedisJobStore
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
jobstores = {
'mongo': MongoDBJobStore(),
'redis' : RedisJobStore(),
'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')
}
executors = {
'default': ThreadPoolExecutor(20),
'processpool': ProcessPoolExecutor(5)
}
job_defaults = {
'coalesce': False,
'max_instances': 3
}
scheduler = BackgroundScheduler(jobstores=jobstores, executors=executors, job_defaults=job_defaults, timezone=utc)
def backup_job(**kwargs):
print('doing backup stuff')
scheduler.add_job(backup_job, 'interval', seconds=600, jobstore='redis'
id=1, name='backup', kwargs={'key':'value'})
それが役に立てば幸い