Реализация счетчика GAE / Java с использованием параллелизма, потоков, статических переменных - PullRequest
3 голосов
/ 02 марта 2012

Я прочитал много статей о счетчиках GAE и это надоедливое ограничение на запись в GAE.Я видел решения с использованием шардинга, задач cron, memcache и т. Д. Затем я достаточно изучил java-потоки, чтобы задать вопрос:

Q: Можем ли мы реализовать счетчик в потоках сервлета, используястатические переменные параллелизма / сервлета?

Это даст дополнительное преимущество, заключающееся в меньшем количестве записей в хранилище данных и memcache (стоит столько же), и устранит требование cron в качестве последнего сервлета в серии fastсчетчик попаданий обновит хранилище данных.

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

// Servlet gets a hit
// static var counter++
// Checks last datastore save time of the static var, if longer than 200ms
// save to datastore & save "last update time"
// If shorter than 200 ms ago, let the next servlet call update the datastore

Можно ли это сделать?Есть предложения?Большое спасибо за ваши мысли.

Ответы [ 3 ]

5 голосов
/ 02 марта 2012

Просто уточню мой комментарий:

Как вы, наверное, знаете, App Engine раскручивает новый экземпляр вашего приложения всякий раз, когда он достигает некоторого порога трафика. Учитывая, что новые экземпляры могут запускаться на совершенно другом сервере, ваш статический счетчик будет считаться недействительным.

Теперь, чтобы уточнить, правильный способ реализации счетчика в App Engine будет состоять в том, чтобы использовать Sharding и разбивать его по нескольким объектам.

Теперь, предполагая, что вы хотите минимизировать ваши вызовы хранилища данных, вы можете вместо этого использовать memcache для хранения данных вашего счетчика и записи их в хранилище данных с определенной частотой (скажем, через cron). Ваши данные memcache будут согласованы для всех экземпляров вашего приложения.

Вы, конечно, рискуете потерять вашего счетчика memcache в случае, если memcache выходит из строя, но об этом заботится запись его в хранилище данных. Опять же, это не 100% надежное решение. но это один из способов минимизации вызовов в хранилище данных.

0 голосов
/ 04 марта 2012

Если вы считаете что-то «критически важным», не думайте, что этот же экземпляр будет обрабатывать следующий запрос или любой последующий запрос.С другой стороны, App Engine, способный быстро масштабироваться для обработки всплесков спроса, состоит в том, что экземпляры исчезают при прохождении всплеска.Экземпляры могут исчезнуть и по другим причинам.Заштрихованные счетчики - это тот способ, который необходим для правильного подсчета.

Также обычно ошибочно полагаться на memcache как на любой другой объект, кроме кэша, который может иметь произвольно сокращенное время жизни.Если приблизительный подсчет подойдет, то у вас есть несколько вариантов.Вы можете сделать что-то вроде накопления счетчиков в memcache, сметая счет в хранилище данных при каждом N-м попадании, или вы можете сделать то же самое, используя глобалы, защищенные блокировкой.

0 голосов
/ 02 марта 2012

Гвидо ван Россум рассказывает об этом в статье в своем блоге. Как я понимаю, у вас проблемы с расой. Я ничего не знаю о Java. Но guido ссылается на API сервиса Memcache для Java в appengine. Может быть, это поможет вам найти решение.

...