Architecting with Queues - Northeast PHP 2015

30
Architecting with Queues for Scale and Separation Sandy Smith Northeast PHP 2015

Transcript of Architecting with Queues - Northeast PHP 2015

Page 1: Architecting with Queues - Northeast PHP 2015

Architecting with Queues for Scale and Separation

Sandy Smith Northeast PHP 2015

Page 2: Architecting with Queues - Northeast PHP 2015

Insert Text Here

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Setting Expectations

2

Page 3: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

What this talk is NOT

•A queues HOWTO (though there is some) •Benchmark bonanza •An Azure talk (though there is some)

3

Page 4: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

What this talk IS

•An architecture talk •A challenge to think differently about your applications •A story about rapidly developing an app

4

Page 5: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

The Challenge

5

Page 6: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Social Contest

•Show off Azure + PHP •People submit tweets to enter contest •Pull specified keywords from Twitter queue (prefiltered by Node.js app) •Human admins filter out inappropriate content •Humans or computer pulls out winner from approved entries, on timer or arbitrarily •Display latest entries and latest winners to public

6

Page 7: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Stretch goals

•Allow any size contest •Assume global contest with distributed moderators

7

Page 8: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Quick refresherPerformance vs. ScalingVertical vs. Horizontal Scaling

8

Page 9: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Initial design

9

Page 10: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

System-level view

10

Twitter Firehose

Entries

node.js app

Contest App DB

Public

Admins

Page 11: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

The real bottleneck

What’s the slowest and most variable part of any application?

11

Page 12: Architecting with Queues - Northeast PHP 2015

Insert Text Here

Architecting with Queues - Sandy Smith - Northeast PHP 2015

The real bottleneck

12

Page 13: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Traditional database design

•Group by kind •Keep metadata with object or in metadata tables •Objects (Document, Person, Account) are most important •Reinforced by TableGateway, ActiveRecord patterns, and ORM and framework module generator defaults •Works for 80+% of cases

13

Page 14: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Tradeoffs of traditional design

•Everything’s in one table, even when you routinely only need a subset •Typically one master writes, replicants read •Design is focused around what something is, not its state or other attribute •Requires creative solutions for horizontal scaling •Encourages (but does not require) centralizing logic for a given type of data

14

Page 15: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Worst of all…

•This design really didn’t show off all the stuff in Azure

15

Page 16: Architecting with Queues - Northeast PHP 2015

(We had a week left)

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Redesign time

16

Page 17: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Redesign goals

• Include as much Azure stuff as is reasonable • Implement the stretch goals of scalability

17

Page 18: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Queues to the rescue!(Plus some other cool stuff)

18

Page 19: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

New approach

•Keep long term but fast storage •Central concern is not the Thing (Entry) but Status

– Unapproved– Approved– Denied– Winner

•Separate updates to long term storage from status changes •Minimal impact to working code

19

Page 20: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Azure queuing options

Azure Queues (duh) •Simple •“Short”-lived (<7 days) •Used within Azure •Uses REST •Can track message processing

20

Azure Service Bus •Enterprisey •Long-lived • In Azure or private cloud •Can use AMQP, REST, or API •Can publish/subscribe •Can batch requests •Can guarantee FIFO •etc.

See https://msdn.microsoft.com/en-us/library/azure/hh767287.aspx

Page 21: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

More options

•Anything you can install on Linux or Windows (RabbitMQ, ZeroMQ, Kafka, Kestrel, ActiveMQ, etc.) •Any relational or NoSQL database •Azure Tables - Simple REST NoSQL store with a twist

21

Page 22: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Solutions

•Long term storage and display retrieval: Azure Table •Since Node.js app already used it, use Service Bus to store changes in status for consistency •Have daemons pull incoming status changes out and write them to the Table

22

Page 23: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

New design

23

__construct(EntryAccessor $mapper)Entry

EntryAccessor

__construct($proxy, $table)EntryAccessorTable

EntryRepository

__construct($dbh)EntryRepositoryTable

Entries

Incoming Daemon

Denied

Winner

Approv-ed

In-coming

Approved Daemon

Denied Daemon

Winner Daemon

Page 24: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Azure Table basics

24

require_once 'vendor\autoload.php'; use WindowsAzure\Common\ServicesBuilder; use WindowsAzure\Common\ServiceException; use WindowsAzure\Table\Models\Entity; use WindowsAzure\Table\Models\EdmType; // Create table REST proxy. $tableRestProxy = ServicesBuilder::getInstance()->createTableService($connectionString); try { // Create table. $tableRestProxy->createTable("mytable"); } catch(ServiceException $e){ // Handle exception based on error codes and messages.} $entity = new Entity(); $entity->setPartitionKey("pk"); $entity->setRowKey("1"); $entity->addProperty("PropertyName", EdmType::STRING, "Sample"); try { $tableRestProxy->insertEntity("mytable", $entity); } catch(ServiceException $e){ // Handle exception based on error codes and messages.}

Page 25: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Create and send with Service Bus

25

use WindowsAzure\ServiceBus\Models\QueueInfo; use WindowsAzure\Common\ServiceException; use WindowsAzure\Common\ServicesBuilder; $serviceBusRestProxy = ServicesBuilder::getInstance()->createServiceBusService($connectionString); try { $queueInfo = new QueueInfo("myqueue"); $serviceBusRestProxy->createQueue($queueInfo); } catch(ServiceException $e) { // handle error } try { // Create message. $message = new BrokeredMessage(); $message->setBody("my message"); // Send message. $serviceBusRestProxy->sendQueueMessage("myqueue", $message); } catch(ServiceException $e) { // handle error }

Page 26: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Receive with Service Bus

26

use WindowsAzure\ServiceBus\Models\QueueInfo; use WindowsAzure\Common\ServiceException; use WindowsAzure\Common\ServicesBuilder; $serviceBusRestProxy = ServicesBuilder::getInstance()->createServiceBusService($connectionString); try { // Set the receive mode to PeekLock (default is ReceiveAndDelete). $options = new ReceiveMessageOptions(); $options->setPeekLock(true); // Receive message. $message = $serviceBusRestProxy->receiveQueueMessage("myqueue", $options); echo "Body: ".$message->getBody()."<br />"; echo "MessageID: ".$message->getMessageId()."<br />"; // *** Process message here *** // Delete message. $serviceBusRestProxy->deleteMessage($message); } catch(ServiceException $e){ // handle error }

Page 27: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Benefits

•Queues add safety: if processing fails, main store is unchanged •App doesn’t wait for process-update-delete cycle

– Concerns more separated– Scaling is simpler

•Can move queue processing to separate machines •Trivial to move to different stores for each status •Very performant with up-to-second data

27

Page 28: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Challenges

•No full ACID •Safety is largely in the application layer •Potential for race conditions

– Humans suck

28

Page 29: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Takeaways

•Look for more than just long processes •Use queues to decouple functionality •Look for status changes, e.g. workflow • Is the type of data the most important aspect of your data?

– It usually is!•Design for replacement of components

– Makes changes easier (not easy)

29

Page 30: Architecting with Queues - Northeast PHP 2015

Architecting with Queues - Sandy Smith - Northeast PHP 2015

Links

•Azure: http://azure.microsoft.com/en-us/ •Social Contest:https://github.com/MusketeersMe/SocialContest •Me

– @SandyS1– http://phparch.com/

•Feedback! https://joind.in/14720 •php[world] (Nov 16–20) world.phparch.com •Slides will be at: slideshare.net/SandySmith

30