Использование	
  очередей	
  
асинхронных	
  сообщений	
  с	
  
       PostgreSQL
     Илья	
  Космодемьянский
    ik@PostgreSQL-­‐ConsulLng.com
Предпосылки




              2
синхронный	
  подход	
  
                    vs	
  
               асинхронный
• Писатель	
  пишет	
  сообщение	
  и	
  ждет	
  пока	
  
  читатель	
  подвердит	
  прочтение
• Писатель	
  не	
  ждет	
  читателя,	
  прочесть	
  
  сообщение	
  могут	
  когда	
  угодно
Асинхронная	
  очередь
•   Message
•   Channel
•   RouLng
•   Filters
•   Durability




                                    4
Асинхронная	
  очередь
• Удобно
• Быстро
• Позволяет	
  интегрировать	
  разнородные	
  
  системы
• Можно	
  построить	
  SOA
• Серебрянная	
  пуля



                                                  5
Проще:	
  очередь	
  заданий
• В	
  чем	
  проблема:
   – Concurrency	
  
   – Падения




                                      6
Проще:	
  очередь	
  заданий
• В	
  чем	
  проблема:
   – Concurrency	
  
   – Падения
                       Решено	
  в	
  СУБД




                                             7
Проще:	
  очередь	
  заданий
• В	
  чем	
  проблема:
   – Concurrency	
  
   – Падения


• При	
  стандартных	
  уровнях	
  изоляции	
  плохо,	
  
  при	
  жестких	
  -­‐	
  медленно.
• В	
  распределенном	
  случае	
  добавляются	
  
  “византийские”	
  конфликты
                                                            8
“Реляционная	
  модель	
  плохо	
  
         масштабируется”
                      Народная	
  мудрость




                                             9
Что	
  именно	
  имели	
  ввиду?
• Целостность	
  данных	
  внутри	
  БД
• Внутри	
  отдельно	
  взятой	
  базы	
  ACID,	
  что	
  
  делать	
  в	
  случае	
  шардинга,	
  непонятно




                                                             10
Распределенный	
  commit
• Предполагается,	
  что	
  все	
  участники	
  умеют	
  
  локальные	
  транзакции
• Протокол	
  занимается	
  организацией	
  
  распределенного	
  взаимодействия
• Coordinator	
  и	
  slave	
  (slaves)
• 1PC,	
  2PC,	
  PA,	
  PC,	
  3PC	
  (Skeen,	
  Stonebracker,	
  
  Gray,	
  Ozsu,	
  Mohan	
  ...)


                                                                      11
2PC
• Обеспечивает	
  распределенную	
  целостность
• Является	
  индустриальным	
  стандартом




                                              12
2PC




      Figure 8.9 Two-phase commit protocol example.


                                                      [Rahimi, Haug]
331




                                                                       13
2PC
• Работает	
  если	
  все	
  в	
  порядке
• Для	
  аварийных	
  сценариев	
  нужно:
   – 	
  2PC	
  TerminaLon	
  protocol
   – 	
  2PC	
  Recovery	
  protocol
• Падение	
  slave	
  (>=1)	
  -­‐	
  OK,	
  падение	
  
  coordinator	
  и	
  slave	
  -­‐	
  не	
  OK	
  
  [Skeen&Stonebraker]
• Высокий	
  оверхэд	
  на	
  обмен	
  сообщениями

                                                           14
Что	
  такое	
  JMS
• Спецификация	
  высокого	
  уровня
• Реализации	
  (IBM	
  WebSphere	
  MQ,	
  Oracle	
  AQ,	
  
  Tibco	
  EMS,	
  Oracle	
  Open	
  ESB	
  etc.)
• 	
  Чем	
  хорошо?
   – Спецификация	
  разумна
   – Транзакционный	
  EJB




                                                            15
Базы	
  и	
  очереди
• Oracle	
  +	
  Advanced	
  Q
• IBM	
  DB2	
  +	
  IBM	
  WebSphere	
  MQ
• PostgreSQL	
  +	
  PgQ?




                                              16
Для	
  PostgreSQL	
  нужны	
  очереди
• Postgres	
  нужно	
  масштабировать
   – 	
  v.v.	
  <	
  9.2	
  → <	
  24х	
  ядер
   – fsync
   – партиционирование
• Postgres	
  можно	
  масштабировать
   – не	
  нужно	
  платить	
  за	
  лицензию!




                                                  17
PgQ
• Обвязка	
  на	
  Python
• Ticker	
  
• Event	
  log	
  table	
  и	
  снапшоты




                                           18
PgQ
• Обвязка	
  на	
  Python
• Ticker	
  
• Event	
  log	
  table	
  и	
  снапшоты

        Идея:	
  средствами	
  SQL	
  в	
  PostgreSQL	
  очередь	
  сделать	
  нельзя!




                                                                                    19
PgQ
• Обвязка	
  на	
  Python
• Ticker	
  
• Event	
  log	
  table	
  и	
  снапшоты

     Кому	
  администрирование	
  Londiste	
  кажется	
  простым	
  и	
  логичным?;-­‐)




                                                                                 20
