Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

53. PostgreSQL и задача параллельной многопроцессной обработки очереди (Дмитрий Котеров)
Author Message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Dec 14, 2008 4:06 pm (написано за 9 секунд)
   Post subject: 53. PostgreSQL и задача параллельной многопроцессной обработки очереди
Reply with quote

dklab.ru/chicken/nablas/53.html
Back to top
View user's profile Send private message Send e-mail
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 184
   поощрить/наказать

Location: Москва

PostPosted: Thu Dec 18, 2008 9:08 am (спустя 3 дня 17 часов 1 минуту; написано за 38 секунд)
   Post subject:
Reply with quote

В MySQL такая возможность появится лет через 5... :)
Back to top
View user's profile Send private message Send e-mail
TLoD,Snake
Guest





Карма: 388
   поощрить/наказать


PostPosted: Tue Jan 27, 2009 8:16 pm (спустя 1 месяц 9 дней 11 часов 8 минут; написано за 1 минуту 36 секунд)
   Post subject:
Reply with quote

Проблема в том, что нельзя закрывать соединение. 50 соединений уже много, 100 - очень много.
Тут имхо надо говорить либо о менеджере очереди в отдельном потоке многопоточного приложения или о менелдере, работающем через сокеты в многопроцессном.
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Sun Feb 01, 2009 12:30 am (спустя 4 дня 4 часа 13 минут; написано за 6 минут 27 секунд)
   Post subject:
Reply with quote

Думаю, что распараллеливать на 100 потоков - это чересчур много. Даже если у вас 8-процессорные машины, то получится, что на 1 машину с базой приходится 12 машин-обработчиков - явно многовато для одной базы, нужно уже применять шардинг (партицировать по нескольким физическим базам). Технику, описанную в статье, хорошо применять при распараллеливании на 10-20 потоков, иначе она уже становится не такой эффективной. Есть, например, developer.skype.com/SkypeGarage/DbProjects/SkyTools/PgQdocs - его гораздо дольше поднимать, и он вообще сложный, но для очень тяжелых случаев наверняка окажется производительнее (правда, он вроде извлекает элемент из очереди, так что в случае обвала скрипта-обработчика он окажется потерянным, если я не ошибаюсь, а с блокировками этой проблемы нет).

Главное - не стрелять из пушки по воробьям и не экономить на спичках. :-)
Back to top
View user's profile Send private message Send e-mail
PavelZ
Заглянувший



Joined: 13 Mar 2009
Posts: 1
Карма: 0
   поощрить/наказать

Location: Хабаровск

PostPosted: Fri Mar 13, 2009 4:01 am (спустя 1 месяц 12 дней 3 часа 30 минут; написано за 6 минут 50 секунд)
   Post subject:
Reply with quote

Очень интересная для меня тема, так как делаю проект виртуального мира и многопользовательской игры на его основе.
Основой проекта стала СУБД PostgreSQL где в нескольких базах будут храниться все мало изменяемые и динамические данные об объектах виртуального мира. Обработчики событий (программные модули) будут обрабатывать множество данных одновременно, поэтому хотя группы объектов будут выделяться в отдельные базы, приходится думать как оптимизировать и структуру данных, так и алгоритмы работы с ними, чтобы ускорить работу и сократить ошибки.
Back to top
View user's profile Send private message
Denis F. Latypoff
Guest





Карма: 388
   поощрить/наказать


PostPosted: Fri Mar 13, 2009 1:14 pm (спустя 9 часов 13 минут; написано за 1 минуту 29 секунд)
   Post subject:
Reply with quote

Вот это улыбнуло
Quote:
К счастью, решить проблему очень легко: нужно после извлечения пачки элементов из очереди сделать повторную проверку
Может сделать три проверки? или четыре? для пущей уверенности :)

Вот эта штука работает атомарно в любой СУБД:
Code (SQL): скопировать код в буфер обмена
CREATE TABLE `t_tmp` LIKE `t`;
RENAME TABLE `t` TO `t_work_{PID}`, `t_tmp` TO `t`;
/*
 * работаем с t_work_{PID}
 */
DROP TABLE `t_work_{PID}`;
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Fri Mar 13, 2009 6:09 pm (спустя 4 часа 55 минут; написано за 1 минуту 38 секунд)
   Post subject:
Reply with quote

