Scaling symfony apps

83
Rome, 28 October 2016 Scaling Symfony apps

Transcript of Scaling symfony apps

Page 1: Scaling symfony apps

Rome, 28 October 2016

Scaling Symfony apps

Page 2: Scaling symfony apps

WHO AM I?

Page 3: Scaling symfony apps

Matteo Moretti

Page 4: Scaling symfony apps

CTO @

website: madisoft.ittech blog: labs.madisoft.it

Page 5: Scaling symfony apps

Scalability

Page 6: Scaling symfony apps

It’s from experience.

There are no lessons.

Page 7: Scaling symfony apps

Nuvola

● > 3M HTTP requests / day● ~ 1000 databases● ~ 350GB mysql data● ~ 180M query / day● ~ 25M of media files● ~ 4.50TB of medis files● From ~5k to ~200k sessions in 5 minutes

Page 8: Scaling symfony apps

Scalability

Your app is scalable if it can adapt to support an increasing amount of data

or a growing number of users.

Page 9: Scaling symfony apps

“But… I don’t have an increasing load”

(http://www.freepik.com/free-photos-vectors/smile - Smile vector designed by Freepik)

Page 10: Scaling symfony apps

“Scalability doesn’t matter to you.”

(http://www.freepik.com/free-photos-vectors/smile - Smile vector designed by Freepik)

Page 11: Scaling symfony apps
Page 12: Scaling symfony apps

“I do have an increasing load”

(http://www.freepik.com/free-photos-vectors/smile - Smile vector designed by Freepik)

Page 13: Scaling symfony apps

Your app is growing

Page 14: Scaling symfony apps

But… suddenly…

Page 15: Scaling symfony apps
Page 16: Scaling symfony apps
Page 17: Scaling symfony apps
Page 18: Scaling symfony apps
Page 19: Scaling symfony apps

Ok, we need to scale

Page 20: Scaling symfony apps

Scaling… what?PHP code?

Database?

Sessions?

Storage?

Async tasks?

Page 21: Scaling symfony apps

Everything?

Page 22: Scaling symfony apps

Can Node.js scale?

Page 23: Scaling symfony apps

Can Symfony scale?

Page 24: Scaling symfony apps

Can PHP scale?

Page 25: Scaling symfony apps

Scaling is aboutapp architecture

Page 26: Scaling symfony apps

App architecture

How can you scale your web server if you put everything inside?

Database, user files, sessions, ...

Page 27: Scaling symfony apps

App architecture / Decouple

● Decouple services● Service: do one thing and do it well

Page 28: Scaling symfony apps

App architecture / Decouple

Page 29: Scaling symfony apps

4 main areas

1. web server2. sessions3. database4. filesystem

There are some more (http caching, frontend, queue systems, etc): next talk!

Page 30: Scaling symfony apps

Web server

Many small webservers

(scale up vs scale out)

Page 31: Scaling symfony apps

Web server

NGINX + php-fpm

PHP 7

Symfony 3

Page 32: Scaling symfony apps

Web server / Cache

PHP CACHE

SYMFONY CACHE

DOCTRINE CACHE

Page 33: Scaling symfony apps

Web server / PHP Cache

Opcache

Bytecode caching

opcache.enable = On

opcache.validate_timestamps = 0

https://tideways.io/profiler/blog/fine-tune-your-opcache-configuration-to-avoid-caching-suprises

Page 34: Scaling symfony apps

PHP code / Symfony cache

● Put Symfony cache in ram ● Use cache warmers during deploy

releaseN/var/cache -> /var/www/project/cache/releaseN

“/etc/fstab”

tmpfs /var/www/project/cache tmpfs size=512m

Page 35: Scaling symfony apps

PHP code / Doctrine cache

● Configure Doctrine to use cache● Disable Doctrine logging and profiling on prod

doctrine.orm.default_metadata_cache:type: apc

doctrine.orm.default_query_cache:type: apc

doctrine.orm.default_result_cache:type: apc

Page 36: Scaling symfony apps

PHP code / Cache

DISK I/O ~ 0%

Page 37: Scaling symfony apps

Monitor

Measure

Analyze

Page 38: Scaling symfony apps

PHP code / Profiling

XHProf

Blackfire

New Relic

Page 39: Scaling symfony apps
Page 40: Scaling symfony apps
Page 41: Scaling symfony apps

PHP code / Recap

● Easy● No need to change your PHP code● It’s most configuration and tuning● You can do one by one and measure how it affects performance● Need to monitor and profile: New Relic for PHP● Don’t waste time on micro-optimization

Take away: use cache!

Page 42: Scaling symfony apps

Sessions

● Think session management as a service● Use centralized Memcached or Redis (Ec2

or ElasticCache on AWS)● Avoid sticky sessions (load balancer set up)

Page 43: Scaling symfony apps

Session / Memcached

No bundle required

https://labs.madisoft.it/scaling-symfony-sessions-with-memcached/

Page 45: Scaling symfony apps

Session / Redisconfig.yml

framework: session: handler_id: snc_redis.session.handler

Page 46: Scaling symfony apps

Session / RedisBundle config

snc_redis: clients: session_client: dsn: '%redis_dsn_session%' logging: false # https://github.com/snc/SncRedisBundle/issues/161 type: phpredis session: client: session_client locking: false prefix: session_prefix_ ttl: '%session_ttl%'

Page 47: Scaling symfony apps

Session / Redisparameters.yml

redis_db: 3redis_dsn_session: 'redis://%redis_ip%/%redis_db%'redis_ip: redis-cluster.my-lan.comsession_ttl: 86400

Page 48: Scaling symfony apps

Session / Recap

● Very easy ● No need to change your PHP code● Redis better than Memcached: it has persistence and many other features● Let AWS scale for you and deal with failover and sysadmin stuff

Take away: use Redis

Page 49: Scaling symfony apps

Database

Aka “The bottleneck”

Page 50: Scaling symfony apps

Database

Relational databases

Page 51: Scaling symfony apps

Database

NOSQL db?

Page 52: Scaling symfony apps

Database

If you need data integrity do not replace your SQL db with

NOSQL to scale

Page 53: Scaling symfony apps

Database

How to scale SQL db?

Page 54: Scaling symfony apps

Database

When to scale?

Page 55: Scaling symfony apps

Database

If dbsize < 10 GB

dont_worry();

Page 56: Scaling symfony apps

Database / Big db problems

● Very slow backup. High lock time● If mysql crashes, restart takes time● It takes time to download and restore in dev● You need expensive hardware (mostly RAM)

Page 57: Scaling symfony apps

Database / Short-term solutions

Use a managed db service like AWS RDS

● It scales for you● It handles failover and backup for you

But:

● It’s expensive for big db● Problems are only mitigated but they are still there

Page 58: Scaling symfony apps

Database / Long-term solutions

Sharding

Page 59: Scaling symfony apps

Database / Sharding

Split a single big db into many small dbs

(multi-tenant)

Page 60: Scaling symfony apps

Database / Sharding

● Very fast backuo. Low lock time● If mysql crashes, restart takes little time● Fast to download and restore in dev● No need of expensive hardware● You arrange your dbs on many machines

Page 61: Scaling symfony apps

Database / Sharding

● How can Symfony deal with them?● How to execute a cli command on one of them?● How to apply a migration (ie: add column) to 1000 dbs?● …...

Page 62: Scaling symfony apps

Database / Sharding

Doctrine DBAL & ORM

Page 63: Scaling symfony apps

Database / Sharding

Define a DBAL connection and a ORM entity manager for each db

https://symfony.com/doc/current/doctrine/multiple_entity_managers.html

Page 64: Scaling symfony apps

Database / Sharding

doctrine: orm: entity_managers: global: connection: global shard1: connection: shard1 shard2: connection: shard2

doctrine: dbal: connections: global:

….. shard1: …… shard2: …... default_connection: global

Page 65: Scaling symfony apps

Database / Sharding

This works for few dbs (~ <5)

Page 66: Scaling symfony apps

Database / Sharding

Doctrine shardinghttp://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/sharding.html

Page 67: Scaling symfony apps

Database / Doctrine sharding

● Suited for multi-tenant applications● Global database to store shared data (ie: user data)● Need to use uuid

http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/sharding.html

Page 68: Scaling symfony apps

Database / Sharding

Configuration

doctrine: dbal: default_connection: global connections: default: shard_choser_service: vendor.app.shard_choser shards: shard1: id: 1 host / user / dbname shard2: id: 2 host / user / dbname

Page 69: Scaling symfony apps

Database / Sharding

ShardManager Interface

$shardManager = new PoolingShardManager();

$currentCustomerId = 3;$shardManager->selectShard($currentCustomerId);// all queries after this call hit the shard where customer // with id 3 is on

$shardManager->selectGlobal();// the global db is selected

Page 70: Scaling symfony apps

Database / Sharding

● It works but it’s complex to be managed● No documentation everywhere● Need to manage shard configuration: adding a new

shard?● Need to parallelize shard migrations: Gearman?● Deal with sharding in test environment

Page 71: Scaling symfony apps

Database / Recap● NOSQL is not used to scale SQL: they have different purposes. You can

use both.● Sharding is difficult to implement● Need to change your code● Short-term solution is to use AWS to leverage some maintenance● Doctrine ORM sharding works well but you need to write code and

wrappers. Best suited for multi-tenant apps● When it’s done, you can scale without any limit

Take away: do sharding if your REALLY need it

Page 72: Scaling symfony apps

Filesystem

Users upload files: documents, media, etc

How to handle them?

Page 73: Scaling symfony apps

Filesystem

● Need of filesystem abstraction● Use external object storage like S3● Avoid using NAS: it’s tricky to be set-up correctly

Page 74: Scaling symfony apps

Filesystem / Abstraction

● FlysystemBundle

● KnpGaufretteBundle

https://github.com/1up-lab/OneupFlysystemBundle

Page 75: Scaling symfony apps

Filesystem / Abstractionhttps://github.com/1up-lab/OneupFlysystemBundle

● AWS S3● Dropbox● FTP● Local filesystem● ...

Page 76: Scaling symfony apps

Filesystem / Abstraction

Configuration

oneup_flysystem: adapters: s3_adapter: awss3v3: client: s3_client bucket: "%s3_bucket%"

oneup_flysystem: adapters: local_adapater: local: directory: ‘myLocalDir’

Page 77: Scaling symfony apps

Filesystem / Abstraction

Configuration

prod.yml

oneup_flysystem: filesystems: my_filesystem: adapter: s3_adapter

dev.yml

oneup_flysystem: filesystems: my_filesystem: adapter: local_adapter

Page 78: Scaling symfony apps

Filesystem / Abstraction

Usage

// League\Flysystem\FilesystemInterface

$filesystem = $container->get(‘oneup_flysystem.my_filesystem’);

$path = ‘myFilePath’;$filesystem->has($path);$filesystem->read($path);$filesystem->write($path, $contents);

Page 79: Scaling symfony apps

Filesystem / Recap

● Easy● Need to change your PHP code ● Ready-made bundles● Avoid local filesystem and NAS

Take away: use FlystemBundle with S3

Page 80: Scaling symfony apps

Scaling / Recap

● Sessions and filesystem: easy. Do it● PHP code: not difficult. Think of it. Save money.● Database: very hard. Think a lot● Queue systems, http cache and some other stuff: next

talk but think of them as services

Page 81: Scaling symfony apps

THANK YOU

Page 82: Scaling symfony apps

WE ARE HIRING!(wanna join? ask us or visit our website)

Page 83: Scaling symfony apps

QUESTIONS?