Является ли Redis атомарным, когда несколько клиентов пытаются одновременно прочитать / записать элемент? - PullRequest
0 голосов
/ 29 августа 2018

Допустим, у меня есть несколько функций AWS Lambda, которые составляют мой API. Одна из функций считывает определенное значение с определенной клавиши на одном узле Redis. Бизнес-логика выглядит следующим образом:

if the key exists:
    serve the value of that key to the client
if the key does not exist:
    get the most recent item from dynamoDB
    insert that item as the value for that key, and set an expiration time
    delete that item from dynamoDB, so that it only gets read into memory once
    Serve the value of that key to the client

Идея состоит в том, что каждый раз, когда клиент делает запрос, он получает необходимое ему значение. Если срок действия ключа истек, lambda должен сначала получить элемент из базы данных и вернуть его в Redis.

Но что произойдет, если 2 клиента одновременно вызовут API-интерфейс к лямбде? Будут ли оба лямбда-процесса читать, что ключа нет, и оба будут брать элемент из базы данных?

Моя цель состоит в том, чтобы создать очередь, в которой определенный элемент находится в памяти только X раз, и как только этот элемент истекает, следующий элемент должен быть извлечен из базы данных, и когда он извлекается, он должен также будет удален, чтобы он не был извлечен снова.

Я пытаюсь понять, есть ли способ сделать это без отдельного процесса EC2, который просто отслеживает время.

Является ли Redis + Lambda + DynamoDB хорошей установкой для того, что я пытаюсь выполнить, или есть лучшие способы?

1 Ответ

0 голосов
/ 30 августа 2018

Сервер Redis будет выполнять команды (или транзакции, или сценарии) атомарно. Но последовательность операций с участием отдельных служб (например, Redis и DynamoDB) не будет атомарной.

Один из подходов состоит в том, чтобы сделать их атомарными, добавив некоторую блокировку вокруг вашей бизнес-логики. Например, можно сделать с помощью Redis .

Однако это дорогое и довольно громоздкое решение, поэтому, если возможно, лучше просто спроектировать свою бизнес-логику так, чтобы она была устойчивой перед лицом одновременных операций. Для этого нужно посмотреть на шаги и представить, что может произойти, если одновременно работают несколько клиентов.

В вашем случае я вижу недостаток в том, что два значения могут быть считаны и удалены из DynamoDB, одно записано поверх другого в Redis. Этого можно избежать, используя команду Redis SETNX (SET, если не eXists). Примерно так:

GET the key from Redis
If the value exists:
    Serve the value to the client
If the value does not exist:
    Get the most recent item from DynamoDB
    Insert that item into Redis with SETNX
        If the key already exists, go back to step 1
    Set an expiration time with EXPIRE
    Delete that item from DynamoDB
    Serve the value to the client
...