Diary Spirit @дневники: изнутри

четверг, 27 октября 2005

Администратор

14:50 И еще немного о ленте избранного
Кому интересно - формирование ленты происходит примерно так.



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

Затем у обнаруженных избранных выбираются записи, сделанные после даты Х. При этом проверяется еще и право доступа к кажой конкретной записи.

Наконец все это разбивается на страницы (учитывая выбранное число вывода для конкретного юзера).



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



Если у кого-то есть внятные мысли по поводу оптимизации запросов - будем рады выслушать.
URL
За разговорами о великой, чистой и светлой любви часто ск...
Японцы, как и положено на ЧМ, бегали и боролись все 90 ми...
Жизнь весьма непредсказуемая штука.... Вышел в середине...
блииин, ну я совсем этого не понимаю! что это за люди????...
Хорошо быть не фанатом. Больные это люди. Самое страшное ...
Пришла на сессию в университет, а оказывается мы там нико...

29.10.2005 в 13:10

29.10.2005 в 13:10
Памяти у нас уже 8 Гб, и мы думаем нарастить.

Я помню не только СМ-4 и 1420, но и ЭВМ ЕС-1020, блин.

URL

29.10.2005 в 13:12

29.10.2005 в 13:12
нос : в общем, хотел бы я посмотреть на нагрузки, настройки и структуры...



ЕС не считается, там UNIX'а не было
URL

29.10.2005 в 16:18

29.10.2005 в 16:18
tarkhil никто ничего не даст смотреть. Спасибо за отзывы.

Не пора ли закрывать тему, а?
URL

29.10.2005 в 16:46

29.10.2005 в 16:46
ну и зря что не дадут

зачем просить высказать мысли по оптимизации запросов, если никто не знает ни структуры базы данных, ни самих этих запросов?
URL

29.10.2005 в 17:09

29.10.2005 в 17:09
.silent вот и я о том же.
URL

29.10.2005 в 17:34

29.10.2005 в 17:34
Dr0n : тогда зачем спрашивать про мысли об оптимизации запросов?
URL

29.10.2005 в 17:38

29.10.2005 в 17:38
tarkhil лично я - ничего не спрашивал.
URL

29.10.2005 в 17:51

29.10.2005 в 17:51
> Если у кого-то есть внятные мысли по поводу оптимизации запросов - будем рады выслушать.
URL

29.10.2005 в 17:56

29.10.2005 в 17:56
а есть вот такая идея (на мой взгляд суперская) - сделать ленту избранного в rss-feed, записей на 20 и все!



грамотно ее сделать и разгрузка будет неплохая, так как любой нормальный человек знает что такое rss и вовсю этим пользуется...
URL

29.10.2005 в 18:29

29.10.2005 в 18:29
!!!



Я достаточно долго занимался оптимизацией хранения информации, да и вопросами паралеллизации тоже занимался, потому я бы всё-таки сказал, что проблема не в поиске, а в забивании коннекшинов к SQL серверам данными. Фактически, после каждой выборки SQL сервер отдайт ВЕСЬ ответ клиенту коннекшина, и пока он не передал этот ответ, этот коннекшин так и висит в памяти и мешает подключится другим SQL клиентам. Простой и верный метод оптимизации этой херни - разделить индексы и тело постов. Например следующим способом: при написании поста (например коммента) в БД кидается некий UID этого текста, права на него, принадлежность к группам (оптималь это сделать не флагами, а разнести по разным колонкам, как булевские переменные), а сам текст скидывается, как файл в некую директорию, причём имя этого файла как раз этот UID из БД и есть. Применительно к дневникам для более быстрого поиска текстового фрагмента это может выглядеть, как /ID_участника/часовой_timestamp/UID_записи где часовой timestamp - это UNIX time по модулю 3600, например. Соответственно, синхронизировать текстовую часть базы данных становится невпример легче (наиболее верно её хранить прямо на отдающих web серверах - процессорах), включать её можно простым инклудом и SQL серваки не будут мучится, отдавая полные тексты. Такой подход гарантирует примерно 60-80% прирост производительности. А если добавить динамическую синхронизацию данных, то и все 120, ведь обращение к файловой системе заведомо быстрее, чем работа через сокеты. (Под динамической синхронизацией я имею ввиду схему, при которой тексты хранятся на отдельном, выделеном серваке и одновременно кэшируются на отдающих web серверах - если какого-то текста нет в кэше, то идет запрос на отдачу текста с выделеного сервака, после чего этот текст кэшируется на отдающем сервере и больше он между серверами не не пересылается. А система таймстампов позволяет в этом случае эффективно очищать роботом устарелый кэш.).



