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
9
730
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
8
3.3k
Addicted to Stable
jnunemaker
PRO
32
2.2k
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.9k
Why NoSQL?
jnunemaker
PRO
10
850
Don't Repeat Yourself, Repeat Others
jnunemaker
PRO
7
3.2k
I Have No Talent
jnunemaker
PRO
14
880
Why MongoDB Is Awesome
jnunemaker
PRO
18
4.3k
Other Decks in Programming
See All in Programming
GraphQL はいいぞ! ~Laravel で学ぶ GraphQL 入門~
azuki
1
160
DynamoDB コスト最適化っぽいことの基本 with Terraform
kuro_kurorrr
2
250
日付と正規化
megmogmog1965
0
140
Advanced App Shrinking Techniques
cbeyls
2
150
Polarsの成長: v0.14からv1.0までの変遷と今後の展望
zerebom
1
350
ピグパーティにおけるMongoDB CommunityバージョンからAtlasへの移行事例
10969hotaka
0
130
CSC307 Lecture 14
javiergs
PRO
0
220
最古の関数型言語「Lisp」ことはじめ / lisp_in_kamiyama
uhooi
1
190
なぜ宣言的 UI は壊れにくいのか / Why declarative UI is less fragile
uenitty
29
13k
SDCon2024: Enabling DevOps and Team Topologies thru architecture: architecting for fast flow
cer
PRO
0
780
Harnessing Large Language Models for Training-free Video Anomaly Detection
tereka114
1
1.3k
CSC307 Lecture 06
javiergs
PRO
0
360
Featured
See All Featured
Creatively Recalculating Your Daily Design Routine
revolveconf
214
11k
The Brand Is Dead. Long Live the Brand.
mthomps
52
36k
Optimizing for Happiness
mojombo
373
69k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
26
1.8k
The Power of CSS Pseudo Elements
geoffreycrofte
64
5.2k
VelocityConf: Rendering Performance Case Studies
addyosmani
321
23k
Fontdeck: Realign not Redesign
paulrobertlloyd
79
5.1k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
129
32k
Gamification - CAS2011
davidbonilla
78
4.9k
What’s in a name? Adding method to the madness
productmarketing
PRO
21
2.9k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
502
140k
Learning to Love Humans: Emotional Interface Design
aarron
269
39k
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