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
November 13, 2012
Programming
8
680
MongoDB for Analytics
Presented at MongoChicago on November 13, 2012.
John Nunemaker
PRO
November 13, 2012
Tweet
Share
More Decks by John Nunemaker
See All by John Nunemaker
Atom
jnunemaker
PRO
7
3.3k
Addicted to Stable
jnunemaker
PRO
32
2.1k
MongoDB for Analytics
jnunemaker
PRO
21
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.2k
Other Decks in Programming
See All in Programming
2024 コーディング研修
ckazu
2
570
Criando a Woovi em uma semana
daniloab
0
120
哲学史とモデリング
tanakahisateru
2
360
冗長なエラーログを削減し、スタックトレースを手に入れる / Reducing Verbose Error Logs and Obtaining Stack Traces
upamune
0
1.1k
Productivity is Messing Around and Having Fun
hollycummins
1
150
WebGLで始める コンピュータグラフィックス入門
heller77
0
360
チーム立ち上げにAWSを活用したらClaudeさんに褒められた話
mkdev10
2
190
AWS CDKコントリビュートTIPS / aws-cdk-contribution-tips
gotok365
4
590
初心者のためのRubyKaigi入門/RubyKaigi Introduction
a_matsuda
10
1.8k
Folding Cheat Sheet #4
philipschwarz
PRO
0
110
PHPはいつから死んでいるかの調査
chiroruxx
2
440
Compose-View Interop in Practice (mDevCamp 2024)
stewemetal
0
170
Featured
See All Featured
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
26
2.3k
The Art of Programming - Codeland 2020
erikaheidi
43
12k
Optimizing for Happiness
mojombo
370
69k
Debugging Ruby Performance
tmm1
70
11k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
358
22k
Build The Right Thing And Hit Your Dates
maggiecrowley
25
2k
Fontdeck: Realign not Redesign
paulrobertlloyd
76
4.9k
Building Effective Engineering Teams - LeadDev
addyosmani
33
1.9k
Building Flexible Design Systems
yeseniaperezcruz
320
37k
Raft: Consensus for Rubyists
vanstee
133
6.3k
Designing on Purpose - Digital PM Summit 2013
jponch
111
6.5k
Art, The Web, and Tiny UX
lynnandtonic
290
19k
Transcript
GitHub John Nunemaker MongoChicago 2012 November 12, 2012 MongoDB for
Analytics A loving conversation with @jnunemaker
Background How hernias can be good for you
None
None
1 month Of evenings and weekends
18 months Since public launch
10-15 Million Page views per day
2.7 Billion Page views to date
13 tiny servers 2 web, 6 app, 3 db, 2
queue
requests/sec
ops/sec
cpu %
lock %
Implementation How we do what we do
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
[ "content.2011.7", "content.2011.8", "content.2011.9", "content.2011.10", "content.2011.11", "content.2011.12", "content.2012.1", "content.2012.2", "content.2012.3",
"content.2012.4", ]
[ "resolutions.2011", "resolutions.2012", ]
Move
Move BigintMove
Move BigintMove MakeYouWannaMove
Move BigintMove MakeYouWannaMove DaMove
Move BigintMove MakeYouWannaMove DaMove SmoothMove
Move BigintMove MakeYouWannaMove DaMove SmoothMove NightMove
Move BigintMove MakeYouWannaMove DaMove SmoothMove NightMove DanceMove
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 MongoChicago 2012 November 12,
2012 @jnunemaker