Обновление данных

Artnt

Новичок
Добрый день.


Нужна помощь в решение следующей проблемы.

Есть приложение, серверная часть которого во время своей работы использует memcached и mySQL.
Соответственно в memcached и mySQL имеется поля value, flag
value = 1000 - число которое нужно изменить
flag = false - флаг показывает было ли изменено число


Во время запроса к серверу выполняются следующие действия:

Проверяется поле flag
Если значение в нем равно false, то элементу value (в memcached и в mySQL) прибавляется некоторое число к примеру 100. Далее полю flag присваивается значение true (чтобы нельзя было вызвать это действие повторно).

Если запросы приходят с интервалом в 1-2 секунды, то все работает нормально.

Однако если в 1 секунду приходит 300-400 запросов, то value увеличивается не на 100, а на 30 000 - 40 000. Видимо это происходит из-за задержки обмена данными между php с memcached и mySQL - запросы на чтение данных обрабатываются быстрее чем на запись.

Подскажите как можно на сервере предупредить такую ситуацию. Что бы данные в таблицу записывались только 1 раз.
 

Raziel[SD]

untitled00
Сделай отдельный скрипт, который будет обновлять данные в мемкэше, а на фронэнде только читать мемкэш.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в memcache нет полей, только ключ и значение
зачем тебе здесь memcahced, если при каждом запросе тебе надо обновлять значение в базе?

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

попробуй объяснить свою задачу какой-нибудь женщине, когда она поймет - напиши сюда, что конкретно тебе надо
 

Artnt

Новичок
Не совсем понял
Т.е. вы предлагаете чтобы в текущем запросе данные в мемкеше не обновлялись? Тогда получается, что для вызова "отдельного скрипта" необходимо сделать отдельный запрос. Но ему все равно же придется получить данные в этом скрипте, которые будут указывать что нужно переписать.

Можно конечно сохранить их в отдельное место. А потом при каком-то запросе запускать "отдельный скрипт" который будет выбирать требуемые данные и записывать их. Однако появляется вопрос что будет мешать пользывателю послать эти же 300 запросов для вызова "отдельного скрипта"?
 

Artnt

Новичок
В приложение данные вычитывающий из memcahced по ключу. Если их нет в memcahced то они вычитываются из БД по id пользывателя (если данные есть в memcahced то БД не трогается вобще ).
Когда записываем, то данные по ключу Обновляются в memcahced, а в бд обновляется соответствующая запись по id уникального пользывателя.

memcahced нужен для ускорения работы приложения, так как записи происходят редко, а вычитывание данных часто.

Т.е. для простоты можно считать что данные вычитываются из memcahced и в него же сохраняются.

Проблема состоит в том что в 1 секунду к memcahced отправляется 300 запросов на запись и 300 запросов на считывание информации. Причем запросы на чтение обрабатываются быстрее, чем на запись.

Т.е. превоночально flag = false
При первом запросе данные считались, и был отправлен запрос на запись (т.е. flag = true).
На втором шаге данные считываются, но в место ожидаемого flag = true, приходит flag = false; соответственно отправляется повторный запрос на запись.
И так еще 298 раз.

Затем по истечению времени до memcahced приходят все же 300 запросов на запись.
Проблема состоит в том чтобы не допустить такого.

Как можно корректно обработать изменения этих 300 запросов?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
у тебя русский не родной? сложно читать рассогласование падежей и родов
 

fixxxer

К.О.
Партнер клуба
Чего то ты там наворотил, когда ты инкрементишь то, я не пойму.

Ну давай проведем мысленный эксперимент. Пусть у нас будет не мемкеш а обычный файл на диске, который ты когда надо лочишь. Тогда что?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
расскажи хоть, что за "данные вычитывающий из memcached", какая именно операция их меняет ...
 

Mamont

Новичок
Однако если в 1 секунду приходит 300-400 запросов, то value увеличивается не на 100, а на 30 000 - 40 000. Видимо <...> запросы на чтение данных обрабатываются быстрее чем на запись.
Сам себе противоречишь: если на следующем запросе получаем обновленные данные, значит на предыдущем этапе успели записать в мемкеш
Представляется следующий алгоритм:
PHP:
$flag = MemCache->get('flag');
$value =  MemCache->get('value');
if( !$flag ) // не изменялось, надо пересчитать
{
   $value += 100;

   sleep(1); /Думаем...

   MemCache->set('flag', true); //Йёпть, а остальные то не в курсе...
   MemCache->set('value', $value);
}
 

Xupypr

Новичок
какой нафиг сет... сразу
MemCache->increment('value', 100);
MemCache->replace('flag', true);

если ключи есть, то зачем нам их значения, ели в любом случае их менять.
 
Сверху