Denis F. Latypoff wrote:
Может сделать три проверки? или четыре? для пущей уверенности :)
В статье объясняется (даже с рисунком), почему одной повторной проверки достаточно. Три или четыре делать излишне.
Denis F. Latypoff wrote:
Вот эта штука работает атомарно в любой СУБД:
Эта штука меняет схему БД, т.е. вызывает запись в pg_catalog, что в реальных системах совершенно неприемлемо.
Например, таблица может реплицироваться.
Кроме того, она вызывает блокировку на запись в таблицу на время своего выполнения.
Back to top
View user's profile Send private message Send e-mail
tmihail
Guest





Карма: 388
   поощрить/наказать


PostPosted: Tue Jul 14, 2009 4:41 pm (спустя 4 месяца 22 часа 31 минуту; написано за 9 минут 41 секунду)
   Post subject:
Reply with quote

Дмитри, спасибо Вам за интересные, познавательные материалы. Статья привлекла пристальное внимание.
Если возможно, поделитесь пожалуйста своим опытом, знаниями и/или соображениями относительно следующих вопросов.
Quote:
Функция pg_try_advisory_lock() пытается "повесить" исключительную блокировку на некоторый "виртуальный" идентификтор, который описывается парой ее параметров. Если этот идентификатор уже заблокирован, она ничего не делает и возвращает false. Если же блокировку удалось установить, то функция возвращает true. Блокировка снимается, когда вызывается pg_advisory_unlock(), либо когда клиент отсоединяется от базы данных.
А если клиент не завершит корректно соединение и вывалится... ("обрыв провода", процесс умер и т.д. и т.п.)

1) Что будет с описанной системой? Не зависнут ли блокировки? Нужно ли со специального клиента-менеджера отслеживать ситуации "зависания"?
2) Как постгресс обработавывает данный вариант? Как он определит, что коннект отвалился и сколько времени на это уйдет? Где и как это конфигурируется?

Спасибо.
Back to top
ln
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Jul 16, 2009 4:09 pm (спустя 1 день 23 часа 27 минут; написано за 2 минуты 7 секунд)
   Post subject:
Reply with quote

SELECT id
  FROM subscription
  WHERE
    last_mail_at < MAILING_STARTED_AT
    AND subscription_type = <тип подписки>
    AND pg_try_advisory_lock(tableoid::INTEGER, id) /* вот она, блокировка! */
  LIMIT 100

если план выполнения запроса по какой-то причине изменится, например на SeqScan или BitmapIndexScan, то может произойти ошибка описанная в главе "13.3.4. Advisory Locks" документации "In the above queries, the second form is dangerous because the LIMIT is not guaranteed to be applied before the locking function is executed. This might cause some locks to be acquired that the application was not expecting, and hence would fail to release (until it ends the session). From the point of view of the application, such locks would be dangling, although still viewable in pg_locks."
Back to top
ln
Guest





Карма: 388
   поощрить/наказать


PostPosted: Thu Jul 16, 2009 4:22 pm (спустя 12 минут; написано за 5 минут 35 секунд)
   Post subject:
Reply with quote

также при "поломке плана" нет гарантии, что условие pg_try_advisory_lock(...) будет проверяться после проверки ограничений по last_mail_at и subscription_type, причём только для записей, удовлетворяющих этим двум ограничениям. то есть предложенный рецепт критично зависит от плана выполнения запроса, на выбор которого мы не можем гарантированно влиять.
Back to top
Тюрин Михаил
Заглянувший



Joined: 16 Jul 2009
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Mon Jul 20, 2009 2:59 pm (спустя 3 дня 22 часа 37 минут; написано за 3 минуты 37 секунд)
   Post subject:
Reply with quote

enable_seqscan перевести в off и enable_bitmapscan тоже в off (там ещё какой-то есть enable_tidscan) - план не поломается с indexascan'а. Причем это можно делать в сесии не ограничивая кластер. Я прав?
Back to top
View user's profile Send private message
Тюрин Михаил
Заглянувший



Joined: 16 Jul 2009
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Wed Jul 22, 2009 10:47 am (спустя 1 день 19 часов 47 минут; написано за 3 минуты 10 секунд)
   Post subject:
Reply with quote

А вот то, что во время выборки перед наложением limit'а можем залочить "лишние" записи - это похоже потенциальный бак... Там правда блокировки по завершении сессии сами сбрасываются, но это надо всё исследовать и обдумать) но проблема похоже есть...
Back to top
View user's profile Send private message
Тюрин Михаил
Заглянувший



Joined: 16 Jul 2009
Posts: 3
Карма: 0
   поощрить/наказать


PostPosted: Wed Aug 05, 2009 3:11 pm (спустя 14 дней 4 часа 23 минуты; написано за 47 секунд)
   Post subject:
