Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AutoScaling Symfony Applications

AutoScaling Symfony Applications

One of the biggest value propositions of the cloud was that we would be able to dynamically adapt our infrastructure according to our needs. But it’s not the magic that most people desire and it’s sometimes hard to navigate in a wide range of problems and solutions, which scare a lot of developers away. But if planned right, it’s not that hard too. This session provides an overview of the problems that arise when you want to develop an automatically scalable php application and how to solve them using open-source tools and cloud services.

D506359a10a07b7fd301b210b8398708?s=128

Luís Faceira

March 08, 2014
Tweet

Transcript

  1. luis.faceira@beubi.com #SfDayPT 2014/03/08

  2.  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!
  3. Who am I What I’ll talk about

  4. CEO of be.ubi I’ve been programming and starting ventures since

    I was 12 years old luis.faceira@beubi.com Send CV to: jobs@beubi.com "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
  5.  The failed promise of the cloud  PaaS vs.

    IaaS  Growing your infrastructure as your userbase grows
  6. or how I learned to stop worrying and love thy

    infrastructure
  7. Capacity vs. Demand

  8. Capacity vs. Demand

  9.  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!
  10. None
  11. None
  12. Costs saving There’s no other alternative Learning

  13. 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
  14. Capacity vs. Demand

  15. Learn as your app grows Generic approach for web applications

  16. Vertical Before After

  17. 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
  18. 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
  19. 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
  20. 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
  21. # 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.
  22. 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
  23. # 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%"]
  24. # 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/...
  25. HORIZONTAL SCALING Computing Before After

  26. 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
  27. 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
  28. 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
  29. 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
  30. # 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: …
  31. 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
  32. Default answer: “It depends”

  33. Please rate and comment on joind.in and do not hesitate

    to get in touch! https://joind.in/10784 luis.faceira@beubi.com