0

「未処理」と呼ばれるテーブルがあり、2000 行を読み取り、HTTP 経由で別のサーバーに送信してから、その行を「処理済み」テーブルに挿入し、「未処理」テーブルから削除します。

私のpythonコードはおおよそ次のようになります:

db = MySQLdb.connect("localhost","username","password","database" )

# prepare a cursor object using cursor() method
cursor = db.cursor()

# Select all the records not yet sent
sql = "SELECT * from unprocessed where SupplierIDToUse = 'supplier1' limit 0, 2000"
cursor.execute(sql)
results = cursor.fetchall()
for row in results:
  id = row[0]
  <code is here here for sending to other server - it takes about 1/2 a second>
  if sentcorrectly="1":
     sql = "INSERT into processed (id, dateprocessed) VALUES ('%s', NOW()')" % (id)
     try:
        inserted = cursor.execute(sql)
     except:
        print "Failed to insert"
     if inserted:
        print "Inserted"
        sql = "DELETE from unprocessed where id = '%s'" % (id)
        try:
            deleted = cursor.execute(sql)
        except:
            print "Failed to delete id from the unprocessed table, even though it was saved in the processed table."
db.close()
sys.exit(0)

これらのレコードを HTTP 経由で他のサーバーに送信する速度を上げることができるように、このコードを同時に実行できるようにしたいと考えています。現時点で、コードを同時に実行しようとすると、選択クエリがコードの複数のインスタンスで同じ ID を取得しているため、同じデータの複数のコピーが他のサーバーに送信され、「処理済み」テーブルに保存されます。

レコードを選択してロックし、各レコードを「処理済み」テーブルに移動する前に行として処理するにはどうすればよいですか? テーブルは MyISAM でしたが、おそらく innoDB でレコードをより適切にロックする方法があることに気付いたので、今日 innoDB に変換しました。

4

1 に答える 1

1

コメントの返信に基づいています。

2 つのソリューションのうちの 1 つは、クライアント側の Python マスター プロセスで 2000 レコードすべてのレコード ID を収集し、それをチャンクに分割してサブ ワーカーで処理することです。

短いバージョンでは、作業を委任するか、おそらくトリッキーなアセット ロック メカニズムに依存するかを選択できます。メッセージキューを使用してスケールアップできるため、前者のアプローチをお勧めします。

委任ロジックはマルチプロセッシングを使用します

import multiprocessing
records = get_all_unprocessed_ids()
pool = multiprocessing.Pool(5) #create 5 workers
pool.map(process_records, records) 

これにより、2000 のタスクが作成され、一度に 5 つのタスクが実行されます。または、ここで概説されているソリューションを使用して、レコードをチャンクに分割することもでき ます。

pool.map(process_records, chunks(records, 100)) 

5 つのバッチで処理される 100 レコードの 20 のリストを作成します

編集: 構文エラー - 署名は map(func, iterable[, chunksize]) で、func の引数を省略しました。

于 2013-04-16T17:01:13.247 に答える