SlideShare a Scribd company logo
High scale flavor
(recipes for message
      queueing)

             Tomas (t0m) Doran
                London Perl
              Workshop 2010
What is message
       queueing.
• In it’s simplest form, it’s just a list.
• 1 (or more) ‘producers’ (writers)
• 1 (or more) ‘consumers’ (readers)
• Queue if rate of production > rate of
  consumption
Why do I want it?
• Decouples producers and consumers
  (probably across the network).
• Lets you manage load, and spikes in load
  (only n consumers).
• In a web environment - lets you serve
  more pages, quicker.
What is the problem
  with web apps?
• App servers take a lot of RAM
• Context switching expensive
• A lot of apps think like a CGI.
• Making the user wait IS HORRIBLE.
• Anything but very fast pages is fail.
One page request per CPU core
   Even if extra context switching has zero overhead
    you serve people sooner if you queue requests.

       A     B       A   B     A     B       A   B

                 A                       B

  A finishes significantly before B in the lower diagram
            B finishes at the same time in both
N.B. This explicitly assumes you never wait on external IO
                       (e.g. a database)
What are the solutions
• Use a PAL (Page Assembly Layer) - e.g.
  Varnish
• Defer doing work inside the web request
  to a queue
• AJAX (heavy javascript) apps making many
  requests make this even more important.
• If your requests are all small and fast then
  you can win by doing multiple small
  requests rather than one expensive one
Message queueing

• Many many flavors.
 • Going to cover options available right
     now in perl
• First, a little theory
Messaging Topologies
• I.e. how producers and consumers interact
  together through the message broker
• 3 common patterns - considerably more
  complex applications possible.
• Even within these there is additional
  complexity to consider, e.g. message
  durability.
1: Publish-Subscribe
• ‘Topic’ in ActiveMQ
• Anonymous queues in AMQP
• One (or more) publishers
• Zero (or more) consumers
• Every consumer gets every message
• Messages discarded if no consumers
• E.g. log message listener(s)
2: Queue(s)
• One or more producers
• One or more consumers
• Each message delivered to exactly one
  consumer
• Messages ‘queued’ (possibly to disk)
• E.g. Job queue with worker pool allowing
  you to work efficiently through high load
  spikes
3: Request / Response

• Create anonymous queue for replies
• Publish to well known queue(s), include
  return address
• Wait for reply.
• Arrange for messages to be discarded if
  you stop listening for the reply.
STOMP
• Streamed Text Oriented Messageing
  Protocol
• Simple. Interoperable.
• You probably want to use ActiveMQ
• Net::STOMP
• Simple semantics: Queues and Topics
• You can build the 3 simple patterns from
  these
ActiveMQ - Topics
• Publish / subscribe semantics.
• Message goes to all the subscribers
• Zero or more subscribers
• Messages thrown away if no subscribers
• Safe (cannot fill up server with undelivered
  messages)
ActiveMQ - Queues
• Load balancer semantics.
• Each message - 1 consumer.
• Messages queued.
• Multiple consumers
• Ack required (auto-ack possible)
• Danger will robinson!
AMQP
• More complex than STOMP
• Wiring of message routing is part of the
  protocol.
• All your clients know (at least half) of the
  wiring.
• Different topologies depending on routing
  configuration.
• Nice when your server dies - no ‘current
  config’
AMQP Concepts
              RabbitMQ


                vhost



  Publisher   Exchange




               Queue
  Consumer
Concepts - Exchanges

• Named
• Messages are published (sent) to one
  exchange
• Can be durable (forces all queues attached
  to be durable)
Queues
• Queues can be named.
• Queues are bound to one (or more)
  exchanges.
• Queues can have 0 or more clients
• Queues may persist or be deleted when
  they have no clients
• FIFO (if you have 1 consumer)
• Message never delivered to > 1 client
Bindings
• Binding is what joins a queue and an
  exchange.
• There can be more than one binding for
  each queue, allowing a single consumer to
  listen to multiple message sources
