Нагруженный сайт: обновление статистики в отдельном потоке?
От: dimgel Россия https://github.com/dimgel
Дата: 01.01.11 00:02
Оценка:
Всем привет и с праздничком.

Допустим есть высоконагруженный форум, на Java (многопоточность) / PostgreSQL (версионник). Допустим в его базе есть такая таблица:

create table message (
   id serial primary key,
   author_id int not null references "user"(id),
   text text not null,
   hits int,    -- статистика "сколько раз прочитано"
   rating int,  -- пусть будет упрощённо, в одно поле
);


Вопрос такой: а не загнётся ли такая схема под нагрузкой? Не лучше ли вынести статистику (hits, rating) в отдельную таблицу и обновлять эту таблицу в отдельном потоке, с некоторой буферизацией (pending writes)?

Мне видятся Scala actors — команды на обновление статистики от потоков, обрабатывающих HTTP-запросы, кидаются в очередь, которую вычитывает поток, обновляющий статистику. У потока есть кеш Map[messageId, (deltaHits, deltaRating)] с ограничением на максимальное количество записей, при достижении которого собственно выполняется batch update. Аргумент такой, что читают/оценивают обычно свежие посты, и количество хитов кеша должно получиться нормальным.

Кроме того, исключаются дедлоки, да и просто локи.

Покритикуйте, пожалуйста. Чего я не учёл?
Re: Нагруженный сайт: обновление статистики в отдельном пото
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.01.11 16:19
Оценка: 4 (1)
Здравствуйте, dimgel, Вы писали:

D>Всем привет и с праздничком.


D>Допустим есть высоконагруженный форум, на Java (многопоточность) / PostgreSQL (версионник). Допустим в его базе есть такая таблица:


D>
D>create table message (
D>   id serial primary key,
D>   author_id int not null references "user"(id),
D>   text text not null,
D>   hits int,    -- статистика "сколько раз прочитано"
D>   rating int,  -- пусть будет упрощённо, в одно поле
D>);
D>


D>Вопрос такой: а не загнётся ли такая схема под нагрузкой? Не лучше ли вынести статистику (hits, rating) в отдельную таблицу и обновлять эту таблицу в отдельном потоке, с некоторой буферизацией (pending writes)?


D>Мне видятся Scala actors — команды на обновление статистики от потоков, обрабатывающих HTTP-запросы, кидаются в очередь, которую вычитывает поток, обновляющий статистику. У потока есть кеш Map[messageId, (deltaHits, deltaRating)] с ограничением на максимальное количество записей, при достижении которого собственно выполняется batch update. Аргумент такой, что читают/оценивают обычно свежие посты, и количество хитов кеша должно получиться нормальным.


D>Кроме того, исключаются дедлоки, да и просто локи.


D>Покритикуйте, пожалуйста. Чего я не учёл?


Того что сегодня вам нужна статистика по просмотрам, а завтра по юзерам.

Общий подход такой: сначала пишется raw лог — одна строка на показ (запрос), а потом с интервалами срабатывает код, который аггрегирует в полезную информацию.

Для того чтобы показывать live статистику можно делать materialized\indexed представления на этой таблице, всяко эффективнее рукопашного вычисления получается.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.