|
|
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Всем привет. Помогите решить такую задачу. Имеется общий фонд (пул) для накопления джекпота. С каждой ставки в игре этот фонд увеличивается на какую-то сумму (процент от ставки). В табличном виде что-то типа: Код: plaintext 1. Код: plaintext Когда это всё делали, то игроков было немного и борьба за захват записи была небольшой. Но с увеличением кол-ва игроков само-собой началась борьба за этот ресурс. Попробовали добавить дополнительное поле part_id - разбить джекпот на части, но это не дало ощутимой разницы, что очень удивило, так как при, скажем, 50 игроках и без part_id задержек практически нет, а при 800 игроках и 64 part_id задержки появляются, при том, что борьба за общую запись должна была снизиться. Есть определенные требования, которые необходимо соблюсти: 1) Нельзя пропускать ни одной ставки. То есть все финансы должны точно совпадать 2) Сумма обновленного джекпота должна быть возвращена сразу после обновления (это, так скажем, крайне желательное условие) 3) Нельзя аккумулировать джекпот отдельно для каждого пользователя (то есть нельзя добавить user_id в эту таблицу), так как пользователей, учавствующих в розыгрыше джекпота, может быть сотни тысяч, и: а) выборка общей суммы джекпота становится тяжелой. б) джекпот могут часто выигрывать, и необходимо лочить все записи. Есть ли какие-то идеи как лучше (правильнее) организовать накопление джекпота? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 00:16:28 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlan, я не уверен что вы правильно локализовали причину проблемы вам для начала стоит включить полный лог запросов и посмотреть какие именно запросы задумываются. Там например возможен вариант конкуренции да, но вызванной не собственно обновлением строки а долгой транзакцией охватывающей этот update. Т.е. начните с изучения лога... потом локализуйте медленные запросы и смотрите что с ними делать. Помимо блокировок возможны еще варианты 1)общая перегрузка сервера по процессору (особенно легко получить если база живет не на выделенном железе) 2)нехватка дисковой производительности ну и большой список менее вероятных но тоже возможных вариантов. PS: включите log_lock_waits в конфиге, может что то интересное увидите. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 03:11:08 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
ThamerlanВсем привет. Помогите решить такую задачу. Имеется общий фонд (пул) для накопления джекпота. С каждой ставки в игре этот фонд увеличивается на какую-то сумму (процент от ставки). В табличном виде что-то типа: Код: plaintext 1. Код: plaintext Когда это всё делали, то игроков было немного и борьба за захват записи была небольшой. Но с увеличением кол-ва игроков само-собой началась борьба за этот ресурс. Попробовали добавить дополнительное поле part_id - разбить джекпот на части, но это не дало ощутимой разницы, что очень удивило, так как при, скажем, 50 игроках и без part_id задержек практически нет, а при 800 игроках и 64 part_id задержки появляются, при том, что борьба за общую запись должна была снизиться. Есть определенные требования, которые необходимо соблюсти: 1) Нельзя пропускать ни одной ставки. То есть все финансы должны точно совпадать 2) Сумма обновленного джекпота должна быть возвращена сразу после обновления (это, так скажем, крайне желательное условие) 3) Нельзя аккумулировать джекпот отдельно для каждого пользователя (то есть нельзя добавить user_id в эту таблицу), так как пользователей, учавствующих в розыгрыше джекпота, может быть сотни тысяч, и: а) выборка общей суммы джекпота становится тяжелой. б) джекпот могут часто выигрывать, и необходимо лочить все записи. Есть ли какие-то идеи как лучше (правильнее) организовать накопление джекпота? имхо, асинхронно. т.е. отдельный процесс, который постоянно пробегает по новым ставкам и апдейтит джекпот. Он один - никаких ожиданий бокировок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 09:36:02 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Ivan DurakThamerlanВсем привет. Помогите решить такую задачу. Имеется общий фонд (пул) для накопления джекпота. С каждой ставки в игре этот фонд увеличивается на какую-то сумму (процент от ставки). В табличном виде что-то типа: Код: plaintext 1. Код: plaintext Когда это всё делали, то игроков было немного и борьба за захват записи была небольшой. Но с увеличением кол-ва игроков само-собой началась борьба за этот ресурс. Попробовали добавить дополнительное поле part_id - разбить джекпот на части, но это не дало ощутимой разницы, что очень удивило, так как при, скажем, 50 игроках и без part_id задержек практически нет, а при 800 игроках и 64 part_id задержки появляются, при том, что борьба за общую запись должна была снизиться. Есть определенные требования, которые необходимо соблюсти: 1) Нельзя пропускать ни одной ставки. То есть все финансы должны точно совпадать 2) Сумма обновленного джекпота должна быть возвращена сразу после обновления (это, так скажем, крайне желательное условие) 3) Нельзя аккумулировать джекпот отдельно для каждого пользователя (то есть нельзя добавить user_id в эту таблицу), так как пользователей, учавствующих в розыгрыше джекпота, может быть сотни тысяч, и: а) выборка общей суммы джекпота становится тяжелой. б) джекпот могут часто выигрывать, и необходимо лочить все записи. Есть ли какие-то идеи как лучше (правильнее) организовать накопление джекпота? имхо, асинхронно. т.е. отдельный процесс, который постоянно пробегает по новым ставкам и апдейтит джекпот. Он один - никаких ожиданий бокировок.асинхронность не катит -- требуется актуальность в моменте -- сл-но никакой асинхроннности хотя если асинхронность апдейтит и флаг в ставках ("просуммировано") и имеется частичный индекс по необработанным -- может работать и "актуальность" , но как-то через одно место (апдейтить таблицу ставок -- плохое решение). первый ответ миши очень в тему а про разделение и прочие бубны -- я делал так: табличка без уникью по jackpot_id, с суррогатом id, когда обновляем -- пытаемся захватить nowait любую с данным джекпотом, и отапдейтить. а агрегацию можно и джобом. (я захватывал FOR UPDATE тут же в цикле массив id, все их кидал с новой суммой в одну запись, остальные тут же удалял). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 11:49:13 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
ps 1. перепутал макса с мишей, извиняюсь 2. в длине цепи из N конкурентов участвует еще и длина единичной "бесконкурентной" транзакции. если она простая -- пишем только данные и сумму -- то это, скорее всего [там должно быть шаманство с записью не напрямую в таблицы, а послежовательно в "журналки", чтобы не позиционировать головки], время последовательного доступа на запись, и, если в память таблица сумм не ложится [что вряд ли] -- время произвольного [-- что плохо] доступа на чтение. для 1000 доступов к суммам 1000 джекпотов, которые почему-то на разных страницах и может быть нехорошо, но если все суммы в памяти -- время рендом-доступа выпадет и все станет много приличнее. т.е. предлагаю сначала пошерстить длину единичной транзакции. если там много левой логики -- попытаться всю левизну скинуть в асинхрон. ну а параллельное не блокирующее синхронное накопление я описывал выше ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 12:31:01 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Maxim BogukThamerlan, я не уверен что вы правильно локализовали причину проблемы вам для начала стоит включить полный лог запросов и посмотреть какие именно запросы задумываются. Там например возможен вариант конкуренции да, но вызванной не собственно обновлением строки а долгой транзакцией охватывающей этот update. Т.е. начните с изучения лога... потом локализуйте медленные запросы и смотрите что с ними делать. Помимо блокировок возможны еще варианты 1)общая перегрузка сервера по процессору (особенно легко получить если база живет не на выделенном железе) 2)нехватка дисковой производительности ну и большой список менее вероятных но тоже возможных вариантов. PS: включите log_lock_waits в конфиге, может что то интересное увидите. --Maxim Boguk www.postgresql-consulting.ru Максим, я специально не стал указывать про железо, логи и прочее. Просто мне, в идеале, хотелось бы найти альтернативные решения задачи. Но если их нет, тогда конечно последний выход это оптимизация имеющегося решения. Так вот по железу: 1) С дисковой проблем нет (ssd в 5 или 6 раиде) 2) Нехватка CPU имеет место быть. E5-2620 0 @ 2.00GHz с 1 cpu c 12 ядрами, причем на vmware. Но как я уже писал, я ожидал улучшения после разбивки фонда джекпота на части, но его не получил. То есть понятно, что перейдя на машинку с 40 ядрами я улучшу ситуацию, но проблему в принципе не решу. По логам: log_lock_waits на 1сек включал. При "50 игроках и без part_id" ничего не получал. Ну может пару-тройку раз было за 10 минутный stress test. При "800 игроках и 64 part_id" засыпало wait'ами по 4-8 секунд при пополнении фонда, и временами до 30 секунд при выигрыше джекпота. А вот насчёт этого: Maxim BogukТам например возможен вариант конкуренции да, но вызванной не собственно обновлением строки а долгой транзакцией охватывающей этот update. наверное буду думать. Транзакцией управляет приложение на java. Хотя, ява-разрабы говорят, что сразу после вызова хранимки на увеличение джекпота делают коммит. Но наверное стоит попробовать самому вызывать через dblink функцию пополнения с моментальным коммитом. Ivan Durakпропущено... имхо, асинхронно. т.е. отдельный процесс, который постоянно пробегает по новым ставкам и апдейтит джекпот. Он один - никаких ожиданий бокировок. Да, фоновая обработка с предварительным аггрегированием это логичное и красивое решение, но в данном случае реальное состояние джекпота должно быть доступно моментально. И выигрыш (если он был) тоже должен произойти сразу после выигрышной ставки (до следующей ставки). думаеццаps 2. в длине цепи из N конкурентов участвует еще и длина единичной "бесконкурентной" транзакции. если она простая -- пишем только данные и сумму -- то это, скорее всего [там должно быть шаманство с записью не напрямую в таблицы, а послежовательно в "журналки", чтобы не позиционировать головки], время последовательного доступа на запись, и, если в память таблица сумм не ложится [что вряд ли] -- время произвольного [-- что плохо] доступа на чтение. для 1000 доступов к суммам 1000 джекпотов, которые почему-то на разных страницах и может быть нехорошо, но если все суммы в памяти -- время рендом-доступа выпадет и все станет много приличнее. т.е. предлагаю сначала пошерстить длину единичной транзакции. если там много левой логики -- попытаться всю левизну скинуть в асинхрон. ну а параллельное не блокирующее синхронное накопление я описывал выше ... много левой логики. Да с этим буду разбираться. Как уже написал выше, попробую внешний вызов через SQL/MED, чтобы понять, что лишняя логика АПП не является тут причиной. И всё же, если есть какие-то другие архитектурные решения для данной задачи, буду рад услышать. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 12:40:32 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
на тебе еще одну идею - вместо UPDATE table SET amount=amount+<%_от_ставки> WHERE jackpot_id = <тут_id>; 1. добавь id как PK в таблицу джекпотов (еще лучше разбить на таблицы для каждого джекпота, но можно и не разбивать, тогда правда всесто подзапроса будет другой - с limit 1) 2. делай Insert into table (id, jackpot_id, amount) select sequence.nextval, <тут_id>, <%_от_ставки> + (select amount from table where jackpot_id = <тут_id> and id = sequence.curval) 3. асинхронно чистим неакуальную историю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 13:19:09 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlan, авторПри "800 игроках и 64 part_id" засыпало wait'ами по 4-8 секунд при пополнении фонда, и временами до 30 секунд при выигрыше джекпота. из этого скорее всего следует что где то образуются 30 секундные транзакции... вообще совет для тестирования 1)dealock_timeout=100ms + log_lock_waits + 2)log_min_duration_statement=0 + log_line_prefix=%m %p %u@%d from %h [vxid:%v txid:%x] [%i] далее стресс тест и анализ каждого лока который вылез в логе... на предмет чего ждали... и чем была в это время занята транзакция которую ждали (скорее всего вас ждет много открытий на предмет того как у вас транзакциии устроены и используются). а дальше думать и дорабатывать приложение. PS: обязательно разнести для тестирования базу и приложение на разное железо... так как если приложение сьедает все CPU то базе будет очень грустно жить. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 13:32:57 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlan... Есть ли какие-то идеи как лучше (правильнее) организовать накопление джекпота? Есть простое решение, джепот в память, в базу штамп последнего розыгрыша, в случае падения сервера джекпот пересчитывать при старте с момента после штампа розыгрыша. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 15:15:10 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Ivan Durakна тебе еще одну идею - вместо UPDATE table SET amount=amount+<%_от_ставки> WHERE jackpot_id = <тут_id>; 2. делай Insert into table (id, jackpot_id, amount) select sequence.nextval, <тут_id>, <%_от_ставки> + (select amount from table where jackpot_id = <тут_id> and id = sequence.curval) Интересная версия хранить актуальную сумму в последней записи, только я не уверен, что sequence.curval всегда даст последнее правильное значение фонда при большой параллельной нагрузке. Тогда лучше, наверное , advisory lock использовать для организации последовательного доступа к последней записи. И фрагментация таблицы из-за удалений неактуальных значений будет огого. Но я возьму эту идею на подумать. Спасибо. Maxim BogukThamerlan, вообще совет для тестирования 1)dealock_timeout=100ms + log_lock_waits + 2)log_min_duration_statement=0 + log_line_prefix=%m %p %u@%d from %h [vxid:%v txid:%x] [%i] далее стресс тест и анализ каждого лока который вылез в логе... на предмет чего ждали... и чем была в это время занята транзакция которую ждали (скорее всего вас ждет много открытий на предмет того как у вас транзакциии устроены и используются). а дальше думать и дорабатывать приложение. --Maxim Boguk www.postgresql-consulting.ru В данном случае я и так знаю, что lock'и идут из-за борьбы за этот update. Уменьшив "dealock_timeout=100ms + log_lock_waits" я узнаю ещё много нового, но хотелось бы сначала побороть главный bottleneck :) NikolayV81 Есть простое решение, джепот в память, в базу штамп последнего розыгрыша, в случае падения сервера джекпот пересчитывать при старте с момента после штампа розыгрыша. Так как я явно упираюсь в CPU, а не в IO, то джекпот в памяти не даст в данном случае никакого прироста производительности, так как там тоже надо организовывать последовательный доступ к общему ресурсу. Разве что только сам Postgresql медленно ставит/снимает lock'и с ресурса и другое "хранилище" будет просто это делать быстрее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 15:44:13 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlan, >>>В данном случае я и так знаю, что lock'и идут из-за борьбы за этот update. Одну строку при разумных настройках базы и железа можно обновлять достаточно легко до 20.000 раз в секунду. У вас больше 1000 обновлений в секунду получается? Если у вас кросс-локи идут при 100 обновлениях в секунду - как я уже говорил смотрите на transaction flow при обновлениях таблицы и разбирайтесь почему не коммитится оперативно транзакция или почему она неразумно много занимает времени. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 15:54:38 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Maxim BogukThamerlan, >>>В данном случае я и так знаю, что lock'и идут из-за борьбы за этот update. Одну строку при разумных настройках базы и железа можно обновлять достаточно легко до 20.000 раз в секунду. У вас больше 1000 обновлений в секунду получается? Если у вас кросс-локи идут при 100 обновлениях в секунду - как я уже говорил смотрите на transaction flow при обновлениях таблицы и разбирайтесь почему не коммитится оперативно транзакция или почему она неразумно много занимает времени. математика тут предельно простая... если между UPDATE table SET amount=amount+<%_от_ставки> WHERE jackpot_id = <тут_id>; и COMMIT; происходит совершенно вроде бы незначительное время типа 10ms - больше 100 update/s таких вы не получите (ни в 1 поток ни в 100). Поэтому без анализа transaction flow c миллисекундным разрешением - вы причину проблем не найдете. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 15:58:44 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Ну и кстати еще один вариант/совет... если у вас база работает с synchronous_commit=on попробуйте его выключить для теста и погонять ваш стресс-тест еще раз. Так как если у вас на сервере обычные механические диски без рейд контроллера (или даже с рейд контроллером но он кривой или криво настроен или криво настроена используемая файловая система) то больше 100-200 commit/s вы не получите что не делайте... и в общем как раз тут могут быть причины ваших тормозов. Это легко видно в полном логе запросов если смотреть на то сколько времени занимает COMMIT. Eсли у вас там миллисекунды (и местами десятки миллисекунд и больше) - это обьясняет все ваши проблемы даже без привлечения теории о проблемах в приложении. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 16:03:13 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Maxim BogukThamerlan, >>>В данном случае я и так знаю, что lock'и идут из-за борьбы за этот update. Одну строку при разумных настройках базы и железа можно обновлять достаточно легко до 20.000 раз в секунду. У вас больше 1000 обновлений в секунду получается? Если у вас кросс-локи идут при 100 обновлениях в секунду - как я уже говорил смотрите на transaction flow при обновлениях таблицы и разбирайтесь почему не коммитится оперативно транзакция или почему она неразумно много занимает времени. --Maxim Boguk www.postgresql-consulting.ru он там не одну строку апдейтит. у него куча левой логики, которая тут же синхронно выполняется. надо разобраться, что обязано быть синхронным, а что можно на джобы перенести. ваня дурак в последнем то же что и я советовал (без уникъю таблица сумм, подбираемая асинхронным джобом, [для скорости еще и без перебора всего, что не залочено -- мне-то лень было джоб запускать, я здесь же синхронно select for update nowait выборку свободного делал, и подбирал свободное в моменте в кучки] зы с ssd какая-то засада при рейдах. у них у каждого есть непрогнозируемое время обслуживания [в среднем все норм, но с некоторой периодичностью выбрасываются рендомные простои], большое. в рейдах это вылезает боком [ждем то того, то этого. в среднем становимся хуже рейда хардов]. статья была на богомерзком хабре. т.ч. большие рейды собирать на ssd -- не совсем верное решение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 16:10:10 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
думаеццазы с ssd какая-то засада при рейдах. у них у каждого есть непрогнозируемое время обслуживания [в среднем все норм, но с некоторой периодичностью выбрасываются рендомные простои], большое. в рейдах это вылезает боком [ждем то того, то этого. в среднем становимся хуже рейда хардов]. статья была на богомерзком хабре. т.ч. большие рейды собирать на ssd -- не совсем верное решение Почитайте про время ответа на запись и чтение на нормальных серверных Intel s3700 там простоев/лагов просто не возникает за то и деньги платятся... а на обычных ssd базы держать не надо. Кстати непредсказуемость времени записи для нормального рейда с кешом и батарейкой совершенно не критична... всеравно вся запись идет в кеш рейда... а дальше уже асинхронно сбрасывается на устройства (предполагая правильную настройку файловой системы, рейда и дисков в нему). --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 16:17:57 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
ThamerlanNikolayV81Есть простое решение, джепот в память, в базу штамп последнего розыгрыша, в случае падения сервера джекпот пересчитывать при старте с момента после штампа розыгрыша. Так как я явно упираюсь в CPU, а не в IO, то джекпот в памяти не даст в данном случае никакого прироста производительности, так как там тоже надо организовывать последовательный доступ к общему ресурсу. Разве что только сам Postgresql медленно ставит/снимает lock'и с ресурса и другое "хранилище" будет просто это делать быстрее. Транзакция и блокировки в БД разработаны, на мой взгляд, для совершенно других нужд, они не могут соревноваться со специализированными решениями. Не знаю как у вас настроен PG, но по умолчанию, насколько я помню, блокировка со строки не будет снята пока не будет получен ответ от подсистемы io о том что у вас данные зафикисированы на носителе ( commit не завершиться ). Приведите то как у вас реализовано в коде и реальную нагрузку ( обновлений в секунду ). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.01.2015, 17:32:13 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
ThamerlanВ данном случае я и так знаю, что lock'и идут из-за борьбы за этот update. Уменьшив "dealock_timeout=100ms + log_lock_waits" я узнаю ещё много нового, но хотелось бы сначала побороть главный bottleneck :) Главный ботлнек имхо в самом использовании апдейта для накопления при интенсивной вставке. Верное решение уже предлагали выше: * инсерт вместо апдейта * возвращать на выходе из транзакции sum(amount) по накопленному хвосту * подбирать хвост джобом через select ... for update -> delete -> insert ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.01.2015, 05:09:09 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Попробовал сделать commit сразу после UPDATE (через dblink). Как и ожидалось - драка за ресурс сразу упала до минимума, то есть java в самом деле делала commit с микро задержкой, что всё-таки сильно влияло на освобождение русурса. И всё же, даже в таком случае видны 20-150мс задержки в логе. Поэтому буду таки продавливать "не совсем честное" решение с фоновым пересчётом (набор дельта инсертов + потом один update фонда и delete дельты). Всем спасибо за идеи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 12:12:55 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlanто есть java в самом деле делала commit с микро задержкой, что всё-таки сильно влияло на освобождение русурса. И всё же, даже в таком случае видны 20-150мс задержки в логе.. А какой пул использует ваше java приложение, и сколько коннектов к pg поднимает пул под нагрузкой? Не используете ли временные таблицы on commit delete rows? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 12:26:42 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
tadminА какой пул использует ваше java приложение, и сколько коннектов к pg поднимает пул под нагрузкой? Не используете ли временные таблицы on commit delete rows? Hibernate. при стресс тестах (600 пользователей) в определённые моменты доходит до 400 соединений (разрешено конечно больше), но в основном около 200-300 открытых соединений и большинство, по pg_stat_activity, неактивны в конкретный момент. Временные таблицы не используем. P.s. Не предлагайте перейти на i/my-batis или pgbouncer. В данный момент это нереально. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 13:26:39 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlan Не предлагайте перейти на i/my-batis или pgbouncer. В данный момент это нереально. :) Я бы Вам всё-таки предложил послушать совета Maxim Boguk и попробовать: Maxim BogukНу и кстати еще один вариант/совет... если у вас база работает с synchronous_commit=on попробуйте его выключить для теста и погонять ваш стресс-тест еще раз. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 14:01:25 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
ThamerlantadminА какой пул использует ваше java приложение, и сколько коннектов к pg поднимает пул под нагрузкой? Не используете ли временные таблицы on commit delete rows? Hibernate. при стресс тестах (600 пользователей) в определённые моменты доходит до 400 соединений (разрешено конечно больше), но в основном около 200-300 открытых соединений и большинство, по pg_stat_activity, неактивны в конкретный момент. Временные таблицы не используем. P.s. Не предлагайте перейти на i/my-batis или pgbouncer. В данный момент это нереально. :) Hibernate это не пул коннектов а ORM. Вам именно пул коннектов нужен, если уж не хотите Pgbouncer то родные Java пулеры посмотрите типа c3p0 или аналогов. 200-400 коннектов из которых 99% IDLE - крайте неприятный режим для PostgreSQL. --Maxim Boguk www.postgresql-consulting.ru ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 14:10:44 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
ThamerlanПопробовал сделать commit сразу после UPDATE (через dblink). Как и ожидалось - драка за ресурс сразу упала до минимума, то есть java в самом деле делала commit с микро задержкой, что всё-таки сильно влияло на освобождение русурса. И всё же, даже в таком случае видны 20-150мс задержки в логе. Поэтому буду таки продавливать "не совсем честное" решение с фоновым пересчётом (набор дельта инсертов + потом один update фонда и delete дельты). Всем спасибо за идеи. ССЗБ детектед. по возможности[т.е. всегда] клиент, в т.ч. написанный на языке стиральных машинок (жаба) должен работать с пж в режиме autocommit on (а не эмулировать давно деприкейтед autocommit off). т.е. короткими транзакциями, рулимыми целиком и полностью в БД, а не в жаба--слое. тот аффтар <уеб>--поделия, который не может обеспечить это простое правило -- ССЗБ если нужно вернуть сразу много курсоров -- вместо них джейсона и xml вона прикрутили --- пользуйтесь но полюбасу табличка сумм без уникъю по джекпоту, с инсертами и подбором кучек джобом --- вас спасёт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 14:11:18 |
|
||
|
Накопление значения с конкурентным доступом
|
|||
|---|---|---|---|
|
#18+
Thamerlanв определённые моменты доходит до 400 соединений (разрешено конечно больше), но в основном около 200-300 открытых соединений и большинство, по pg_stat_activity, неактивны в конкретный момент. Временные таблицы не используем. P.s. Не предлагайте перейти на i/my-batis или pgbouncer. В данный момент это нереально. :) При каждом коммите происходит обмен сообщениями между процессами (сессиями). Чем их больше, тем это дороже. Стоимость растет нелинейно. Возможно, сейчас эта нелинейность исправлена. На картинке пример того, как изменилась нагрузка нашей системы при переходе от 100 коннектов к pg_bouncer. Это на 16-ти ядрах, что круто для 2009 года. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2015, 14:57:16 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=38850236&tid=1998236]: |
0ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
72ms |
get topic data: |
9ms |
get forum data: |
4ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
| others: | 245ms |
| total: | 411ms |

| 0 / 0 |
