Slide 1

Slide 1 text

[email protected] #SfDayPT 2014/03/08

Slide 2

Slide 2 text

 Store files on S3 (20 minutes)  Move your database to a separate server (10 minutes)  Create AMI image of your server’s disk (15 minutes)  Create an ELB with sticky sessions for that AMI (5 minutes)  Configure CloudWatch to trigger scaling (10 minutes) Good luck!

Slide 3

Slide 3 text

Who am I What I’ll talk about

Slide 4

Slide 4 text

CEO of be.ubi I’ve been programming and starting ventures since I was 12 years old [email protected] Send CV to: [email protected] "u bi qui tous" (adj.): existing or being everywhere at the same time; omnipresent ubi.banking is a modular banking processes management solution used in 8 Portuguese financial institutions. Symfony 1.4 SWE is a patent-pending retail solution that analyzes the Facebook profile of customers in real- time and presents individualized prices. Symfony 2

Slide 5

Slide 5 text

 The failed promise of the cloud  PaaS vs. IaaS  Growing your infrastructure as your userbase grows

Slide 6

Slide 6 text

or how I learned to stop worrying and love thy infrastructure

Slide 7

Slide 7 text

Capacity vs. Demand

Slide 8

Slide 8 text

Capacity vs. Demand

Slide 9

Slide 9 text

 Autoscaling requires changes to the application  Over-engineering for the perfect architecture  The fear of vendor lock-in  Premature optimization is the root of all evil!

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

Costs saving There’s no other alternative Learning

Slide 13

Slide 13 text

PaaS  Simpler  API, Deployment and Architectural lock-in  Costly  Rigid  CLI? Good for stable applications managed by business IaaS  Quite complex  Deployment lock-in  Cheapest  Flexible and emulatable Good for mutant applications managed by devops

Slide 14

Slide 14 text

Capacity vs. Demand

Slide 15

Slide 15 text

Learn as your app grows Generic approach for web applications

Slide 16

Slide 16 text

Vertical Before After

Slide 17

Slide 17 text

Process:  Disable app  Backup data  Start new bigger server  Restore app and data  Redirect  It’s sloooow, involves downtime  But requires no changes to the app  You MUST test the process  Setup monitoring and notifications  You can autoscale vertically but it isn’t worth the effort Vertical

Slide 18

Slide 18 text

AUTOMATE  Server Provisioning  App Deployment  Backup/Restore  Make all envs equal with virtualization  Use Vagrant! Do not not use it!  Infrastructure management code is still code, it should be tested as well! Preparations

Slide 19

Slide 19 text

OPTIMIZE PERFORMANCE  Lots of great presentations out there!  Understand your app’s performance  Focus on the bottleneck  It probably is the database reads  Use a Content-Delivery-Network  Only move forward if you don’t have a clear “next target” Preparations

Slide 20

Slide 20 text

DECOUPLE SERVICES  Common Web App Architecture:  Web Server  Database  Cache  Backend  Demand doesn’t oscillate equally across different services, so capacity shouldn’t either  Ensure that all service references to “localhost” are changeable parameters  You can and you should emulate the multiple servers inside vagrant Preparations

Slide 21

Slide 21 text

# example of decoupling services # parameters.yml default: database_host: localhost database_port: ~ cache_service_host: mycache.myapp.com cache_service_port: ~ service_a_host: localhost service_a_port: 123456 service_b_host: serviceb.myapp.com service_b_port: ~ service_c_host: etc.

Slide 22

Slide 22 text

ISOLATE DATA PERSISTANCE  Persistent storage is the hardest thing to scale, so isolate it to leave it to the last  Save the session in the database  Encapsulate file storage in wrapper that can handle:  Network File System  Cloud Storage Provider (e.g. S3)  Use Gaufrette and KnpGaufretteBundle  You can and you should emulate the multiple servers inside vagrant Preparations

Slide 23

Slide 23 text

# example of storing session in database # app/config/config.yml framework: session: # ... handler_id: session.handler.pdo parameters: pdo.db_options: db_table: session db_id_col: session_id db_data_col: session_value db_time_col: session_time services: pdo: class: PDO arguments: - "mysql:host=%database_host%; port=%database_port%; dbname=%database_name%“ - "%database_user%“ - "%database_password%" calls: - [setAttribute, [3, 2]] session.handler.pdo: class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler arguments: ["@pdo", "%pdo.db_options%"]

Slide 24

Slide 24 text

# example of configuring KnpGaufrette to abstract file storage # app/config/config.yml knp_gaufrette: adapters: uploads: local: directory: /path/to/my/filesystem create: true uploads_s3: amazon_s3: amazon_s3_id: amazonS3 bucket_name: foo_bucket options: directory: foo_directory # usage when local : gaufrette://uploads/... # usage when cloud : gaufrette://uploads_s3/...

Slide 25

Slide 25 text

HORIZONTAL SCALING Computing Before After

Slide 26

Slide 26 text

HORIZONTAL SCALING  The architecture and the app must be well prepared  Zero downtime  Distribute load across multiple servers:  Load-balancers / Proxys  Round-robin DNS  Process:  Start server  Provision server  Reconfigure load-balancer  You can, and probably should, mix with vertical scaling Computing

Slide 27

Slide 27 text

EXAMPLE ON AWS  Create a machine image through your automated provisioning  Automate the machine image packaging with Packer.io  Generate an AMI on AWS  Create a load-balancer that redirects to machines with that image  In AWS start an AutoScaling group for your AMI  If you want, you can use HAProxy out of the cloud  Setup triggers that create or destroy servers  CloudWatch on AWS  Or an infrastructure controller  Crons on a separate unique server  Proactive AutoScaling Computing

Slide 28

Slide 28 text

APPROACH A: PARTITIONING  The simplest solution on SQL  Separate different subdomains in different databases  Each set of database servers grows on its own  Requires changes to your application  Almost impossible to automate  It just delays the need for horizontal scaling for a while Data

Slide 29

Slide 29 text

APPROACH B: READ SYNC  Arguable the best solution in SQL  All writes are done on one authoritative master server that scales vertically  Data is replicated across multiple slave servers  There may be slight delays  You can hardcode multiple read-replicas on your Doctrine configuration  You can optionally use HAProxy to distribute sql read connections as well  This approach should allow you to support 10s to 100s of thousands users  PS – Write sync does not provide you with extra capacity Data

Slide 30

Slide 30 text

# Doctrine’s config file # Uses built-in # \Doctrine\DBAL\Connections\MasterSlaveConnection doctrine: dbal: driver: %database_driver% host: %database_host% port: %database_port% dbname: %database_name% user: %database_user% password: %database_password% slaves: slave1: host: %database_host_slave1% port: %database_port_slave1% dbname: %database_name_slave1% user: %database_user_slave1% password: %database_password_slave1% slave2: …

Slide 31

Slide 31 text

APPROACH C: SHARDING  This is the solution usually applied by NoSQL, MySQL Cluster, etc.  The writes and reads occur on a different server depending on the has of the row  This is the most scalable solution, scales both writes and reads  Transactions have an higher-toll and are not always supported  It’s not easy to automate resharding, but it’s possible  Leave it to the experts, use provided clustering solutions Data

Slide 32

Slide 32 text

Default answer: “It depends”

Slide 33

Slide 33 text

Please rate and comment on joind.in and do not hesitate to get in touch! https://joind.in/10784 [email protected]