Обновить
0

Пользователь

7
Подписчики
Отправить сообщение
на max(id), если без лишних оговорок, имеем гонку — могут теряться некоторые документы
по пункту 5 значит мы решили, что всё таки как-то не ровненько, и трекать надо бы, — хорошо.

далее:

6.1) вооот. тут то вы, как раз, через досылку _только_ после удаления, и реализовали, по сути, трекание событий досыльщика, — ОК
6.2) а тут вам надо внимательно почитать про «delivery_mode=2» и «персистентность» раббита (и например еще в связи с этим и про лаг acka по 200ms) — раббит fsync делает отложенно (для буфера из многих мессаджей), то что вы потеряете — вы даже не отследите

и
далее. это всё вам надо же держать еще горячие «реплики» (и базы и очередей), вы же не будете ждать пока железо новое подвезут/введут, так что проблема восстановления после аварий и потерь (fsync а по сети тем более нету, в раббите особенно) приобретает более общие рамки. и да, мы еще не рассматривали падение и восстановлени pg.
> (но обработалось уже на продуктовом консумере)
до аварии
5) вы с этого начали, но проблему в итоге так и не решили
> отдельно хранить какие из событий мы уже обработали

6) а тут я вам показываю, что вам и пачкой могут повторы прилетать:
6.1) либо когда не сработал Message acknowledgment на очереди досыльщика (и он повторно будет досылать)
6.1) либо в случае аварии раббита (kill -9 и подобное, когда он потеряет события, которые были в его очереди), когда поле восстановления всё, что пропало из очереди досыльщика (но обработалось уже на продуктовом консумере) снова дошлется
4) но вопрос мой открыт: приложение не хотели трогать совсем? такую же систему в целом можно было сделать, если просто с клиента писать еще и в раббит после записи в базу.
5) 100 рублей превращаются в 200ти всё равно, значит надо трекать всё равно повторное выполнение. значит дело не в конкретной «очереди» (pgq/rabbit/etc), а вообще так всё всегда везде.
6) вооот. опять получите повторно сообщения, так как те, которые исчезли при падении (из очереди досыльщика) и так и не успели удалится из таблицы, — все придут опять. у вас досыльщик и конечный консумер работаю же абсолютно независмо и асинхронно.

// тут еще момент: проблема с Message acknowledgment отдельно интересна для досыльщика, надо бы посмотреть, заложились ли вы на повторный приход «удаления»

«HornetQ» — уж лучше уж кастылить дальше)

мой вам совет итоговый — делать честного pgq-шнуго консумера с нормальным треканием обработки (там всё уже прилагется).
github.com/markokr/skytools/tree/master/sql/pgq_ext/functions

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

замечания:

1) интересно было вспомнить про XactCallback внутри pg
2) страшно пускать древненький сишный, по цифрам бета, код pg_amqp *0.4.1* в бой, можно покрашить весь кластер начисто
3) вместо pid надо Session Id (комбинация pid и backend_start)
www.postgresql.org/docs/9.0/static/runtime-config-logging.html#GUC-LOG-LINE-PREFIX %c

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

5) проблема «повторного прихода события» не решается и в консумере rabbit а. если он упал в процессе обработки и не отметил событие как выполненное, клиент получит его еще раз (Message acknowledgment www.rabbitmq.com/tutorials/tutorial-two-python.html)

и 100 рублей превратятся в 200ти всё равно, так что трекать всё равно надо, и это не проблема pgq, а! ограничение реального мира

6) ну и большой вопрос, как быть когда раббит развалится (https://aphyr.com/posts/315-call-me-maybe-rabbitmq) и надо будет сводить концы с концами и что-то досылать в него ( тут и опять в том числе повторная доставка )

// примерно подобную штуку проектировал: pgq шный консумер перекладывал в раббит — лаг 1 секунда, но нет синхронных завязок внутри базы и страшного кода. но при этом я воспроинмал раббит уже просто как отрезок сети
peter.eisentraut.org/blog/2015/03/03/the-history-of-replication-in-postgresql/

немного истории для обобщения и введения в дальнейшее рассмотрение
движки… используют общий бинлог.… это важно — читайте, например, в этой статье Олега Царёва, здесь, на Хабре.

можно упомянуть развитие истории «бинлога» базы данных из статьи Олега
peter.eisentraut.org/blog/2015/03/03/the-history-of-replication-in-postgresql/

Tungsten — эт что-то не то.

! londiste (из skytools) — pgfoundry.org/projects/skytools

// еще можно slony и bucardo
pgconf.ru/paper/10 — PCI DSS compliance — оч хороший доклад будет
положительный рейтинг тут — это более подозрительно, чем наоборот. imho
там «зацикливание» сходится по четкой мат модели, для «больших» таблиц — попросту говоря его нет. посмотрите цифры по ссылке в примерах
www.sql.ru/forum/1126127/ocherednoy-velosipedist всем еще раз прочитать до конца!
www.sql.ru/forum/1126127/ocherednoy-velosipedist всем еще раз прочитать до конца!
ндааа, хабр конечно еще то болотце, читать надо сильно условного всё тут

explain analyze
select min(item_id), max(item_id) from items

«Result (cost=0.29..0.29 rows=1 width=0) (actual time=0.045..0.046 rows=1 loops=1)»
" InitPlan 1 (returns $0)"
" -> Limit (cost=0.00..0.15 rows=1 width=8) (actual time=0.020..0.020 rows=1 loops=1)"
" -> Index Only Scan using items_item_ux1_080914 on items (cost=0.00..61820478.54 rows=422748256 width=8) (actual time=0.018..0.018 rows=1 loops=1)"
" Index Cond: (item_id IS NOT NULL)"
" Heap Fetches: 0"
" InitPlan 2 (returns $1)"
" -> Limit (cost=0.00..0.15 rows=1 width=8) (actual time=0.018..0.019 rows=1 loops=1)"
" -> Index Only Scan Backward using items_item_ux1_080914 on items (cost=0.00..61820478.54 rows=422748256 width=8) (actual time=0.016..0.016 rows=1 loops=1)"
" Index Cond: (item_id IS NOT NULL)"
" Heap Fetches: 1"
«Total runtime: 0.071 ms»

71 микросекунда

100 микросекунд — можно 10 000 раз в секунду на одно ядре делать такой min max
wiki.postgresql.org/wiki/PGQ_Tutorial

на пхп потребитель pgq тоже есть

там есть нормальный демон
github.com/dimitri/libphp-pgq
SystemDaemon

Фонтейн, чувак живой, всё норм
www.hagander.net/talks/
Data driven cache invalidation (slightly updated), JDCon-East, New York City, NY, March 2011 and EuroPython 2011, Florence, Italy (+ scripts)

че-то правда у него пдфка не грузится, а
скрипты скачиваются

вот еще видео
ep2013.europython.eu/conference/talks/data-driven-cache-invalidation

суть в PGQ
у меня на PostgreSQL 9.2.6 поведение как и описано в документации. как и должно быть. «рулы» в данном случае делают отличное от read commited поведение

Информация

В рейтинге
Не участвует
Дата рождения
Зарегистрирован
Активность