• You can bind to topic exchanges selectively
  via the message ‘routing key’
Job queue
• Named exchange
• Bound to 1 named and persistent queue
• 0 or more listeners get round-robin
  messages
• Messages queue when nobody listens / if
  consumers are slow
Publish/Subscribe
• Named exchange
• Each client creates an anonymous
  ephemeral queue
• Client binds the queue to that exchange
• All clients get all messages
• Messages go to /dev/null if no clients
AMQP can be complex
• Different exchange types - direct, topic,
  fanout (and custom exchange types
  possible)
• Messages have a routing key allowing
  selective binding.
• You can do a lot using these and a mix of
  named and anonymous queues
• Much more complex topologies possible
Implementations:

• So - I want a queue
• What do I use?
 • Naive approaches
 • Job queue only approaches
 • More sophisticated/custom approaches
(Shared) database table
• Have a ‘jobs’ table, with some data, and a
  ‘status’ column.
• Waiting => Running => Done
• Job workers poll the table and change
  statuses.
• NO NO NO NO NO NO NO NO
• No, really, mst will come and break your
  legs if you do this (after he stops laughing)
(Shared) database table
• Have a ‘jobs’ table, with some data, and a
  ‘status’ column.
• Waiting => Running => Done
• Job workers poll the table and change
  statuses.
• NO NO NO NO NO NO NO NO
• No, really, mst will come and break your
  legs if you do this.
(Shared) database table
• Have a ‘jobs’ table, with some data, and a
  ‘status’ column.
• Waiting => Running => Done
• MySQL will get the query plan wrong if
  you try joining this table (hint: the
  cardinality on your status column is 3).
• You will lose super-hard. HAND.
(Queue) database table

• Have separate queued / running / done tables
• Less bad for performance - at least the ‘find
  something to do’ query is very cheap.
• Still pretty terrible.
• You still re-invented a big old wheel here,
  probably badly.
Gearman
• Around since 2006. Multi platform.
• Not really a message queue - designed as a
  job queuing system
• Client, Job Server, Worker
• Failover (multiple job servers)
• NOT persistent
• Simple, works well (if that’s all you need)
TheSchwartz
• Is Persistent
• From the same place as Gearman
• Not as well adopted
• Relies on a MySQL database - SPOF
• Still simple - maybe the easiest way to get
  started (if you need reliable)?
Client libs: Net::Stomp
• Apache ActiveMQ.
• Dead simple producers and consumers.
• Just a client - you need to manage / run
  your own jobs.
• Blocking.
• Works perfectly well for sending messages
  from a web app.
Client libs:
      Net::RabbitFoot
• AMQP / RabbitMQ
• AnyEvent based - non blocking.
• Documentation pretty poor (sorry).
• Works well if you have an async app.
• Can be used inside a web app for simple
  sending.
Catalyst::Engine::Stomp
•   By chrisa @ Venda & yours truly; now
    maintained by Paul Moony.
•   Simple framework for writing jobs / managing
    workers.
•   Allows you to fire and forget, or fire and wait
    for termination (and pass a message back)
