SlideShare a Scribd company logo
@molly_struve
Cache is King
Get the Most Bang for Your Buck From Ruby
@molly_struve
Site Reliability Engineer
@molly_struve
@molly_struve
Adding Indexes
Using SELECT statements
Batch Processing
@molly_struve
Elasticsearch::Transport::Errors::GatewayTimeout 504
{
"statusCode": 200,
"took": "100ms"
}
@molly_struve
Resque
@molly_struve
@molly_struve
Demo Time!
@molly_struve
Quantity of Datastore Hits
@molly_struve
@molly_struve
The average company has...
60 thousand
assets
24 million
vulnerabilities?
@molly_struve
MySQL
Elasticsearch
Cluster
@molly_struve
Serialization
@molly_struve
MySQL
Elasticsearch
Cluster
ActiveModelSerializers
@molly_struve
module Beehive
module Serializers
class Vulnerability < ActiveModel::Serializer
attributes :id, :client_id, :created_at, :updated_at,
:priority, :details, :notes, :asset_id,
:solution_id, :owner_id, :ticket_id
end
end
end
@molly_struve
200 MILLION
@molly_struve
11 hours and counting...
@molly_struve
@molly_struve
@molly_struve
(1.6ms)
(0.9ms)
(4.1ms)(5.2ms)
(5.2ms)
(1.3ms)
(3.1ms)
(2.9ms)
(2.2ms)
(4.9ms)
(6.0ms)
(0.3ms)
(1.6ms)
(0.9ms)
(2.2ms)
(3.0ms)
(2.1ms)
(1.3ms)
(2.1ms)
(8.1ms)
(1.4ms)
@molly_struve
MySQL
@molly_struve
Bulk Serialization
@molly_struve
class BulkVulnerabilityCache
attr_accessor :vulnerabilities, :client, :vulnerability_ids
def initialize(vulns, client)
self.vulnerabilities = vulns
self.vulnerability_ids = vulns.map(&:id)
self.client = client
end
# MySQL Lookups
end
@molly_struve
module Serializers
class Vulnerability
attr_accessor :vulnerability, :cache
def initialize(vuln, bulk_cache)
self.cache = bulk_cache
self.vulnerability = vuln
end
end
end
self.cache = bulk_cache
@molly_struve
class Vulnerability
has_many :custom_fields
end
@molly_struve
CustomField.where(:vulnerability_id => vuln.id)
cache.fetch('custom_fields', vuln.id)
@molly_struve
The Result...
(pry)> vulns = Vulnerability.limit(300);
(pry)> Benchmark.realtime { vulns.each(&:serialize) }
=> 6.022452222998254
(pry)> Benchmark.realtime do
> BulkVulnerability.new(vulns, [], client).serialize
> end
=> 0.7267019419959979
@molly_struve
Decrease in database hits
Individual Serialization:
Bulk Serialization:
2,100
7
@molly_struve
1k vulns 1k vulns 1k vulns
Vulnerability Batches
@molly_struve
1k vulns 1k vulns 1k vulns
Vulnerability Batches
7k 7
@molly_struve
MySQL Queries
Bulk Serialization
Deployed
@molly_struve
Bulk Serialization
Deployed
RDS CPU Utilization
@molly_struve
Process
in Bulk
@molly_struve
@molly_struve
@molly_struve
Elasticsearch
Cluster
+
Redis
MySQL
Vulnerabilities
@molly_struve
Redis.get
Client 1
Index
Client 2
Index
Client 3 & 4
Index
@molly_struve
indexing_hashes = vulnerability_hashes.map do |hash|
{
:_index => Redis.get(“elasticsearch_index_#{hash[:client_id]}”)
:_type => hash[:doc_type],
:_id => hash[:id],
:data => hash[:data]
}
end
@molly_struve
indexing_hashes = vulnerability_hashes.map do |hash|
{
:_index => Redis.get(“elasticsearch_index_#{hash[:client_id]}”)
:_type => hash[:doc_type],
:_id => hash[:id],
:data => hash[:data]
}
end
@molly_struve
(pry)> index_name = Redis.get(“elasticsearch_index_#{client_id}”)
DEBUG -- : [Redis] command=GET args="elasticsearch_index_1234"
DEBUG -- : [Redis] call_time=1.07 ms
GET
@molly_struve
@molly_struve
@molly_struve
client_indexes = Hash.new do |h, client_id|
h[client_id] = Redis.get(“elasticsearch_index_#{client_id}”)
end
@molly_struve
indexing_hashes = vuln_hashes.map do |hash|
{
:_index => Redis.get(“elasticsearch_index_#{client_id}”)
:_type => hash[:doc_type],
:_id => hash[:id],
:data => hash[:data]
}
end
client_indexes[hash[:client_id]],
@molly_struve
1 + 1 + 1
Client 1 Client 2 Client 3
1k 1k 1k
@molly_struve
1000x
@molly_struve
65% job
speed up
@molly_struve
Local Cache
@molly_struve
Redis
@molly_struve
Process
in Bulk
Hash
Cache
@molly_struve
Sharded Databases
CLIENT 1
CLIENT 2
CLIENT 3
@molly_struve
Asset.with_shard(client_id).find(1)
@molly_struve
{
'client_123' => 'shard_123',
'client_456' => 'shard_456',
'client_789' => 'shard_789'
}
Sharding Configuration
@molly_struve
@molly_struve
Sharding Configuration Size
20 bytes 1kb 13kb
@molly_struve
285 Workers
@molly_struve
7.8 MB/second
@molly_struve
ActiveRecord::Base.connection
@molly_struve
(pry)> ActiveRecord::Base.connection
=> #<Octopus::Proxy:0x000055b38c697d10
@proxy_config= #<Octopus::ProxyConfig:0x000055b38c694ae8
@molly_struve
module Octopus
class Proxy
attr_accessor :proxy_config
delegate :current_shard, :current_shard=,
:current_slave_group, :current_slave_group=,
:shard_names, :shards_for_group, :shards, :sharded,
:config, :initialize_shards, :shard_name, to: :proxy_config, prefix: false
end
end
@molly_struve
Know your gems
@molly_struve
Process
in Bulk
Framework
Cache
Hash
Cache
@molly_struve
Avoid making datastore hits you don’t
need
@molly_struve
User.where(:id => user_ids).each do |user|
# Lots of user processing
end
@molly_struve
FALSE
@molly_struve
(pry)> User.where(:id => [])
User Load (1.0ms) SELECT `users`.* FROM `users` WHERE 1=0
=> []
@molly_struve
@molly_struve
return unless user_ids.any?
User.where(:id => user_ids).each do |user|
# Lots of user processing
end
@molly_struve
(pry)> Benchmark.realtime do
> 10_000.times { User.where(:id => []) }
> end
=> 0.5508159045130014
(pry)> Benchmark.realtime do
> 10_000.times do
> next unless ids.any?
> User.where(:id => [])
> end
> end
=> 0.0006368421018123627
@molly_struve
(pry)> Benchmark.realtime do
> 10_000.times { User.where(:id => []) }
> end
=> 0.5508159045130014
“Ruby is slow”Hitting the database is slow!
@molly_struve
User.where(:id => user_ids).each do |user|
# Lots of user processing
end
@molly_struve
User.where(:id => user_ids).each do |user|
# Lots of user processing
end
users = User.where(:id => user_ids).active.short.single
@molly_struve
.none
@molly_struve
(pry)> User.where(:id => []).active.tall.single
User Load (0.7ms) SELECT `users`.* FROM `users` WHERE 1=0 AND
`users`.`active` = 1 AND `users`.`short` = 0 AND `users`.`single` = 1
=> []
(pry)> User.none.active.tall.single
=> []
.none in action...
@molly_struve
@molly_struve
@molly_struve
Logging
pry(main)> Rails.logger.level = 0
$ redis-cli monitor > commands-redis-2018-10-01.txt
pry(main)> Search.connection.transport.logger = Logger.new(STDOUT)
@molly_struve
Preventing useless
datastore hits
@molly_struve
@molly_struve
Report
Elasticsearch
MySQL Redis
@molly_struve
(pry)> Report.blank_reports.count
=> 10805
(pry)> Report.active.count
=> 25842
(pry)> Report.average_asset_count
=> 1657
Investigating Existing Reports
@molly_struve
Report
Elasticsearch
MySQL Redis
@molly_struve
@molly_struve
return if report.asset_count.zero?
@molly_struve
10+ hrs
@molly_struve
3 hrs
@molly_struve
Process
in Bulk
Framework
Cache
Database
Guards
Hash
Cache
@molly_struve
Resque Workers
Redis
@molly_struve
45 workers
45 workers
45 workers
@molly_struve
70 workers
70 workers
70 workers
@molly_struve
@molly_struve
@molly_struve
@molly_struve
48 MB
16 MB
@molly_struve
Redis Requests
70 workers
100k
200k
@molly_struve
@molly_struve
?
@molly_struve
Resque
Throttling
@molly_struve
Redis Requests
100k
200k
@molly_struve
Redis Network Traffic
48MB
16MB
@molly_struve
@molly_struve
Process
in Bulk
Framework
Cache
Database
Guards
Remove
Datastore
Hits
Hash
Cache
@molly_struve
Every
datastore hit
COUNTS
@molly_struve
@molly_struve
Questions
@molly_struve
Contact
https://www.linkedin.com/in/mollystruve/
https://github.com/mstruve
@molly_struve
molly.struve@gmail.com

More Related Content

PDF
Cache is King: RubyConf Columbia
PDF
Cache is King - RailsConf 2019
PDF
Cache is King: Get the Most Bang for Your Buck From Ruby
PDF
Memcached Presentation @757rb
PDF
DEF CON 23 - amit ashbel and maty siman - game of hacks
PDF
Kickin' Ass with Cache-Fu (without notes)
 
PDF
Kickin' Ass with Cache-Fu (with notes)
 
PPT
Using npm to Manage Your Projects for Fun and Profit - USEFUL INFO IN NOTES!
Cache is King: RubyConf Columbia
Cache is King - RailsConf 2019
Cache is King: Get the Most Bang for Your Buck From Ruby
Memcached Presentation @757rb
DEF CON 23 - amit ashbel and maty siman - game of hacks
Kickin' Ass with Cache-Fu (without notes)
 
Kickin' Ass with Cache-Fu (with notes)
 
Using npm to Manage Your Projects for Fun and Profit - USEFUL INFO IN NOTES!

What's hot (20)

PDF
Top Node.js Metrics to Watch
PDF
Couchdb w Ruby'm
PDF
Nagios Conference 2013 - Sheeri Cabral - Alerting With MySQL and Nagios
PDF
Gazelle - Plack Handler for performance freaks #yokohamapm
PDF
BlockChain implementation by python
PDF
HTTP For the Good or the Bad
PPTX
Web security
PPT
Top Ten Web Defenses - DefCamp 2012
PDF
MongoDB Performance Debugging
PPTX
Jmx capture
PDF
What is nodejs
ODP
Remove php calls and scale your site like crazy !
PPTX
Token Based Authentication Systems
PPTX
Django cryptography
PDF
2014 database - course 3 - PHP and MySQL
PDF
Riak at The NYC Cloud Computing Meetup Group
PDF
Node.js in action
PDF
Sometimes web sockets_dont_work
PPTX
Create online games with node.js and socket.io
PDF
How to get rid of terraform plan diffs
Top Node.js Metrics to Watch
Couchdb w Ruby'm
Nagios Conference 2013 - Sheeri Cabral - Alerting With MySQL and Nagios
Gazelle - Plack Handler for performance freaks #yokohamapm
BlockChain implementation by python
HTTP For the Good or the Bad
Web security
Top Ten Web Defenses - DefCamp 2012
MongoDB Performance Debugging
Jmx capture
What is nodejs
Remove php calls and scale your site like crazy !
Token Based Authentication Systems
Django cryptography
2014 database - course 3 - PHP and MySQL
Riak at The NYC Cloud Computing Meetup Group
Node.js in action
Sometimes web sockets_dont_work
Create online games with node.js and socket.io
How to get rid of terraform plan diffs

Similar to Cache is King - RubyHACK 2019 (20)

PDF
Scaling Twitter
PDF
Scaling Twitter 12758
PPTX
Clustrix Database Percona Ruby on Rails benchmark
PDF
Scaling Social Games
PDF
Intro to-rails-webperf
KEY
Rails services in the walled garden
PDF
Magic of Ruby
KEY
Perform Like a frAg Star
PPTX
Scalability at GROU.PS
PDF
Granular Archival and Nearline Storage Using MySQL, S3, and SQS
PDF
Memcached Study
PDF
MySQL Cluster Scaling to a Billion Queries
PDF
CouchDB
PDF
Getting Started with Couchbase Ruby
PDF
Apache CouchDB talk at Ontario GNU Linux Fest
PDF
Real World Caching with Ruby on Rails
PDF
Introduction to CouchDB
PPTX
Launch webinar-introducing couchbase server 2.0-01202013
ZIP
Memcached, presented to LCA2010
PPTX
Couchbase Overview - Monterey Bay Information Technologists Meetup 02.15.17
Scaling Twitter
Scaling Twitter 12758
Clustrix Database Percona Ruby on Rails benchmark
Scaling Social Games
Intro to-rails-webperf
Rails services in the walled garden
Magic of Ruby
Perform Like a frAg Star
Scalability at GROU.PS
Granular Archival and Nearline Storage Using MySQL, S3, and SQS
Memcached Study
MySQL Cluster Scaling to a Billion Queries
CouchDB
Getting Started with Couchbase Ruby
Apache CouchDB talk at Ontario GNU Linux Fest
Real World Caching with Ruby on Rails
Introduction to CouchDB
Launch webinar-introducing couchbase server 2.0-01202013
Memcached, presented to LCA2010
Couchbase Overview - Monterey Bay Information Technologists Meetup 02.15.17

More from Molly Struve (10)

PDF
LeadDev NYC 2022: Calling Out a Terrible On-call System
PDF
Talk Horsey to Me
PDF
Eight Timezones, One Cohesive Team
PDF
All Day DevOps: Calling Out A Terrible On-Call System
PDF
Talk Horsey To Me
PDF
Elasticsearch 5 and Bust (RubyConf 2019)
PDF
Creating a Scalable Monitoring System That Everyone Will Love ADDO
PDF
Creating a Scalable Monitoring System That Everyone Will Love (Velocity Conf)
PDF
Building a Scalable Monitoring System
PDF
Taking Elasticsearch From 0 to 88mph
LeadDev NYC 2022: Calling Out a Terrible On-call System
Talk Horsey to Me
Eight Timezones, One Cohesive Team
All Day DevOps: Calling Out A Terrible On-Call System
Talk Horsey To Me
Elasticsearch 5 and Bust (RubyConf 2019)
Creating a Scalable Monitoring System That Everyone Will Love ADDO
Creating a Scalable Monitoring System That Everyone Will Love (Velocity Conf)
Building a Scalable Monitoring System
Taking Elasticsearch From 0 to 88mph

Recently uploaded (20)

PDF
Embodied AI: Ushering in the Next Era of Intelligent Systems
PPTX
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
PPTX
Fundamentals of safety and accident prevention -final (1).pptx
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PPTX
UNIT-1 - COAL BASED THERMAL POWER PLANTS
PPT
Mechanical Engineering MATERIALS Selection
PDF
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
PDF
Automation-in-Manufacturing-Chapter-Introduction.pdf
PPTX
UNIT 4 Total Quality Management .pptx
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
PDF
Operating System & Kernel Study Guide-1 - converted.pdf
PDF
R24 SURVEYING LAB MANUAL for civil enggi
PDF
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PDF
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
DOCX
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
PPTX
bas. eng. economics group 4 presentation 1.pptx
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PDF
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
PDF
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
PPT
Project quality management in manufacturing
Embodied AI: Ushering in the Next Era of Intelligent Systems
M Tech Sem 1 Civil Engineering Environmental Sciences.pptx
Fundamentals of safety and accident prevention -final (1).pptx
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
UNIT-1 - COAL BASED THERMAL POWER PLANTS
Mechanical Engineering MATERIALS Selection
Unit I ESSENTIAL OF DIGITAL MARKETING.pdf
Automation-in-Manufacturing-Chapter-Introduction.pdf
UNIT 4 Total Quality Management .pptx
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Operating System & Kernel Study Guide-1 - converted.pdf
R24 SURVEYING LAB MANUAL for civil enggi
The CXO Playbook 2025 – Future-Ready Strategies for C-Suite Leaders Cerebrai...
PREDICTION OF DIABETES FROM ELECTRONIC HEALTH RECORDS
ASol_English-Language-Literature-Set-1-27-02-2023-converted.docx
bas. eng. economics group 4 presentation 1.pptx
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
Human-AI Collaboration: Balancing Agentic AI and Autonomy in Hybrid Systems
BMEC211 - INTRODUCTION TO MECHATRONICS-1.pdf
Project quality management in manufacturing

Cache is King - RubyHACK 2019