Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
MongoDB for Analytics
Search
John Nunemaker
PRO
May 04, 2012
Programming
21
2.2k
MongoDB for Analytics
Presented at MongoSF on May 4th, 2012.
John Nunemaker
PRO
May 04, 2012
Tweet
Share
More Decks by John Nunemaker
See All by John Nunemaker
Atom
jnunemaker
PRO
7
3.3k
MongoDB for Analytics
jnunemaker
PRO
8
690
Addicted to Stable
jnunemaker
PRO
32
2.2k
MongoDB for Analytics
jnunemaker
PRO
16
29k
Why You Should Never Use an ORM
jnunemaker
PRO
51
8.7k
Why NoSQL?
jnunemaker
PRO
10
830
Don't Repeat Yourself, Repeat Others
jnunemaker
PRO
7
3.2k
I Have No Talent
jnunemaker
PRO
14
850
Why MongoDB Is Awesome
jnunemaker
PRO
18
4.3k
Other Decks in Programming
See All in Programming
The test code generator using static analysis and LLM
mikik0
1
550
ウォンテッドリーでのKMPワークフロー / KMP workflow at Wantedly
kubode
0
120
Using Ruby in the browser is wonderful
ledsun
1
1.6k
The rollercoaster of releasing an Android, iOS, and macOS app with Kotlin Multiplatform | KotlinConf
prof18
0
110
The Hotwire Landscape After Turbo 8 @ Helvetic Ruby 2024, Zurich
marcoroth
0
180
The Frontend Rubyist
largo
0
470
パッケージ開発論
e99h2121
1
300
Prepare for Jakarta EE 11 - Performance and Developer Productivity
ivargrimstad
0
760
Containerization Tips and Tricks for PHP apps
dunglas
2
3.3k
Navigating Generative AI: A Developer's Guide
alperhankendi
0
150
It’s about time to pack Ruby and Ruby scripts in one binary
ahogappa0613
1
1.3k
Module Harmony について
yosuke_furukawa
PRO
3
500
Featured
See All Featured
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
126
32k
Writing Fast Ruby
sferik
623
60k
A Tale of Four Properties
chriscoyier
153
22k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
34
6.1k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
323
20k
What's in a price? How to price your products and services
michaelherold
238
11k
Large-scale JavaScript Application Architecture
addyosmani
504
110k
The Cult of Friendly URLs
andyhume
74
5.7k
Six Lessons from altMBA
skipperchong
22
3.1k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
117
18k
Product Roadmaps are Hard
iamctodd
45
9.8k
Gamification - CAS2011
davidbonilla
77
4.6k
Transcript
GitHub John Nunemaker MongoSF 2012 May 4, 2012 MongoDB for
Analytics A loving conversation with @jnunemaker
None
Background How hernias can be good for you
None
None
1 month Of evenings and weekends
1 year Since public launch
13 tiny servers 2 web, 6 app, 3 db, 2
queue
7-8 Million Page views per day
None
None
None
None
Implementation Imma show you how we do what we do
baby
Doing It (mostly) Live No aggregate querying
None
None
get('/track.gif') do track_service.record(...) TrackGif end
class TrackService def record(attrs) message = MessagePack.pack(attrs) @client.set(@queue, message) end
end
class TrackProcessor def run loop { process } end def
process record @client.get(@queue) end def record(message) attrs = MessagePack.unpack(message) Hit.record(attrs) end end
http://bit.ly/rt-kestrel
class Hit def record site.atomic_update(site_updates) Resolution.record(self) Technology.record(self) Location.record(self) Referrer.record(self) Content.record(self)
Search.record(self) Notification.record(self) View.record(self) end end
class Resolution def record(hit) query = {'_id' => "..."} update
= {'$inc' => {}} update['$inc']["sx.#{hit.screenx}"] = 1 update['$inc']["bx.#{hit.browserx}"] = 1 update['$inc']["by.#{hit.browsery}"] = 1 collection(hit.created_on) .update(query, update, :upsert => true) end end end
Pros
Pros Space
Pros Space RAM
Pros Space RAM Reads
Pros Space RAM Reads Live
Cons
Cons Writes
Cons Writes Constraints
Cons Writes Constraints More Forethought
Cons Writes Constraints More Forethought No raw data
http://bit.ly/rt-counters http://bit.ly/rt-counters2
Time Frame Minute, hour, month, day, year, forever?
# of Variations One document vs many
Single Document Per Time Frame
None
{ "t" => 336381, "u" => 158951, "2011" => {
"02" => { "18" => { "t" => 9, "u" => 6 } } } }
{ '$inc' => { 't' => 1, 'u' => 1,
'2011.02.18.t' => 1, '2011.02.18.u' => 1, } }
Single Document For all ranges in time frame
None
{ "_id" =>"...:10", "bx" => { "320" => 85, "480"
=> 318, "800" => 1938, "1024" => 5033, "1280" => 6288, "1440" => 2323, "1600" => 3817, "2000" => 137 }, "by" => { "480" => 2205, "600" => 7359,
"600" => 7359, "768" => 4515, "900" => 3833, "1024"
=> 2026 }, "sx" => { "320" => 191, "480" => 179, "800" => 195, "1024" => 1059, "1280" => 5861, "1440" => 3533, "1600" => 7675, "2000" => 1279 } }
{ '$inc' => { 'sx.1440' => 1, 'bx.1280' => 1,
'by.768' => 1, } }
Many Documents Search terms, content, referrers...
None
[ { "_id" => "<oid>:<hash>", "t" => "ruby class variables",
"sid" => BSON::ObjectId('<oid>'), "v" => 352 }, { "_id" => "<oid>:<hash>", "t" => "ruby unless", "sid" => BSON::ObjectId('<oid>'), "v" => 347 }, ]
Writes {'_id' => "#{sid}:#{hash}"}
Reads [['sid', 1], ['v', -1]]
Growth Don’t say shard, don’t say shard...
Partition Hot Data Currently using collections for time frames
Bigger, Faster Server More CPU, RAM, Disk Space
Users Sites Content Referrers Terms Engines Resolutions Locations Users Sites
Content Referrers Terms Engines Resolutions Locations
Partition by Function Spread writes across a few servers
Users Sites Content Referrers Terms Engines Resolutions Locations
Partition by Server Spread writes across a ton of servers,
way down the road, not worried yet
GitHub Thank you!
[email protected]
John Nunemaker MongoSF 2012 May 4,
2012 @jnunemaker