Scaling Rails App
Scaling Rails App
No prior understanding of scaling
No assumption regarding libraries
No assumption regarding system architecture
Scalability is the capability of a system, network, or process to handle a growing amount of work, or its potential to be enlarged to accommodate that growth.
Horizontal: adding more machines
Vertical: adding more resource in a machine
Simple application
Upgrade to better library
Change SQLite to better database
Change your app server
Don't | Do |
Webrick | Puma |
Mongrel | Unicorn |
Passenger | |
Thin |
Consider: daemonize your app server, adjust workers configuration, integrate into deploy script. Also event based, process based or thread based.
Use Webserver
Why we need extra layer?
- SSL
- App server doesn't handle static files well
- App server is designed for low latency client
- App server is IO blocking
- Web server manage expires header, gzip compression for static files, redirection, and many more
- HTTP/1.1 keep-alive is not available in app server
- Using only app server will make it harder if we want to scale to multiple machine
- HTTP2
Webservers
Webservers
- HttpPlatformHandler (IIS)
- mod_proxy (Apache / lighthttpd)
- proxy_pass (Nginx)
- Passenger + nginx / apache module
- Please do not use fcgi anymore
Make application work across multiple machine
Static Files Service for assets
config.asset_host = "https://someserver.example.com"
Static files server
(Nginx, Apache, etc)
AWS S3
Azure Blob Storage
Google Cloud Storage
Swift
(Openstack Storage)
Consider:
-
Implement "strong caching header".
Cache-Control is preferable over Expires. -
Implement "weak caching header" i.e. Last-Modified or ETag
-
Implement gzip and add Content-Encoding="gzip" header
-
Restrict access by checking http referer
-
Adjust your deploy script (asset_sync)
-
CORS problem.
What about user uploaded content?
-
Paperclip, Carrierwave, and Refile has plugins/extensions for major storage service provider
-
Use networked file system such as nfs or smb
-
Use sftp or ftp (shudder)
-
Extend those gems. We are engineers.
-
We can use the same asset host or use different server
Why don't we move database to special server so it can be used by many rails application?
config/database.yml
Self hosted database
AWS RDS
AWS
Dynamodb
Google
Cloud SQL
Google
Cloud Datastore
Azure Cosmos DB
Azure SQL
Consider:
-
Replication - Copying an entire table or database onto multiple servers.
-
Partitioning - Splitting up a large monolithic database into multiple smaller databases based on data cohesion.
-
Clustering - Using multiple application servers to access the same database. Used for computation intensive, parallelized, analytical applications that work on non volatile data.
-
Sharding - Splitting up a large table of data horizontally i.e. row-wise.
-
Update your deployment script
-
Replication is great for high availability
-
Secure your database so it's not available from the big bad world. Use db tunnel.
Now we can tell web server to connect to multiple rails instance
How?
Load Balancer
- Nginx has built in support
- Apache also has built in support using mod_proxy_balancer
- IIS?
- Standalone load balancer such as HAProxy
- Hardware load balancer?
What's Next?
Cache
Doesn't make sense if each rails instance implement it's own data cache
config.cache_store = :memory_store, { size: 64.megabytes }
config.cache_store = :file_store, "/cache/directory"
config.cache_store = :mem_cache_store, "cache.example.com"
config.cache_store = :redis_store, 'redis://1.2.3.4:6379/0/cache'
Roll your own
memcached server
redis server
distributed
replicated
networked file system
AWS ElastiCache
Azure
Cache Store
Redis Cloud
Mem Cloud
Better. Now implement workers
www.
example.com
assets.
example.com
Workers
Next, Add CDN
- Different domains. Browser limit connections to single domain
- Distributed globally
- High capacity
- High speed
- Caching
- Header control
- Analytics
- Whole sites or just assets
- Setup CDN
- Set CDN origin to our site / assets site
- CDN will give you end point
- Optional, set CNAME or alias your domain to CDN
- Set your application to use CDN endpoint
set CNAME cdn.example.com to cdn.cdnprovider.net
config.asset_host = "https://cdn.example.com"
Build yourself
www.
example.com
assets.
example.com
cdn.
example.com
I want to add...
Scaling Principles
- Separate
- Scale individual service horizontally or vertically
- Load balance or connect to other
TODO for your consideration:
- Configuration and or Orchestration tools. Chef. Puppet. Salt. Ansible. Terraform. Cloudformation.
- Logging. Collecting Log. Transporting Log. Storing Log. Parsing. Analysis.
Use ELK (Elasticsearch, Logstash, Kibana) or Graylog. - Monitoring. Zabbix, Monit, God, Nagios, Cacti, Newrelic, Cloudwatch.
- Budget planning.
Use tools from cloud providers, prices as advertised, estimate and extrapolate from usage data. - Security. Protect public access to data storage and services.
Scaling Rails App
Questions?
Scaling Rails App
By Karuna Murti
Scaling Rails App
Scaling Rails Application
- 1,714