2015-06-28 2 views
0

У меня есть запрос, какИнкрементальное обновление в значении столбца в mysql. Проблемы параллелизма?

update pageviews set count = count + 1 where pageid = $pageid 

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

Мой стол - тип InnoDB.

Предполагая, что тысячи просмотров страниц могут происходить в секунду, разве это не масштабируемо? Могу ли я столкнуться с проблемами параллелизма? Как блокировка запросов и т. Д.?

Кто-то сказал мне, что я должен использовать очереди для таких целей. Зачем мне нужна очередь? В каком состоянии могут быть повреждены мои данные или масштабируемость может стать проблемой?

ответ

1

Из-за коробки, на товарном оборудовании, InnoDB обрабатывает около 100 таких утверждений в секунду. Нет проблем с параллелизмом или блокировкой, а также проблем с производительностью.

  • innodb_flush_log_at_trx_commit по умолчанию 1 для обеспечения безопасности. Но для каждого транзакции требуется диск ввода/вывода. 2 намного быстрее и разумный компромисс. (Авария может потерять транзакции на одну секунду.)

  • Возможно, что ваш UPDATEautocommited? Или в транзакции само по себе? Может ли это быть любым способом? Если это так, это сократит накладные расходы.

  • Просмотр страниц обрабатывается веб-сервером, правильно? Может ли он собрать некоторые страницы перед тем, как писать в таблицу? Даже если он собрался в течение одной секунды, это может стать значительным ускорением. Если вы сделаете это, не забудьте отсортировать список IN в update pageviews set count = count + 1 where pageid IN (...). Это уменьшит вероятность взаимоблокировок.

  • Обрабатывать ошибки с вашего UPDATE. (В противном случае, ваши данные будут «неправильно» или «поврежден».)

1

В дополнение к @ ответ Рик: Я не знаю, как очередь может помочь вам, единственная мысль, что у меня есть, чтобы отправить все события страницы в очереди, где у вас есть несколько потребителей, каждый из которых обновляет свою собственную базу данных, а результаты агрегируются позже. Кроме того, очередь позволяет обрабатывать некоторые пиковые нагрузки, когда в течение короткого периода времени много загрузок - в этом случае вместо блокировки обновлений базы данных вы будете помещать события в память, и они будут обработаны позже, но это не поможет если вы не можете обрабатывать поток событий при регулярной нагрузке.

И еще одно предложение - если у вас тысячи просмотров страниц в секунду, возможно, вам не нужно отслеживать их точно (если это не биллинг), поэтому вы можете иметь такой код, если у вас есть состояние сервер:

onPageView() { 
    cnt += 1 
    if (cnt == 1000) {update table set views = views + 1000; counter = 0;} 
} 

(не забывайте о безопасности потоков)

или даже

onPageView() { 
    value = random(0, 1000); 
    if (value == 0) { 
     update table set views = views + 1000 
    }  
} 

и вам не нужно заботиться о состоянии и вы уменьшаете количество записей в 1000 раз

Смежные вопросы