•   Achieves many of the same things a Gearman
•   Used in anger by several companies.
         (http://miltonkeynes.pm.org/talks/2010/06/paul_mooney_stomp_moosex_workers.pdf)
Net::ActiveMQ

• Builds on Catalyst::Engine::STOMP
• Chisel talked about this at YAPC::EU (Friday
  PM ‘Going Postal’)
• NetAPorter people - poke him to release it
  (or at least put it on github)!
Web::Hippie
• Persistent (potentially bidirectional) web
  pipe to applications.
• Cheap connection, no polling needed (on
  reasonably modern browsers). Great as the
  listener part for ‘replies’
• Downsides - needs to be async - no DBI
  (kinda)!
• Plays very nicely with RabbitMQ (hint
  MooseX::Storage & Joose.Storage <3)
CatalystX::JobServer
• My current baby.
• Uses AMQP.
• Provides Web::Hippie pipes for jobs - shiny
  shiny ajax updates.
• Barely production ready (but useable).
• I’m talking about it later...
Conclusions
• Use JSON for your message payloads.
• You probably want to use Gearman if you
  can get away with it.
• STOMP works well and is simple, tried and
  tested jobs solution.
• AMQP is nicer and more flexible, but there
  are less proven solutions (in perl).

More Related Content

PDF
Gophers Riding Elephants: Writing PostgreSQL tools in Go
PDF
Beyond Apache: Faster Web Servers
ODP
The Art of Message Queues - TEKX
PDF
Do More With Message Queue
PPTX
What to consider when monitoring microservices
PPTX
Do we need JMS in 21st century?
ODP
Art Of Message Queues
PDF
Enterprise messaging
Gophers Riding Elephants: Writing PostgreSQL tools in Go
Beyond Apache: Faster Web Servers
The Art of Message Queues - TEKX
Do More With Message Queue
What to consider when monitoring microservices
Do we need JMS in 21st century?
Art Of Message Queues
Enterprise messaging

What's hot (20)

PPTX
Message queue architecture
PDF
3 years with Clojure
PPTX
Windows Azure Service Bus
PPTX
Ups and downs of enterprise Java app in a research setting
PPT
Zarafa SummerCamp 2012 - Exchange Web Services on Zarafa
PPTX
Parallel and Asynchronous Programming - ITProDevConnections 2012 (English)
PDF
ActiveMQ In Action - ApacheCon 2011
PDF
Flink Forward SF 2017: Tzu-Li (Gordon) Tai - Joining the Scurry of Squirrels...
PPTX
Discover the Capabilities of Windows Azure Service Bus to Power Agile Busines...
PDF
10 things, an Oracle DBA should care about when moving to PostgreSQL
PPT
Apache ActiveMQ - Enterprise messaging in action
PDF
Archipel Introduction - ejabberd SF Meetup
PPTX
Serve like a boss (part one)
PDF
Transactional Streaming: If you can compute it, you can probably stream it.
KEY
Messaging, interoperability and log aggregation - a new framework
PDF
Cloud Messaging Service: Technical Overview
PDF
Where do I put this data? #lessql
PDF
Apache con2016final
PDF
Multiply like rabbits with rabbit mq
PDF
Mini-Training: Message Brokers
Message queue architecture
3 years with Clojure
Windows Azure Service Bus
Ups and downs of enterprise Java app in a research setting
Zarafa SummerCamp 2012 - Exchange Web Services on Zarafa
Parallel and Asynchronous Programming - ITProDevConnections 2012 (English)
ActiveMQ In Action - ApacheCon 2011
Flink Forward SF 2017: Tzu-Li (Gordon) Tai - Joining the Scurry of Squirrels...
Discover the Capabilities of Windows Azure Service Bus to Power Agile Busines...
10 things, an Oracle DBA should care about when moving to PostgreSQL
Apache ActiveMQ - Enterprise messaging in action
Archipel Introduction - ejabberd SF Meetup
Serve like a boss (part one)
Transactional Streaming: If you can compute it, you can probably stream it.
Messaging, interoperability and log aggregation - a new framework
Cloud Messaging Service: Technical Overview
Where do I put this data? #lessql
Apache con2016final
Multiply like rabbits with rabbit mq
Mini-Training: Message Brokers
Ad

Similar to High scale flavour (20)

KEY
Real time system_performance_mon
KEY
Cooking a rabbit pie
PDF
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
PPTX
Picking a message queue
PDF
Follow the White Rabbit - Message Queues with PHP
PDF
The Future of Messaging: RabbitMQ and AMQP
PPTX
High powered messaging with RabbitMQ
PDF
RabbitMQ with python and ruby RuPy 2009
PDF
Life in a Queue - Using Message Queue with django
PDF
Queue Everything and Please Everyone
PDF
Messaging with RabbitMQ and AMQP
PDF
Messaging Standards and Systems - AMQP & RabbitMQ
PDF
RabbitMQ fairly-indepth
PPT
Easy enterprise application integration with RabbitMQ and AMQP
PDF
PDF
Messaging Standards and Systems - AMQP & RabbitMQ
PPTX
Velocity Conference '13: Asynchronous messaging for performance optimization,...
PDF
Distributed and concurrent programming with RabbitMQ and EventMachine Rails U...
PDF
Evented applications with RabbitMQ and CakePHP
Real time system_performance_mon
Cooking a rabbit pie
Architecture | The Future of Messaging: RabbitMQ and AMQP | Eberhard Wolff
Picking a message queue
Follow the White Rabbit - Message Queues with PHP
The Future of Messaging: RabbitMQ and AMQP
High powered messaging with RabbitMQ
RabbitMQ with python and ruby RuPy 2009
Life in a Queue - Using Message Queue with django
Queue Everything and Please Everyone
Messaging with RabbitMQ and AMQP
Messaging Standards and Systems - AMQP & RabbitMQ
RabbitMQ fairly-indepth
Easy enterprise application integration with RabbitMQ and AMQP
Messaging Standards and Systems - AMQP & RabbitMQ
Velocity Conference '13: Asynchronous messaging for performance optimization,...
Distributed and concurrent programming with RabbitMQ and EventMachine Rails U...
Evented applications with RabbitMQ and CakePHP
Ad

More from Tomas Doran (20)

PPTX
Long haul infrastructure: Failures and successes
PDF
Empowering developers to deploy their own data stores
PDF
Dockersh and a brief intro to the docker internals
PDF
Sensu and Sensibility - Puppetconf 2014
PDF
Steamlining your puppet development workflow
PDF
Building a smarter application stack - service discovery and wiring for Docker
PDF
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
PPT
Deploying puppet code at light speed
PDF
Thinking through puppet code layout
PDF
Docker puppetcamp london 2013
PDF
"The worst code I ever wrote"
PDF
Test driven infrastructure development (2 - puppetconf 2013 edition)
PDF
Test driven infrastructure development
PPT
London devops - orc
KEY
London devops logging
KEY
Message:Passing - lpw 2012
KEY
Webapp security testing
KEY
Webapp security testing
KEY
Dates aghhhh!!?!?!?!
KEY
Zero mq logs
Long haul infrastructure: Failures and successes
Empowering developers to deploy their own data stores
Dockersh and a brief intro to the docker internals
Sensu and Sensibility - Puppetconf 2014
Steamlining your puppet development workflow
Building a smarter application stack - service discovery and wiring for Docker
Chasing AMI - Building Amazon machine images with Puppet, Packer and Jenkins
Deploying puppet code at light speed
Thinking through puppet code layout
Docker puppetcamp london 2013
"The worst code I ever wrote"
Test driven infrastructure development (2 - puppetconf 2013 edition)
Test driven infrastructure development
London devops - orc
London devops logging
Message:Passing - lpw 2012
Webapp security testing
Webapp security testing
Dates aghhhh!!?!?!?!
Zero mq logs

Recently uploaded (20)

PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Approach and Philosophy of On baking technology
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PPTX
Big Data Technologies - Introduction.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPT
Teaching material agriculture food technology
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Unlocking AI with Model Context Protocol (MCP)
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Modernizing your data center with Dell and AMD
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Approach and Philosophy of On baking technology
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Big Data Technologies - Introduction.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
Teaching material agriculture food technology
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
NewMind AI Weekly Chronicles - August'25 Week I
Unlocking AI with Model Context Protocol (MCP)
The AUB Centre for AI in Media Proposal.docx
Per capita expenditure prediction using model stacking based on satellite ima...
NewMind AI Monthly Chronicles - July 2025
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
MYSQL Presentation for SQL database connectivity
Mobile App Security Testing_ A Comprehensive Guide.pdf
Modernizing your data center with Dell and AMD

High scale flavour

  • 1. High scale flavor (recipes for message queueing) Tomas (t0m) Doran London Perl Workshop 2010
  • 2. What is message queueing. • In it’s simplest form, it’s just a list. • 1 (or more) ‘producers’ (writers) • 1 (or more) ‘consumers’ (readers) • Queue if rate of production > rate of consumption
  • 3. Why do I want it? • Decouples producers and consumers (probably across the network). • Lets you manage load, and spikes in load (only n consumers). • In a web environment - lets you serve more pages, quicker.
  • 4. What is the problem with web apps? • App servers take a lot of RAM • Context switching expensive • A lot of apps think like a CGI. • Making the user wait IS HORRIBLE. • Anything but very fast pages is fail.
  • 5. One page request per CPU core Even if extra context switching has zero overhead you serve people sooner if you queue requests. A B A B A B A B A B A finishes significantly before B in the lower diagram B finishes at the same time in both N.B. This explicitly assumes you never wait on external IO (e.g. a database)
  • 6. What are the solutions • Use a PAL (Page Assembly Layer) - e.g. Varnish • Defer doing work inside the web request to a queue • AJAX (heavy javascript) apps making many requests make this even more important. • If your requests are all small and fast then you can win by doing multiple small requests rather than one expensive one
  • 7. Message queueing • Many many flavors. • Going to cover options available right now in perl • First, a little theory
  • 8. Messaging Topologies • I.e. how producers and consumers interact together through the message broker • 3 common patterns - considerably more complex applications possible. • Even within these there is additional complexity to consider, e.g. message durability.
  • 9. 1: Publish-Subscribe • ‘Topic’ in ActiveMQ • Anonymous queues in AMQP • One (or more) publishers • Zero (or more) consumers • Every consumer gets every message • Messages discarded if no consumers • E.g. log message listener(s)
  • 10. 2: Queue(s) • One or more producers • One or more consumers • Each message delivered to exactly one consumer • Messages ‘queued’ (possibly to disk) • E.g. Job queue with worker pool allowing you to work efficiently through high load spikes
  • 11. 3: Request / Response • Create anonymous queue for replies • Publish to well known queue(s), include return address • Wait for reply. • Arrange for messages to be discarded if you stop listening for the reply.
  • 12. STOMP • Streamed Text Oriented Messageing Protocol • Simple. Interoperable. • You probably want to use ActiveMQ • Net::STOMP • Simple semantics: Queues and Topics • You can build the 3 simple patterns from these
  • 13. ActiveMQ - Topics • Publish / subscribe semantics. • Message goes to all the subscribers • Zero or more subscribers • Messages thrown away if no subscribers • Safe (cannot fill up server with undelivered messages)
  • 14. ActiveMQ - Queues • Load balancer semantics. • Each message - 1 consumer. • Messages queued. • Multiple consumers • Ack required (auto-ack possible) • Danger will robinson!
  • 15. AMQP • More complex than STOMP • Wiring of message routing is part of the protocol. • All your clients know (at least half) of the wiring. • Different topologies depending on routing configuration. • Nice when your server dies - no ‘current config’
  • 16. AMQP Concepts RabbitMQ vhost Publisher Exchange Queue Consumer
  • 17. Concepts - Exchanges • Named • Messages are published (sent) to one exchange • Can be durable (forces all queues attached to be durable)
  • 18. Queues • Queues can be named. • Queues are bound to one (or more) exchanges. • Queues can have 0 or more clients • Queues may persist or be deleted when they have no clients • FIFO (if you have 1 consumer) • Message never delivered to > 1 client
  • 19. Bindings • Binding is what joins a queue and an exchange. • There can be more than one binding for each queue, allowing a single consumer to listen to multiple message sources • You can bind to topic exchanges selectively via the message ‘routing key’
  • 20. Job queue • Named exchange • Bound to 1 named and persistent queue • 0 or more listeners get round-robin messages • Messages queue when nobody listens / if consumers are slow
  • 21. Publish/Subscribe • Named exchange • Each client creates an anonymous ephemeral queue • Client binds the queue to that exchange • All clients get all messages • Messages go to /dev/null if no clients
  • 22. AMQP can be complex • Different exchange types - direct, topic, fanout (and custom exchange types possible) • Messages have a routing key allowing selective binding. • You can do a lot using these and a mix of named and anonymous queues • Much more complex topologies possible
  • 23. Implementations: • So - I want a queue • What do I use? • Naive approaches • Job queue only approaches • More sophisticated/custom approaches
  • 24. (Shared) database table • Have a ‘jobs’ table, with some data, and a ‘status’ column. • Waiting => Running => Done • Job workers poll the table and change statuses. • NO NO NO NO NO NO NO NO • No, really, mst will come and break your legs if you do this (after he stops laughing)
  • 25. (Shared) database table • Have a ‘jobs’ table, with some data, and a ‘status’ column. • Waiting => Running => Done • Job workers poll the table and change statuses. • NO NO NO NO NO NO NO NO • No, really, mst will come and break your legs if you do this.
  • 26. (Shared) database table • Have a ‘jobs’ table, with some data, and a ‘status’ column. • Waiting => Running => Done • MySQL will get the query plan wrong if you try joining this table (hint: the cardinality on your status column is 3). • You will lose super-hard. HAND.
  • 27. (Queue) database table • Have separate queued / running / done tables • Less bad for performance - at least the ‘find something to do’ query is very cheap. • Still pretty terrible. • You still re-invented a big old wheel here, probably badly.
  • 28. Gearman • Around since 2006. Multi platform. • Not really a message queue - designed as a job queuing system • Client, Job Server, Worker • Failover (multiple job servers) • NOT persistent • Simple, works well (if that’s all you need)
  • 29. TheSchwartz • Is Persistent • From the same place as Gearman • Not as well adopted • Relies on a MySQL database - SPOF • Still simple - maybe the easiest way to get started (if you need reliable)?
  • 30. Client libs: Net::Stomp • Apache ActiveMQ. • Dead simple producers and consumers. • Just a client - you need to manage / run your own jobs. • Blocking. • Works perfectly well for sending messages from a web app.
  • 31. Client libs: Net::RabbitFoot • AMQP / RabbitMQ • AnyEvent based - non blocking. • Documentation pretty poor (sorry). • Works well if you have an async app. • Can be used inside a web app for simple sending.
  • 32. Catalyst::Engine::Stomp • By chrisa @ Venda & yours truly; now maintained by Paul Moony. • Simple framework for writing jobs / managing workers. • Allows you to fire and forget, or fire and wait for termination (and pass a message back) • Achieves many of the same things a Gearman • Used in anger by several companies. (http://miltonkeynes.pm.org/talks/2010/06/paul_mooney_stomp_moosex_workers.pdf)
  • 33. Net::ActiveMQ • Builds on Catalyst::Engine::STOMP • Chisel talked about this at YAPC::EU (Friday PM ‘Going Postal’) • NetAPorter people - poke him to release it (or at least put it on github)!
  • 34. Web::Hippie • Persistent (potentially bidirectional) web pipe to applications. • Cheap connection, no polling needed (on reasonably modern browsers). Great as the listener part for ‘replies’ • Downsides - needs to be async - no DBI (kinda)! • Plays very nicely with RabbitMQ (hint MooseX::Storage & Joose.Storage <3)
  • 35. CatalystX::JobServer • My current baby. • Uses AMQP. • Provides Web::Hippie pipes for jobs - shiny shiny ajax updates. • Barely production ready (but useable). • I’m talking about it later...
  • 36. Conclusions • Use JSON for your message payloads. • You probably want to use Gearman if you can get away with it. • STOMP works well and is simple, tried and tested jobs solution. • AMQP is nicer and more flexible, but there are less proven solutions (in perl).

Editor's Notes