Есть и другой подход - тоже индексы разделяются с текстами, но тексты хранятся на специальном SQL сервере, который заточен только под отдачу данных. В этом случае индекс берётся из одного коннекшина, а данные отдаются с другого сервера. Структуировать БД при этом стоит примерно так же, как и в предидущем примере с файловой системой - с обязательным заведением timestamp - таблиц. Такой подход более масштабиремый на увеличение машин (легче синхронизировать тела постов), но и даёт меньший прирост производительности.



Последнее, про оптимизацию - при редактировании любого поста не нужно изменять сам пост, гораздо быстрее создать новую запись и объявить её актуальной (поставить булевский флаг, например), а уж потом время от времени собирать роботом неактуальные записи и удалять их.
URL

29.10.2005 в 18:35

29.10.2005 в 18:35
Да, и ещё - храните комменты и сами посты в разных таблицах и пореже используте JOIN'ы из нескольких таблиц - это куда ускорит поиск по БД.



А так же попробуйте кэшировать новые записи в HEAP таблицах - при записи в таблицу она локируется (или тормозится) на некоторое время на чтение. Тобишь чем больше запросов на запись, тем больше будет тормозить чтение таблицы. Потому при большом вале запросов на запись стоит их отправлять в какую-нить промежуточную таблицу, заточенную только на приём новых сообщений, а потом уже валом брать оттуда весь дамп новых записей и пакетно их отправлять на store в основную БД (делать это омжно роботом с периодичностью, допустим, полсекунды).
URL

29.10.2005 в 19:23

29.10.2005 в 19:23
ymik, вообще-то, коннекшн он один и закрывать его не надо :)

новый запрос просто ловит этот открытый коннекшн и пользует.



а так, я не думаю что дайрики пишут идиоты, чувак ;)
URL

29.10.2005 в 20:36

29.10.2005 в 20:36
.silent

Вообще-то под коннекшином понимается не только открытый сокет до сервака, но и очередь запросов. Кстати, если бы там был только один открытый коннекшин - всё быстро бы очень нагнулось. Поскольку один коннекшин - это одна позиция в очереди и работать что-то может только если этот коннекшин является командным для запуска тучи хранимых процедур в новых нитках. А то пока по этому коннекшину сервак не отдаст ok report всё встаёт.
URL

29.10.2005 в 22:04

29.10.2005 в 22:04
ymik, сомневаюсь я что-то в том, что на дайриках используются хранимые процедуры. они появились лишь в новом MySQL не так давно.

а открывать новый connection или использовать старый - решит mySQL и php сами.



а так коннекшны вручную лучше не закрывать вручную. если не будут по ним работать - они автоматически закроются.



а если открывать каждым пользователем новый коннекшн - сервер быстро свалится к чертям.
URL

29.10.2005 в 22:43

29.10.2005 в 22:43
.silent