Reply with quote

sql.ru/forum/actualthread.aspx?tid=681777
 - поднял еще тут обсуждение
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 413
   поощрить/наказать


PostPosted: Wed Sep 23, 2009 1:19 am (спустя 1 месяц 17 дней 10 часов 8 минут; написано за 1 минуту 52 секунды)
   Post subject:
Reply with quote

tmihail wrote:
Функция pg_try_advisory_lock() пытается "повесить" исключительную блокировку на некоторый "виртуальный" идентификтор, который описывается парой ее параметров. Если этот идентификатор уже заблокирован, она ничего не делает и возвращает false. Если же блокировку удалось установить, то функция возвращает true. Блокировка снимается, когда вызывается pg_advisory_unlock(), либо когда клиент отсоединяется от базы данных.
А если клиент не завершит корректно соединение и вывалится... ("обрыв провода", процесс умер и т.д. и т.п.)
В этом-то вся и соль функции. Если соединение разрывается по любой причине (аварийно ли, специально ли - не важно), то блокировка ОСВОБОЖДАЕТСЯ. Это очень ценное ее качество. То, что процесс отвалился (например, по обрыву провода) - это задача протокола TCP, а не постгреса. Если не ошибаюсь, тайм-аут на это дело - около 30 секунд (но рекомендую погуглить на тему tcp keep_alive).
ln wrote:
то есть предложенный рецепт критично зависит от плана выполнения запроса, на выбор которого мы не можем гарантированно влиять.
Совершенно верно.
Тюрин Михаил wrote:
enable_seqscan перевести в off и enable_bitmapscan тоже в off (там ещё какой-то есть enable_tidscan) - план не поломается с indexascan'а. Причем это можно делать в сесии не ограничивая кластер. Я прав?
Да.
Тюрин Михаил wrote:
А вот то, что во время выборки перед наложением limit'а можем залочить "лишние" записи - это похоже потенциальный бак...
Если план правильный, "наложения limit" никакого не существует. Он просто берет первые limit записей из индекса, ничего не накладывая.
Back to top
View user's profile Send private message Send e-mail
Никита Тихомиров
Guest





Карма: 388
   поощрить/наказать


PostPosted: Tue Nov 10, 2009 8:18 pm (спустя 1 месяц 17 дней 18 часов 58 минут; написано за 3 минуты 20 секунд)
   Post subject:
Reply with quote

Дмитрий, добавьте, пожалуйста в статью информацию о том что индекс обязателен в основном для того чтобы не залочить лишние записи, а не для производительности. А также про enable_seqscan и enable_bitmapscan в off.
Эта информация есть в этой ветке форума если в нее вчитаться, но при начале разработки сложно понять важность этих условий. Это бы спасло мне несколько часов, другим, надеюсь, тоже поможет.
Back to top
Дмитрий М.
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sat Jan 23, 2010 1:30 am (спустя 2 месяца 12 дней 5 часов 12 минут; написано за 1 минуту 38 секунд)
   Post subject:
Reply with quote

Подскажите в почему Postgresql на запрос
Code (SQL): скопировать код в буфер обмена
 
выдает ошибку
Code (SQL): скопировать код в буфер обмена
ERROR:  syntax error at OR near "@""@"

Клиент Pgadmin 1.10.1, Postgresql 8.4
Code (Bash): скопировать код в буфер обмена
Procedural Languages
  Name   | Trusted?
---------+----------
 plpgsql | yes
Back to top
Александр_
Guest





Карма: 388
   поощрить/наказать


PostPosted: Sun Apr 04, 2010 12:30 pm (спустя 2 месяца 12 дней 10 часов 59 минут)
   Post subject:
Reply with quote

Дмитрий, потому что такого синтаксиса в постгресе нет. Читайте внимательно статью:
Quote:
псевдо-операция @IDS := ... означает, что данные нужно сохранить в некоторый массив вызывающего скрипта
Back to top
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
Post a reply
Username
Subject
Господа спамеры и оптимизаторы!

Вы можете даже и не пытаться вставлять в текст поста ссылки - они все равно автоматически удаляются (вернее, тэги <a> заменяются на тэги <u>).

Но если не поверите и все же попытаетесь - как только увидите, что все безрезультатно, удалите свой пост, пожалуйста. Модераторы тоже люди, нехорошо, если они погрязнут в тоннах спама.
     

Disable BBCode in this post
Disable Smilies in this post
    HTML is OFF
BBCode is ON
Smilies are ON
You cannot post new topics in this forum. You can reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML