背景
B サイド システムでは、バッチ処理機能が不可欠であり、ユーザーが一連のアクションをバッチで完了し、反復操作のコストを削減するのに役立ちます。ビッグプロモーション投資促進システムでは、マーチャントのバッチ商品登録、バッチメイン画像マーキング、ワンクリック公開、提出された商品のエクスポートなどをサポートするオンラインバッチ処理フレームワークも必要です。これにより、マーチャントはデータをバッチアップロードして、操作記録を管理し、バッチ操作の詳細な結果を表示します。これらのタスクの入力データは、Excel、DB、OpenSearch などを含むさまざまなソースから取得されます。フレームワークは、さまざまなタイプの入力データの解析をサポートできる必要があります。同時に、投資促進システムには多数のアプリケーションがあり、同時にさまざまなドメインのアプリケーションへの便利なアクセスをサポートできる必要があるため、パッケージのみを導入してからタスク ロジックを実装するのが最善です。 。大量のデータを含むシナリオでは、フレームワークは、システムのスループットと安定性を確保しながら、さまざまな種類のタスク インスタンスの洗練されたスケジューリングをサポートする必要があります。
プログラム全体
▐建築設計
ビジネスコンテナはフレームワークにアクセスするアプリケーションであり、タスクセンターはバッチ処理フレームワークの中心となるアプリケーションです。インスタンスのスケジューリングやステータス変更はタスクセンターで完結するため一元管理が容易ですが、インスタンスの実行ロジックはビジネスコンテナに実装されているため、実行時にビジネスコンテナをコールバックする必要があります。
▐モデル 設計
単一データ項目の次元でタスク インスタンスをスケジュールするには、タスク登録情報とタスク インスタンスに加えて、サブタスク インスタンスのモデルも導入する必要があります。タスク登録情報オブジェクトには、あるタスクのタスク種類や実行電流制限値などの情報が含まれる。ユーザーがデータをバッチでアップロードするたびに、メイン タスク インスタンスが生成され、1 つのデータ項目がサブタスク インスタンスに対応します。
▐主な工程
コアプロセスはMapReduceのアイデアを利用しており、大きなタスクを分割して複数のマシンに分散して実行し、最終的に結果を要約します。ビジネスコンテナに接続する場合、タスクのメインインスタンスの分割、サブインスタンスの実行、結果のマージロジックを実装する必要があります。メインインスタンスが分割されると、ユーザー入力データはサブインスタンスに解析されて DB に保存されます。サブインスタンスの実行は、単一のデータ項目の実行ロジックです。結果のマージは、統計後にサブインスタンスの処理結果を表示します。 (Excel でタスクの詳細を生成するなど)。
▐ステートマシン
サブタスク
技術的なポイント
▐実行のスケジュール設定
電流制限コンポーネント
電流制限コンポーネントは、guava パッケージの実装を使用します。タスクを登録するとき、メイン インスタンスとサブインスタンスの実行の電流制限値をそれぞれ構成する必要があります。電流制限はタスク タイプ ディメンションでも行われます。スケジューリング中に、対応する電流制限値は、タスクデバイスのキーに従って取得されます。電流リミッターはマシン上でローカルにキャッシュされ、有効期限が切れると、タスク登録情報が再照会され、新しい電流リミッターが作成されます。現在、電流制限は単一マシンのディメンションでのみ実装されています。クラスタの電流制限数をタスク センター内のクラスタ マシンの数で割って、単一マシンの電流制限値を取得します。
マスターインスタンスのスケジューリング
タスクインスタンス作成後、一度トークンの取得を試み、取得できた場合は直接メインインスタンスを起動して以降の処理を実行します。トークンが取得されない場合、タスクはトリガー保留状態のままになり、ScheduleX タスクが定期的に取得されるのを待って実行を再試行します。
サブインスタンスのスケジュール設定
サブインスタンスのステータスを更新する前にマシンが再起動された場合、mq の再試行メカニズムを使用して、冪等タスク タイプを直接再実行できます。冪等タスクをサポートしていないタスク タイプの場合、サブインスタンスは直接更新されて失敗する可能性があります。メッセージが再試行されるとき。
▐センターとクライアント間のコミュニケーション
タスクの実装ロジックを実行するときは、ビジネス コンテナをコールバックする必要があり、SDK はタスク センターによってアクティブに開始される通信方法をサポートする必要があります。具体的な実装は次のとおりです。
クライアント側: Dubbo インターフェースを提供し、ビジネス アプリケーションの起動時にサービスを登録し、異なるアプリケーションを区別するために Dubbo グループを使用します (グループを繰り返すことはできないため、アプリケーション名をグループとして直接使用します)。
タスクセンター側: すべてのビジネスアプリケーションサービスのコンシューマとして登録します。ビジネスコンテナをコールバックする必要がある場合、まずタスクに登録されているアプリケーションに基づいて対応するコンシューマを見つけ、そのコンシューマを介してビジネスアプリケーションへの呼び出しを開始します。 。
メイン インスタンスは分割され、その結果は非同期呼び出しを使用してマージされます。サブインスタンスはすでに分割の結果であることを考慮して、現在は同期呼び出しのみをサポートしています。
▐探索の例
メイン インスタンスの分割と結果のマージの実行には時間がかかり、極端なシナリオでは数十万のデータが読み書きされることを考慮すると、メイン インスタンスの分割と結果のマージはすべてクライアントへの非同期呼び出しです。非同期シナリオでは、ビジネス アプリケーションを検出して再試行する方法を検討する必要があります。そうしないと、マシンが再起動された後、実行中のタスク インスタンスが中間状態に留まり、大量のダーティ データが生成されます。
ライブ検出に使用されるソリューションは、クライアント側でハートビートを報告し、タスク センター側でスケジュールされたタスクでハートビートを検出することです。リクエストを受信した後、クライアントはタスク インスタンスのハートビートをローカルで定期的に報告します。つまり、DB 内のインスタンスのハートビート時間を更新します。実行が完了すると報告しなくなります。タスク センターは、ScheduleX タスク テーブルをスキャンしてハートビート タイムアウトのあるタスク インスタンスを検出し、クライアントへのリクエストを再開始します。
▐クライアント 実装
"myDemo") (key =
public class MyDemo implements MapReduceTask {
/**
* 主任务实例拆分
*
* @param context context
* @return {@link TaskResult}
*/
public TaskResult processInstance(ExecuteContext executeContext) {
while (true) {
// 分批读取输入数据
...
// 生成子实例
List<SubInstance> subInstances = ...;
// 提交数据
executeContext.commit(subInstances);
}
return TaskResult.success();
}
/**
* 子任务实例执行
*
* @param context context
* @return {@link TaskResult}
*/
public TaskResult map(SubExecuteContext subExecuteContext) {
// do something
...
return TaskResult.success();
}
/**
* 结果合并
*
* @param context 上下文
* @return {@link TaskResult}
*/
public TaskResult reduce(ExecuteContext executeContext) {
do {
// 读取子实例
List<SubInstance> subInstanceList = executeContext.read(pageSize);
if (CollectionUtils.isEmpty(subInstanceList)) {
break;
}
// 构建结果明细
...
} while (subInstanceList.size() == pageSize);
// 生成结果数据
Map<String, Object> resultInfoMap = ...;
return TaskResult.success(resultInfoMap);
}
}
メインタスクの分割および結果マージロジックでは、サブインスタンスでそれぞれ読み取り操作と書き込み操作が必要となるため、タスク実行コンテキスト ExecuteContext では、クライアントが呼び出すための commit() メソッドと read() メソッドが提供されます。そのうち、書き込みロジックは、ビジネス コンテナ内でサブインスタンス オブジェクトを構築して送信する必要があります。
サブインスタンスの読み書きで毎回Dubbo経由でタスクセンターを呼び出すと、高頻度の読み書きによりネットワークタイムアウトなどの例外が増加することを考慮し、DBソリューションへの直接接続を採用し、 SDK には DB との対話層が組み込まれています。DBへの書き込み効率を高めるため、コミットされたデータはタスク実行コンテキストのバッファに格納され、しきい値を超えた後、バッチでDBにデータが挿入され、最後にバッファが削除されます。クリアされ、残りのデータが挿入されます。
効果と展望
新しいバージョンのバッチ処理フレームワークがリリースされた後、バッチ登録、ワンクリック登録、提出された商品のエクスポート、バッチキャンセルなどの複数の主要なマーチャント操作の移行とアクセスが完了し、完全かつ安定的にサポートされています。このダブル イレブン プロモーションの投資プロモーション。130W 以上のタスク インスタンスを処理しました。現時点では、システム全体は比較的安定しており、タスクを柔軟に設定でき、システム全体を監視できます。
今後の最適化の方向性について: サブインスタンスは mq を介して分散されるため、多数のサブインスタンスが実行されて電流制限がかかると、他のタスクの電流制限がされていない後続のサブインスタンスからのメッセージがブロックされる可能性があります。現在は、ビジネスアイデンティティごとにメッセージを分離し、送信レートの上限を大まかに制御していますが、将来的には、単一マシンのメッセージ送信レートと、メッセージの送信レートを一致させることで、極端なシナリオにおけるシステム全体のスループットの向上を目指します。クラスター消費、およびさまざまなタイプのタスクのグループ消費。
淘天核心技术团队,持续建设全网比价、用增、交易、招商、选品、搭建、投放等能力,支撑大促(双11、618等)和日销业务。简单、高效、纯粹的技术文化,在使命与责任中互相成就,共同成长。
Base杭州职位热招中:Java开发工程师、前端工程师、测试开发工程师、数据分析师。详情联系:[email protected]
本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。