Мне интиресно, а с чего вы вдруг решили, что дневники на 100% написаны на PHP? Критические части запросто могут быть скомпилированы в отдельные модули - это раз, два - внутри PHP передать один конекшин из одной нитки (а каждая страница отрывается именно в своей нитке) в другую невозможно, поэтому на каждый mysql_connect PHP будет новый коннекшин. Естественно, что если этих коннекшинов будет море сервер буден висеть, но тут применяется обратное кэширование результатов, что прекрасно видно по тем технологиям, что тут используется, таким образом кол-во открываемых коннекшинов становится критичным только на таких страницах, как дискуссии и избранное да правка с добавлением постов. Что и прекрасно видно по работе дайриков.



Мне кажется, что вы недостаточно разбираетесь в работе связки PHP+Apache2+MySQL на уровне открытия сокетов, хранения данных, работы с памятью, иначе бы вы не утвеждали, что " вообще-то, коннекшн он один и закрывать его не надо новый запрос просто ловит этот открытый коннекшн и пользует", а так же "открывать новый connection или использовать старый - решит mySQL и php сами". Поверьте мне, я знаю о чём говорю: к моим базам данных сыпятся порядка 2000 запросов в секунду и как минимум 20% из них - на добавление данных, а ещё 30% включают в себя выборки по регулярным выражениям.
URL

29.10.2005 в 22:54

29.10.2005 в 22:54
да, кстати, кэширование!



какой смысл генерировать _всю_ ленту, если она не менялась или менялась несущественно?
URL

29.10.2005 в 23:31

29.10.2005 в 23:31
Причем проверка шарашит по всей базе пользователей.

Хм... кстати, интиресно, а зачем шарашить по всей БД, когда можно писать список избранных прямо в проперти пользователя в БД. К примеру, если это всё на PHP, можно завечти отдельное поле в таблице юзера object и сторить туда PHPшный объект пользователя, содержащий всю информацию о выбранных дневниках. И потом выбирать комменты уже по этим пользователям.



Ещё интиресно, как у вас хранится информация о пользователях и их комментарии? поиск по БД можно существенно ускорить, если

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

б) заводить для каждого поста отдельную таблицу комментариев, куда будут сыпатся все комменты на данный пост (разделить пост и комменты)

г) заводить новые таблицы для постов в дневник, давая им имена на основе timestamp по модулю 86400 (тобишь на каждые новые сутки - новая таблица). Тогда записи будут структуированы и по времени.



Подобная организация БД явно сократит время на шарашанье и поиск, поскольку в запросе всегда можно чётко указать в каких таблицах и что искать.
URL

29.10.2005 в 23:53

29.10.2005 в 23:53
ymik

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

б) заводить для каждого поста отдельную таблицу комментариев, куда будут сыпатся все комменты на данный пост (разделить пост и комменты)


я на тебя конкретно ахреневаю, чувак. ты видел сколько дневников здесь, сколько постов и комментариев? если ты хочешь для каждого из них создавать отдельные таблицы - то я не знаю что еще сказать 8)



а насчет того, разбираюсь ли я в программировании - я программист :)

чего не скажешь о некоторых... о тебе, к примеру...



тебе надо приписать букву Н после буквы M в нике.
URL

30.10.2005 в 00:07

30.10.2005 в 00:07
ymik

> б) заводить для каждого поста отдельную таблицу комментариев, куда будут сыпатся все комменты на данный пост (разделить пост и комменты)



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

Кроме того, насколько мне не изменяет память, комментарии и так хранятся в отдельной таблице. Но не поручусь.
URL

30.10.2005 в 00:18

30.10.2005 в 00:18
.silent я - действующий java программист с шестилетним опытом работы. С вэбом я работаю с 2001 года. Есть несколько статей на javable.com про TCP/IP и работу протоколов повер него, в частности HTTP. Участвовал в JBoss ru.community, если это, конечно, вам о чём-то говорит... По поводу оптимизации - сейчас у меня в сети работают 12 чатов. Два года назад на этой платформе работало 50 чатов. И всё это - вначале на одном, а потом - на двух MySQL серваках. Что такое оптимизация запросов - я знаю прекрасно.