mbus
•   h–p://code.google.com/p/mbus/
•   v	
  1.1	
  stable
•   PostgreSQL	
  extension
•   depends	
  on	
  hstore	
  only




                                      21
mbus
=# create extension hstore;
=# create extension mbus;
                         v1.1	
  by	
  default,	
  Postgres	
  9.2

=# create extension mbus version 1.0;

                         specify	
  version	
  for	
  Postgres	
  9.1	
  or	
  9.0




                                                                                     22
mbus
• hstore	
  headers
• hstore	
  payload
• paterns:
   – queue
   – publish/subscribe
   – request/responce
• selectors
• delivery	
  expiraLon/delivery	
  delay

                                            23
mbus
                    queue
mbus.create_queue(qname,	
  ncons)




                                     24
mbus
                    queue
mbus.create_queue(qname,	
  ncons)

                  consumers_cnt
                  Количество	
  частей,	
  от	
  2х	
  до	
  128-­‐256
                  Разумное	
  число	
  -­‐	
  сколько	
  консьюмеров	
  
                  хотите	
  повесить	
  на	
  очередь,	
  слишком	
  много	
  
                  -­‐	
  тяжелее	
  просмотреть	
  всю	
  очередь




                                                                             25
mbus
                                 queue
mbus.post_<qname>(
  data hstore,
  headers hstore DEFAULT NULL::hstore,
  properties hstore DEFAULT
  NULL::hstore,
  delayed_until timestamp DEFAULT NULL,
  expires timestamp DEFAULT NULL)

Возвращает	
  iid	
  сообщения


                                          26
mbus
              queue
mbus.consume(qname)
              Вычитывает	
  сообщение	
  из	
  очереди




                                                         27
mbus
                           queue
mbus.consume(qname)
Resultset	
  вида:
CREATE TABLE qt_model (
	        id integer NOT NULL,
	        added timestamp without time zone NOT NULL,
	        iid text NOT NULL,
	        delayed_until timestamp without time zone NOT NULL,
	        expires timestamp without time zone,
	        received integer[],
	        headers hstore,
	        properties hstore,
	        data hstore
);




                                                               28
mbus
           publish/subscribe
mbus.create_consumer(qname, cname, selector)




                                               29
mbus
           publish/subscribe
mbus.create_consumer(qname, cname, selector)

                       Только	
  durable




                                               30
mbus
           publish/subscribe
mbus.create_consumer(qname, cname, selector)

                    Статический	
  селектор	
  вида:
                    $$(t.properxes-­‐>'STATE')='DONE'$$,	
  




                                                               31
mbus
         publish/subscribe
mbus.consume(qname, cname)
mbus.consume_<qname>_by_<cname>()
mbus.consumen_<qname>_by_<cname>(amt integer)




                                                32
mbus
                             security
• mbus.control
   – superuser	
  =	
  true
   – relocatable	
  =	
  false
   – schema	
  =	
  'mbus'
• mbus.create_view(qname,	
  [cname,	
  vname])	
  
  →	
  grant


                                                      33
mbus	
  roadmap
• 2PC
• JMS-­‐клиент




                                   34
• Gerhard Weikum, Gottfried Vossen - Transactional
  Information Systems: Theory, Algorithms, and the
  Practice of Concurrency Control and Recovery
• Saeed K. Rahimi, Frank S. Haug - Distributed Database
  Management Systems: A Practical Approach
• Gregor Hohpe, Bobby Wolf - Enterprise Integration
  Patterns




                                                      35

