分散大規模データ収集のプロセスでは、情報ソースの管理が特に重要です。同じタスクを同時に 1 つのコレクタのみで処理できるようにするには、タスクのスケジューリングの一意性を確保する必要があります。通常、分散データ収集を実行する場合は、収集タスクを分散し、タスクの一意性を確保することが主な役割であるスケジューリング モジュールが存在します。
分散型であるため、複数のサーバー (複数のマシン) が関与し、各サーバーは複数のコレクター (複数のプロセス) に関与し、各コレクターには複数のスレッドが関与する可能性があります。したがって、タスク内のロック メカニズムはスケジューリングモジュールは特に重要です。アプリケーションの実装アーキテクチャに応じて、ロック実装メソッドは通常、次のタイプに分類できます。
ハンドラーが単一プロセスおよびマルチスレッドの場合、Python では、スレッド モジュールの Lock オブジェクトを使用して、共有変数への同期アクセスを制限し、スレッド セーフを実現できます。
単一マシンと複数のプロセスの場合、Python ではマルチプロセッシングの Lock オブジェクトを使用して処理できます。
マルチマシンおよびマルチプロセス展開の場合、分散同期ロックを実装するには、サードパーティのコンポーネント (ストレージ ロック オブジェクト) に依存する必要があります。
スケジューリング モジュールはマルチマシン、マルチプロセス、マルチスレッドの処理メカニズムであるため、3 番目の方法と一致します。
#分散ロックの実装方法
現在主流の分散ロックの実装方法は次のとおりです。それぞれの実装方法にはそれぞれメリットがあり、総合的に検討した結果、Redis が最適です。主な理由は、
- Based on mysql などのデータベース
#redis などのキャッシュに基づく- #zookeeper に基づく
ただし、redis を使用して実装された分散ロックは、次の条件も満たす必要があります。
- redis はメモリをベースに動作するため、データベースよりもアクセス速度が速く、同時実行性が高くてもロック後のパフォーマンスがそれほど低下しないためです
- redis はキー値の生存時間 (TTL) を設定できます
- redis は使いやすく、全体的な実装オーバーヘッドが低くなります
データの一貫性を確保するために、redis を使用して分散同期ロックを実装します。これは次の特性を満たす必要があります。
- 1 つのスレッドのみが占有できる他のスレッドはロックが解放されるまで待機する必要があります
- ロック操作はアトミック性を満たす必要があります
- デッドロックは発生しません。ロックを取得したときなど スレッドがロックを解放する前に突然異常終了し、他のスレッドがロックの解放をループで待機することになる
- ロックは同じスレッドによって設定する必要があります
実際の操作プロセスでは、スケジューリング モジュールを分離しました。 Java クライアント Jredis (JRedis は、Redis 分散ハッシュ キー/値データベースに接続するために使用されるハイエンドの高性能 Java クライアントです。Spring Boot を使用して同期および非同期を実装する独立したサービス) に基づいて、コレクション システム全体から収集します。これにより、他のコレクターが HTTP 経由で処理される収集タスクをリクエストできるようになります。処理プロセスは大まかに次のとおりです:
- 相互排他性を満たし、同時にロックを取得できるのは 1 つのスレッドのみです。
- Redis の ttl を使用してデッドロックが発生しないようにします。が発生しますが、ロックの有効期限による問題も発生します。複数のスレッドが同時にロックを占有するという問題があるため、
- 使用を避けるために、ロックの有効期限を合理的に設定する必要があります。ロックが誤って削除されないようにするためのロックの一意性
public static List有効期限
を追加する必要があります。そうしないと、不明な例外が発生した場合にロックが解放されず、コレクタが収集タスクを取得できなくなる可能性があります。
以上がRedis 分散ロックに基づいてタスク スケジューリングを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。