Neiru черезмерное размножение таблиц не так страшно, сколько страшна выборка по всему, что нужно и по тому, что не нужно тоже. Если имеется возможность сократить выборку путём подставления имён нужных таблиц - тем лучше.
URL

30.10.2005 в 00:25

30.10.2005 в 00:25
ymik, твой сайт говорит прекрасно о твоем знании html, php и mySQL, чувак :)))))))))

и кошка у тебя на аватаре облезлая =P
URL

30.10.2005 в 00:33

30.10.2005 в 00:33
Все, приехали. Пошла метрология пиписек. Нафига, спрашивается, просили помочь?
URL

30.10.2005 в 00:38

30.10.2005 в 00:38
ymik а вот тут момент спорный. С учётом того, что каждая таблица — это три файла на диске, очень спорный.



Вы бы сами пошли на такой шаг на своём сервере? С таким подходом у вас каждый день будет появляться примерно 17000 * 3 = 51000 новых файлов на диске, большинство из которых будет даром занимать килобайт-другой.

Да и 17000 новых таблиц одинаковой структуры в базе каждый день — это тоже более чем сомнительный момент.



Прим.: 17000 - округлённое число комментариев за прошедшие сутки.
URL

30.10.2005 в 00:38

30.10.2005 в 00:38
.silent угу. переходим на личности?..



tarkhil нафига просили я уж и не знаю...по крайней мере, надеюсь, что тред не свалится в выяснение у кого чего в куда. По крайней мере я таких бесед не поддерживаю.
URL

30.10.2005 в 00:47

30.10.2005 в 00:47
ymik, не я первый прешел, заметь.

ты лучше почитай комменты других, направленные тебе.



беседу можешь не поддерживать, конечно. твое мнение насчет пары миллионов таблиц принят по назначению :)
URL

30.10.2005 в 00:49

30.10.2005 в 00:49
Классика жанра %)

ymik т.е. на сколько я понимаю, ты хочешь устранить использование кода индексации mysql и использовать вместо него код файловой системы для поиска данных на диске?
URL

30.10.2005 в 00:56

30.10.2005 в 00:56
Neiru вопрос, несомненно, интиресный, пошёл бы я на это. наверное, всё же нет, поскольку таблички хранятся в файлах и куча файлов вполне может быть чревата тем, что такая база не будет оптимизироваться в дальнейшем впринципе. Вероятнее всего я бы всё же сделал бы пункт а и усечённый вариант б (с заведением таблицы комментариев при первом комментарии на пост) либо, как предлагал выше - вынес бы тексты комментариев в другую БД на другой SQL сервер или вообще в файловую систему, а в информации о посте хранил бы только индексы записей. Таким образом я бы получил набор таблиц с информацией ТОЛЬКО о постах и, соответственно, при выборке для фрэнд-ленты в запрос подставлял бы имена только тех таблиц, что лежат у меня в избраном, чтобы не шарить по всей БД.
URL

30.10.2005 в 01:03

30.10.2005 в 01:03
.silent пара миллионов таблиц это не так страшно, как сложная выборка из нескольких миллионов записей с сортировкой по времени.



Dr0n скорее задача отказаться от пересылки больших объёмов данных между серверами, чтобы не забивать канал SQL сервера, а то он вначале тратит время, чтобы отработать "тяжёлый" запрос, а потом ещё тратит время, чтобы переслать результат реквестеру (притом, что кол-во мест в очереди ограничено из-за настроек сервера, а встать в очередь до того, как не отработан предидущий запрос нельзя из-за особеностей протокола).
URL

30.10.2005 в 01:07

30.10.2005 в 01:07
ymik о каких пересылках больших объемов данных между серверами? Какие это данные? Про какой протокол ты говоришь? Вообще, про какой сервер БД?
URL

30.10.2005 в 01:09

30.10.2005 в 01:09
ymik, да что Вы говорите?

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