Сегодня чего-то вспомнил старую фишку - прикол про Вконтакте. Там же типа такая хрень, что на главной странице работает Java Script, который через случайные промежутки времени рандомно увеличивает счёткик зарегистрированных пользователей Контакта, типа там на уже 140 миллионов, вся фигня. Как-то видел у Павла Дурова на странице (ну он кагбэ типа создатель контактов вроде как) такую занимательную заметку:
Цитата
Почитал комментарии к новости о 10 миллионах и нашел забавное мнение, которое повторилось несколько раз. Вкратце оно сводится к следующему:
"вас не 10 миллионов, это вы тут накручиваете количество пользователей, потому что у вас на главной странице стоит простой javasсript".
Кодеры в этом месте уже могли посмеяться и получить удовольствие. Но я пишу эту заметку не для того, чтобы кто-то над кем-то посмеялся. Мне интересно подробнее остановиться на системе подсчета пользователей ВКонтакте - для тех, кто не совсем представляет, как эта система работает, но хотел бы знать.
Javasсript, который выводит динамику роста пользователей на главной странице, делает это на основе статистики скорости роста базы предыдущих дней в соответствии с математической ожидаемостью роста - в зависимости от часа и дня недели. Каждую ночь он синхронизируется с базой данных и корректирует количество зарегистрированных исходя из точных значений базы через SQL-запрос.
В результате этого погрешность в каждую отдельную секунду достигает всего 0.0001%, что очень хорошо для системы такого рода. Хотя, разумеется, наши собственные подсчеты количества пользователей мы предпочитаем делать на основе запросов к базе данных, а не на основе клиентских скриптов.
Реализовать систему, подобную приведенной выше, может не так много народу. И это нормально - не все обязаны быть программистами. Каждый человек, искушенный в высоконагрузочных системах, понимает, что COUNT к большой таблице в реальном времени каждые полсекунды кладет базу. Понятно, что без математического ожидания, которое выводит примерное количество пользователей с погрешностью 1-2 тыс. человек, здесь не обойтись.
В этой связи особенно занятно мнение "у Вас статистика считается простым java-скриптом". Остается только позавидовать уверенности, с которой ребята судят об окружающей их жизни.
Для чего я уделил этому мнению больше внимания, чем обычной чепухе, которую говорят о Контакте. Прежде всего, чтобы лишний раз вспомнить о том, насколько для нас важно выводить данные о количестве пользователей. ВКонтакте - единственный сайт, который выводит точное количество найденных пользователей при расширенном поиске по 10-миллионной базе. То есть только ВКонтакте Вы можете узнать, например, точное количество девушек, рожденных в 1984 году. Любой желающий может заняться даже подведением общеконтактовской статистики.
Ни одна другая социальная сеть такой возможности не даст (на большие запросы в лучшем случае скажет "найдено более 500 человек"), так как это требует действительно нетривиальных технических усилий. У нас широта возможностей доходит до абсурда: можно зайти в расширенный поиск, нажать "Начать поиск" без указания дополнительных условий - и выведется количество всех найденных пользователей.
Кроме того, ВКонтакте - социальная сеть, в которой порядковые номера пользователей выдаются более менее по порядку. Конечно, красивые номера типа 10000000 изымаются сразу, чтобы не искушать любителей регистрировать ботов для оккупирования круглых аккаунтов, но теоретически любой желающий может написать скрипт, который попытается зайти на каждый из порядковых номеров (id1, id2...) и посчитает актуальное количество пользователей.
Ни одна другая крупная социальная сеть не достигает подобной прозрачности в предоставлении статистической информации. Другие сайты могут заявить "нас 700 миллионов" - и никто никогда этого проверить не сможет. Только ВКонтакте предоставляет некие инструменты для сверки официальной статистики и актуальной.
Получается, пока мы единственный сайт, который дает открытую статистику по количеству пользователей, и также единственный, кого кто-то обвинил в ее закрытости.
Парадокс, верно? Но не может ли второе быть следствием первого?
Возвращаясь к мысли годовой давности - возможно, чем больше мы даем, тем больше подозрений вызываем.
Представьте, что на улице кто-то раздает деньги прохожим - Вы решите, что деньги фальшивые, верно?
Но вот что странно - почему-то этой статьи сейчас у Павла Дурова нет! Может он понял, что где-то обложался, и удалил её? Не знаю. Вот задумался на словами
Цитата
Каждый человек, искушенный в высоконагрузочных системах, понимает, что COUNT к большой таблице в реальном времени каждые полсекунды кладет базу. Понятно, что без математического ожидания, которое выводит примерное количество пользователей с погрешностью 1-2 тыс. человек, здесь не обойтись.
Это как? Я, конечно, не сильно крутой специалист, но всё же... Какая же СУБД стоит на обслуживании Контагда, если запрос COUNT там реально выполняется??? Даже сраный Мускул, ИМХО, так не делает, ВСЕГДА и почти В ЛЮБОЙ СУБД запрос COUNT на одиночную таблицу берётся из индекса. Дуров что, сам писал СУБД, и там нет индексов??? Не понимаю.
Ну и допустим, на секунду, что вот нет индексов у него. Ну не и всё. И что же делать? Мне, например, сразу пришло в голову такое решение:
создаём левую табличку UserNum с одним полем UN, в котором одна запись типа long. Первично заполняем её:
Код
insert into UserNum values (select COUNT(*) from ContaktVegetables where NAME<>'DELETED')
Начальное число у нас есть. Уже из этой таблицы можно брать значение количества юзеров. И теперь кто мешает нам написать два простейших триггера:
Код
Create trigger DContaktVegetables on ContaktVegetables
for delete
as
declare @n int
select @n=top 1 UN from UserNum
update UserNum set UN=(@n-(select COUNT(*) from deleted))
Create trigger IContaktVegetables on ContaktVegetables
for insert
as
declare @n int
select @n=top 1 UN from UserNum
update UserNum set UN=(@n+(select COUNT(*) from inserted))
И всё, проблема решена! Простой запрос на выборку к таблице UserNum можно хоть 100 раз в секунду делать, ничего не случится.
И, кстати, тока что понял, что Дуров гонит как Троцкий. Попробуйте сделать поиск по всей базе, типа там
http://vkontakte.ru/gsearch.php?from=people&sort=-1#c[country]=0&c[section]=people&offset=1000
Сразу видно, что ограничение есть. Так что ничем не проверить реальное число найденных записей, все ведь никак не отобразятся.