У меня есть лямбда-функция, которая выполняет транзакцию в DynamoDB, подобную этой.
try {
const reservationId = genId();
await transactionFn();
return {
statusCode: 200,
body: JSON.stringify({id: reservationId})
};
async function transactionFn() {
try {
await docClient.transactWrite({
TransactItems: [
{
Put: {
TableName: ReservationTable,
Item: {
reservationId,
userId,
retryCount: Number(retryCount),
}
}
},
{
Update: {
TableName: EventDetailsTable,
Key: {eventId},
ConditionExpression: 'available >= :minValue',
UpdateExpression: `set available = available - :val, attendees= attendees + :val, lastUpdatedDate = :updatedAt`,
ExpressionAttributeValues: {
":val": 1,
":updatedAt": currentTime,
":minValue": 1
}
}
}
]
}).promise();
return true
} catch (e) {
const transactionConflictError = e.message.search("TransactionConflict") !== -1;
// const throttlingException = e.code === 'ThrottlingException';
console.log("transactionFn:transactionConflictError:", transactionConflictError);
if (transactionConflictError) {
retryCount += 1;
await transactionFn();
return;
}
// if(throttlingException){
//
// }
console.log("transactionFn:e.code:", JSON.stringify(e));
throw e
}
}
Это просто обновление 2 таблиц по вызову API. Если он сталкивается с ошибкой конфликта транзакций, он просто повторяет транзакцию, рекурсивно вызывая функцию.
Таблица eventDetails получает слишком много обновлений в дБ. (проверил это с помощью aws Contributor Insights), поэтому установил единицу к более высокому значению, чем раньше.
Для ReservationTable Предоставленная емкость по требованию.
Когда я выполняю нагрузочный тест для этого API с 400 (или более) пользователей, использующих JMeter (конфигурация master-slave) Я получаю ошибку Throttled для некоторых вызовов API, а некоторым API требуется более 20 se c для ответа. Когда я проверил X-Ray для этого API-интерфейса, обнаружил, что DynamoDB отнимает слишком много времени для этого перехода для медленных вызовов API.
Даже при большом фиксированном обеспечении (я тоже пытался масштабировать по требованию), Я получаю душевное исключение для вызовов API.
ProvisionedThroughputExceededException: The level of configured provisioned throughput for the table was exceeded.
Consider increasing your provisioning level with the UpdateTable API.
ОБНОВЛЕНИЕ
И еще одна вещь. Когда я выполняю нагрузочное тестирование, я всегда использую один и тот же идентификатор события. Это означает, что я всегда обновляю одну и ту же строку для всех запросов API. Я нашел эту статью, в которой говорится, что один раздел может иметь до 1000 WCU. Поскольку я всегда обновляю одну и ту же строку в таблице eventDetails во время нагрузочного тестирования, это вызывает эту проблему?