Высокие concurrency счетчики без осколков

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

Мои вопросы:

  • Что касается №1: Выполнение memcache.decr() в отложенной транзакционной задаче кажется излишним. Если memcache.decr() выполняется за пределами транзакции, я думаю, что в худшем случае транзакция терпит неудачу, и мы пропускаем подсчет того, что мы уменьшаем. Могу ли я игнорировать некоторые другие проблемы, которые могут возникнуть при этом?
  • Каковы существенные компромиссы между двумя реализациями?

Вот компромиссы, которые я вижу:

  • 2 не требует транзакций хранилища данных.

  • Для получения значения счетчика # 2 требуется выборка хранилища данных, а при # 1 обычно требуется только memcache.get() и memcache.add().
  • При добавлении счетчика оба вызова memcache.incr(). Периодически # 2 добавляет задачу в очередь задач, в то время как # 1 транзакционно выполняет сбор данных. # 1 также всегда выполняет memcache.add() (чтобы проверить, настало ли время для сохранения счетчика в хранилище данных).

<я > Выводы

(без фактических тестов производительности):

  • 1 обычно должен быть быстрее при получении счетчика (# 1 memcache vs # 2 datastore). Хотя # 1 также должен выполнить дополнительный memcache.add().

  • Тем не менее, # 2 должно быть быстрее при обновлении счетчиков (# 1 datastore get + put vs # 2 задает задачу).
  • С другой стороны, С# 1 вам нужно быть более осторожным с интервалом обновления, поскольку квота очереди задач почти на 100 раз меньше, чем API-интерфейсы хранилища данных или memcahce.

Ответ 1

Переход к хранилищу данных, скорее всего, будет дороже, чем переход через memcache. Иначе memcache не будет полезен в первую очередь: -)

Я бы порекомендовал первый вариант.

Если у вас есть разумная скорость запроса, вы можете реализовать ее еще проще:

1) update the value in memcache
2) if the returned updated value is evenly divisible by N
2.1) add N to the datastore counter
2.2) decrement memcache by N

Предполагается, что вы можете установить достаточно длинный тайм-аут в вашем memcache, чтобы жить между последовательными событиями, но если события настолько скудны, что ваш memcache истечет, скорее всего, вам не нужен счетчик "high concurrency": )

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

Однако при использовании memcache будьте осторожны, что некоторые клиентские API будут считать, что один тайм-аут означает, что это значение отсутствует. Если пакет TCP SYN в экземпляр memcache удаляется, это означает, что ваш запрос ошибочно предполагает, что данных нет. (Аналогичные проблемы могут возникнуть с UDP для memcache)

Ответ 2

Memcache очищается, вы теряете счетчик. УЧ. Использование базы данных mysql или решения NOSQL разрешит эту проблему с возможным поражением производительности. (Redis, Tokyotyrant, MongoDB и т.д.) Может не иметь такой производительности.

Имейте в виду, что вы можете сделать 2 действия:

  • Храните счетчик memcache только по причинам высокой производительности.
  • сохранить журнал, а затем получить более точные показатели.