Илья Космодемьянский. Использование очередей асинхронных сообщений с PostgreSQL

  • 1.
    Использование  очередей   асинхронных  сообщений  с   PostgreSQL Илья  Космодемьянский ik@PostgreSQL-­‐ConsulLng.com
  • 2.
  • 3.
    синхронный  подход   vs   асинхронный • Писатель  пишет  сообщение  и  ждет  пока   читатель  подвердит  прочтение • Писатель  не  ждет  читателя,  прочесть   сообщение  могут  когда  угодно
  • 4.
    Асинхронная  очередь • Message • Channel • RouLng • Filters • Durability 4
  • 5.
    Асинхронная  очередь • Удобно •Быстро • Позволяет  интегрировать  разнородные   системы • Можно  построить  SOA • Серебрянная  пуля 5
  • 6.
    Проще:  очередь  заданий •В  чем  проблема: – Concurrency   – Падения 6
  • 7.
    Проще:  очередь  заданий •В  чем  проблема: – Concurrency   – Падения Решено  в  СУБД 7
  • 8.
    Проще:  очередь  заданий •В  чем  проблема: – Concurrency   – Падения • При  стандартных  уровнях  изоляции  плохо,   при  жестких  -­‐  медленно. • В  распределенном  случае  добавляются   “византийские”  конфликты 8
  • 9.
    “Реляционная  модель  плохо   масштабируется” Народная  мудрость 9
  • 10.
    Что  именно  имели  ввиду? • Целостность  данных  внутри  БД • Внутри  отдельно  взятой  базы  ACID,  что   делать  в  случае  шардинга,  непонятно 10
  • 11.
    Распределенный  commit • Предполагается,  что  все  участники  умеют   локальные  транзакции • Протокол  занимается  организацией   распределенного  взаимодействия • Coordinator  и  slave  (slaves) • 1PC,  2PC,  PA,  PC,  3PC  (Skeen,  Stonebracker,   Gray,  Ozsu,  Mohan  ...) 11
  • 12.
    2PC • Обеспечивает  распределенную  целостность • Является  индустриальным  стандартом 12
  • 13.
    2PC Figure 8.9 Two-phase commit protocol example. [Rahimi, Haug] 331 13
  • 14.
    2PC • Работает  если  все  в  порядке • Для  аварийных  сценариев  нужно: –  2PC  TerminaLon  protocol –  2PC  Recovery  protocol • Падение  slave  (>=1)  -­‐  OK,  падение   coordinator  и  slave  -­‐  не  OK   [Skeen&Stonebraker] • Высокий  оверхэд  на  обмен  сообщениями 14
  • 15.
    Что  такое  JMS •Спецификация  высокого  уровня • Реализации  (IBM  WebSphere  MQ,  Oracle  AQ,   Tibco  EMS,  Oracle  Open  ESB  etc.) •  Чем  хорошо? – Спецификация  разумна – Транзакционный  EJB 15
  • 16.
    Базы  и  очереди •Oracle  +  Advanced  Q • IBM  DB2  +  IBM  WebSphere  MQ • PostgreSQL  +  PgQ? 16
  • 17.
    Для  PostgreSQL  нужны  очереди • Postgres  нужно  масштабировать –  v.v.  <  9.2  → <  24х  ядер – fsync – партиционирование • Postgres  можно  масштабировать – не  нужно  платить  за  лицензию! 17
  • 18.
    PgQ • Обвязка  на  Python • Ticker   • Event  log  table  и  снапшоты 18
  • 19.
    PgQ • Обвязка  на  Python • Ticker   • Event  log  table  и  снапшоты Идея:  средствами  SQL  в  PostgreSQL  очередь  сделать  нельзя! 19
  • 20.
    PgQ • Обвязка  на  Python • Ticker   • Event  log  table  и  снапшоты Кому  администрирование  Londiste  кажется  простым  и  логичным?;-­‐) 20
  • 21.
    mbus • h–p://code.google.com/p/mbus/ • v  1.1  stable • PostgreSQL  extension • depends  on  hstore  only 21
  • 22.
    mbus =# create extensionhstore; =# create extension mbus; v1.1  by  default,  Postgres  9.2 =# create extension mbus version 1.0; specify  version  for  Postgres  9.1  or  9.0 22
  • 23.
    mbus • hstore  headers •hstore  payload • paterns: – queue – publish/subscribe – request/responce • selectors • delivery  expiraLon/delivery  delay 23
  • 24.
    mbus queue mbus.create_queue(qname,  ncons) 24
  • 25.
    mbus queue mbus.create_queue(qname,  ncons) consumers_cnt Количество  частей,  от  2х  до  128-­‐256 Разумное  число  -­‐  сколько  консьюмеров   хотите  повесить  на  очередь,  слишком  много   -­‐  тяжелее  просмотреть  всю  очередь 25
  • 26.
    mbus queue mbus.post_<qname>( data hstore, headers hstore DEFAULT NULL::hstore, properties hstore DEFAULT NULL::hstore, delayed_until timestamp DEFAULT NULL, expires timestamp DEFAULT NULL) Возвращает  iid  сообщения 26
  • 27.
    mbus queue mbus.consume(qname) Вычитывает  сообщение  из  очереди 27
  • 28.
    mbus queue mbus.consume(qname) Resultset  вида: CREATE TABLE qt_model ( id integer NOT NULL, added timestamp without time zone NOT NULL, iid text NOT NULL, delayed_until timestamp without time zone NOT NULL, expires timestamp without time zone, received integer[], headers hstore, properties hstore, data hstore ); 28
  • 29.
    mbus publish/subscribe mbus.create_consumer(qname, cname, selector) 29
  • 30.
    mbus publish/subscribe mbus.create_consumer(qname, cname, selector) Только  durable 30
  • 31.
    mbus publish/subscribe mbus.create_consumer(qname, cname, selector) Статический  селектор  вида: $$(t.properxes-­‐>'STATE')='DONE'$$,   31
  • 32.
    mbus publish/subscribe mbus.consume(qname, cname) mbus.consume_<qname>_by_<cname>() mbus.consumen_<qname>_by_<cname>(amt integer) 32
  • 33.
    mbus security • mbus.control – superuser  =  true – relocatable  =  false – schema  =  'mbus' • mbus.create_view(qname,  [cname,  vname])   →  grant 33
  • 34.
    mbus  roadmap • 2PC •JMS-­‐клиент 34
  • 35.
    • Gerhard Weikum,Gottfried Vossen - Transactional Information Systems: Theory, Algorithms, and the Practice of Concurrency Control and Recovery • Saeed K. Rahimi, Frank S. Haug - Distributed Database Management Systems: A Practical Approach • Gregor Hohpe, Bobby Wolf - Enterprise Integration Patterns 35