OpenSearchでデータ量が多い時にreindex APIがタイムアウトする問題を回避
OpenSearch
Typescript
reindex APIにて、wait_for_completionをtrueにして実行した時にデータ量が多いと、Request timeout エラーが発生する。 回避策として、wait_for_completionをfalseにした場合に返ってくる task id を用いて task 状況をチェックし、retry処理を入れることで回避した。
async reIndex(
sourceIndexName: string,
destinationIndexName: string,
): Promise<void> {
const response = await this.client
.reindex<ReindexResponse>({
wait_for_completion: false,
body: {
source: {
index: sourceIndexName,
},
dest: {
index: destinationIndexName,
},
},
})
.catch((error) => {
throw new Error(`Failed to reindex\nCause: ${error}`);
});
const taskId = response.body.task as string;
let retryCount = 0;
const maxRetries = 720; // 5秒間隔で1時間
while (retryCount < maxRetries) {
const isCompleted = await this.checkReindexTask(taskId);
if (isCompleted) {
return;
}
const waitTime =
process.env.NODE_ENV === 'local' || process.env.NODE_ENV === ''
? 300
: 5000;
await new Promise((resolve) => setTimeout(resolve, waitTime));
retryCount++;
if (retryCount % 10 === 0) {
this.logger.log(
`Checking reindex task status. TaskID: ${taskId}, Retry count: ${retryCount}/${maxRetries}`,
);
}
}
throw new Error(
`Reindex task did not complete within the expected time\nTask ID: ${taskId}`,
);
}
async checkReindexTask(taskId: string): Promise<boolean> {
try {
const response = await this.client.tasks.get<TaskGetResponse>({
task_id: taskId,
});
return response.body.completed;
} catch (error) {
throw new AWSServiceException(
`Failed to get task\nTask ID: ${taskId}\nCause: ${error}`,
);
}
}