Professional Documents
Culture Documents
Applications on PostgreSQL
Konstantin Gredeskoul
CTO, Wanelo.com
@kig
@kigster
Proprietary and
Condential
Proprietary and
Proprietary and
Proprietary and
Heroku or Not?
Assuming we want full control of our
application layer, places like Heroku arent a
great t
But Heroku can be a great place to start. It
all depends on the size and complexity of the
app we are building.
nginx
N x Unicorns
Unicorn
/ Passenger
Ruby
Ruby VM
VM
/home/user/app/current/public
PostgreSQL
Server
/var/pgsql/data
First optimizations:
cheap early on, well worth it
Proprietary and
Proprietary and
browser
CDN
cache images, JS
N x Unicorns
Unicorn
/ Passenger
Ruby
Ruby VM
VM
PostgreSQL
Server
memcached
/home/user/app/current/public
incoming http
DNS round robin
or failover / HA solution
Load Balancers
nginx
haproxy
App Servers
Unicorn / Passenger
Ruby VM (times N)
Data stores
Transient to
Permanent
memcached
Background Workers
Sidekiq / Resque
CDN
cache images, JS
redis
Object Store
User Generated
Content
single DB
PostgreSQL
Proprietary and
Proprietary and
Even though we
achieved 99.99% uptime
in 2013, in 2014 we had
a couple short
downtimes caused by
overloaded replica that
lasted around 5 minutes.
But users quickly
notice
Proprietary and
Proprietary and
Perhaps not :)
Proprietary and
12-Step Program
for curing your dependency on slow application latency
Proprietary and
Proprietary and
Step 1:
Add More Cache!
Proprietary and
Moar Cache!!!
https://github.com/wanelo/compositor
https://github.com/Shopify/identity_cache
Proprietary and
Proprietary and
Step 2:
Optimize SQL
Proprietary and
SQL Optimization
Find slow SQL (>100ms) and either remove it, cache
the hell out of it, or x/rewrite the query
Are there adequate indexes for the query? Is the database using
appropriate index? Has the table been recently analyzed?
Proprietary and
Proprietary and
Proprietary and
Proprietary and
Proprietary and
Follows table
Proprietary and
Stories table
Proprietary and
Proprietary and
Proprietary and
Step 3:
Upgrade Hardware and RAM
Proprietary and
Hardware + RAM
Sounds obvious, but better or faster hardware is an
obvious choice when scaling out
Proprietary and
So whos better?
AWS
JOYENT
8 SSD drives
SSD Make: ?
CPU: E5-2670
2.6Ghz
CPU: E5-2690
2.9GHz
Step 4:
Scale Reads by Replication
Proprietary and
Proprietary and
haproxy
pgBouncer
pgBouncer
replica
replica
Proprietary and
Special considerations
Application must be tuned to support eventual
consistency. Data may not yet be on replica!
Proprietary and
P
App Servers
Unicorn / Passenger
Ruby VM (times N)
PostgreSQL
Master
Sidekiq / Resque
PostgreSQL
Replica 1
PostgreSQL
Replica 3
Proprietary and
Background Workers
PostgreSQL
Master
Sidekiq / Resque
PostgreSQL
Replica 1
Proprietary and
Step 5:
Use more appropriate tools
Proprietary and
Redis is a great data store for transient or semipersistent data with list, hash or set semantics
Back to PostgreSQL
But we still have single master DB taking
all the writes
True story: applying WAL logs on
replicas creates signicant disk write load
Proprietary and
Step 6:
Move write-heavy tables out:
Replace with non-DB solutions
Proprietary and
http://wanelo.ly/event-collection
Proprietary and
Step 7:
Tune PostgreSQL and your
Filesystem
Proprietary and
Tuning ZFS
Tuning Filesystem
Proprietary and
Proprietary and
https://github.com/wanelo-chef/postgres
It installs PG in eg /opt/local/postgresql-9.3.2
It congures its data in /var/pgsql/data93
It allows seamless and safe upgrades of minor or major
versions of PostgreSQL, never overwriting binaries
Proprietary and
http://www.slideshare.net/PGExperts/ve-steps-perform2013
http://wiki.postgresql.org/wiki/Performance_Optimization
http://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server
Proprietary and
Step 8:
Buer and serialize frequent
updates
Proprietary and
Counters, counters
Problem: products.saves_count is
Buering explained
Redis Cache
2. increment
counter
Save Product
1. enqueue update
request for product
with a delay
Save Product
Save Product
3. Process Job
5. Update Product
PostgreSQL
Proprietary and
Buering conclusions
Proprietary and
Step 9:
Optimize DB schema
Proprietary and
Proprietary and
Schema tricks
Proprietary and
Users
id
email
encrypted_password
reset_password_token
reset_password_sent_at
remember_created_at
sign_in_count
current_sign_in_at
last_sign_in_at
current_sign_in_ip
last_sign_in_ip
confirmation_token
confirmed_at
confirmation_sent_at
unconfirmed_email
failed_attempts
unlock_token
locked_at
authentication_token
created_at
updated_at
username
avatar
state
followers_count
saves_count
collections_count
stores_count
following_count
stories_count
refactor
UserCounts
user_id
followers_count
saves_count
collections_count
stores_count
following_count
stories_count
Users
id
email
created_at
username
avatar
state
UserLogins
user_id
encrypted_password
reset_password_token
reset_password_sent_at
remember_created_at
sign_in_count
current_sign_in_at
last_sign_in_at
current_sign_in_ip
last_sign_in_ip
confirmation_token
confirmed_at
confirmation_sent_at
unconfirmed_email
failed_attempts
unlock_token
locked_at
authentication_token
updated_at
Step 10:
Shard Busy Tables Vertically
Proprietary and
Vertical sharding
Proprietary and
Proprietary and
PostgreSQL
Master (Main Schema)
PostgreSQL
Replica (Main Schema)
PostgreSQL
Master (Split Table)
Proprietary and
http://wanelo.ly/vertical-sharding
Proprietary and
Step 11:
Wrap busy tables with services
Proprietary and
Splitting o services
Service App
Unicorn w/Sinatra
PostgreSQL
Native
Client Adaptor
Services conclusions
Step 12:
Shard Services Backend
Horizontally
Proprietary and
https://github.com/wanelo/sequel-schema-sharding
Proprietary and
index__on_user_id_and_collection_id
https://github.com/wanelo/sequel-schema-sharding
Proprietary and
https://github.com/wanelo/sequel-schema-sharding
Proprietary and
Sample
conguration of
shard mapping to
physical nodes
with read
replicas,
supported by the
library
Proprietary and
How can we migrate the data from old nonsharded backend to the new sharded backend
without a long downtime?
Proprietary and
Create Save
HTTP Service
Read/Write
Enqueue
Sidekiq Queue
New Sharded Backend
Background
Worker
Create Save
HTTP Service
Read/Write
Enqueue
Migration Script
Sidekiq Queue
New Sharded Backend
Background
Worker
Background
Worker
Sidekiq Queue
Enqueue
Create Save
HTTP Service
Read/Write
https://github.com/wanelo/sequel-schema-sharding
Proprietary and
Proprietary and
MemCached Cluster
4-core 16GB zones
Cluster of MemCached Servers
is accessed via Dali fault tolerant library
one or more can go down
Load Balancers
incoming http
requests
Makara distributes DB
load across 3 replicas
and 1 master
pgbouncer
nginx
haproxy
Unicorn
Main Web/API App,
Ruby 2.0
memcached
PostgreSQL
Async Replicas
PostgreSQL 9.2
Master
Unicorn
Saves Service
Fastly CDN
cache images, JS
Redis Sidekiq
Jobs Queue / Bus
redis
Amazon S3
Product Images
User Profile Pictures
haproxy
redis-001
twemproxy
Sidekiq Background
Worker
Unicorn
Saves Service
to DBs
redis-256
pgbouncer
Solr Reads
8GB High CPU zones
Systems Diagram
Solr Updates
Solr Master
Solr Replica
Proprietary
y and
d
We are hiring!
DevOps, FullStack, Scaling Experts, iOS & Android
http://wanelo.com/about/play
Or email play@wanelo.com
Proprietary and
Thanks!
github.com/wanelo
github.com/wanelo-chef
@kig
ki
@kig
building.wanelo.com
@kigster
Proprietary and