13. Was brauchen wir?
KÜNSTLER Name, City, Genre, Bild
SOCIAL PROFILE Plattform (z.B. twitter), Link
MEDIA POSTS Bilder, Videos, Audios, Statusmeldungen
PROFIL INFO Freunde, Follower, Datum, Webseiten,
Pro lbild, Biographie, Label, etc.
14. MySQL Schema
Artist
id
name
Indexs
name
Numbers
artist
socialprofile
outgoing Socialprofile artist_genres
incoming id artist
feedback artist genre
push url Indexes
Service Informations Twitter
artist Indexes service artist_genre
lang, artist_outgoing Indexes
verified artist_incoming artists_service
location, artist_feedback
id, artist_push
url, artist
created_at,
description, Stream
time_zone, artist Genres
profile_image_url, socialprofile id
screen_name Service Informations Facebook message name
Indexes artist created_at Indexes
artist category, Indexes name
name, message
fan_count, artist_created_at
Service Informations Myspace bio, created_at
artist url,
website, username,
genre, record_label,
location, location,
art_des_labels, profile_image_url, Stream Informations Facebook
Stream Informations Twitter
headline, band_members, stream Stream Informations Myspace
stream
created_at website, name, stream
source,
id, ink, caption, category,
in_reply_to_status_id,
profile_image_url, pinnwand_posts, link, image,
in_reply_to_user_id,
label genre, likes, link,
truncated,
Indexes friends, type, source
deleted
artist id icon Indexes
Indexes
Indexes Indexes stream
stream
artist stream
15. MongoDB Schema
Artist
id (Object Id)
name (str)
genres (strict array)
socialprofiles (strict array)
service (dbref)
url (str)
numbers (strict array)
incoming
outgoing
push
feedback
date
meta (array)
(unterschiedliche Felder, ja nach Plattform)
Indexes
name,
genres,
socialprofiles.service,
socialprofiles.numbers
Stream
id (Hash aus facebook / myspace / twitter id)
socialprofile (dbref)
genres (strict array) (redundanz der genres vom
artists um den stream direkt über genres
abzufragen)
data (array)
( data from plattforms,
field message is a must have)
created_at (datetime)
Indexes
socialprofile,
genres,
data.message
16. Wie kommen wir an die Daten? (Einfach)
Crawler musweet
• Verarbeitung von Links Links • Darstellung der Inhalte
• Extraktion von Medien • Zuordnung Artist / Service
• Aufbereitung der Inhalte
Daten
24. MySQL vs. MongoDB (1)
Alle Social Media Pro le mit Follower-Zahlen von einem Artist
MySQL MongoDB
SELECT db.artist.find( { "name": "Snoop Dogg" } )
n.incoming,
a.id as artist,
a.name as artist_name, Dauer: 0.0001 Sek.
s.id as socialprofile,
s.url as socialprofile_url,
FROM
numbers as n
JOIN socialprofile as s on s.id =
n.socialprofile
JOIN artist as a on a.id = n.artist
WHERE
a.name = "Snoop Dogg"
ORDER n.incoming DESC
Dauer: 0.0288 Sek.
25. MySQL vs. MongoDB (2)
10 HipHop Musiker mit den meisten Followern
MySQL MongoDB
SELECT db.artist.find( {
n.incoming, "genre": DBRef("genre","hiphop")
a.id as artist, } ).sort( {
a.name as artist_name, "socialprofiles.numbers.incoming": -1
s.id as socialprofile, } ).limit(10)
s.url as socialprofile_url,
FROM
Dauer: 0.0230 Sek.
numbers as n
JOIN artist_genres as ag on
ag.artists = n.artist
JOIN genres as g on g.id = ag.genre
JOIN socialprofile as s on s.id =
n.socialprofile
JOIN artist as a on a.id = n.artist
WHERE
g.name = "Hip/Hop"
ORDER BY
n.incoming DESC
LIMIT 10
Dauer: 0.8741 Sek.
26. MySQL Index
• Index wird von links nach rechts gelesen
Reihenfolge wichtig
Felder: „artist“, „incoming“, „push“, „date“
SELECT * FROM numbers WHERE artist = 1 Funktioniert
SELECT * FROM numbers WHERE incoming = 1 Funktioniert nicht
SELECT * FROM numbers WHERE artist = 1 AND push < 10 Funktioniert nicht
SELECT * FROM numbers WHERE artist = 1 AND push < 10 AND incoming > 0 Funktioniert
• Index Debugging
EXPLAIN SELECT * FROM numbers WHERE artist = 1
27. MongoDB Index
• Index Reihenfolge ist egal
kann ein Feld mitten im Index verwenden
db.artist.ensureIndex( {"name":1, "numbers": -1 } );
db.artist.find( { "name": "Snoop Dog" } ) Funktioniert
db.artist.find( { "socialprofiles.numbers.incoming": { "$gte": 10 } } ) Funktioniert
db.artist.find( {
"name": "Snoop Dogg",
"socialprofiles.numbers.incoming": { "$gte": 0 }
} ) Funktioniert
• Index Debugging
db.artist.find( { "name": "Snoop Dogg" } ).explain()
30. MongoDB Fehlermeldungen
• Sortierte Abfrage ohne Limit:
Fehler: „too much data for sort() with no index. add an index or
specify a smaller limit“
Lösung: Feld in den Index aufnehmen
• Duplicate Key Error:
Fehler: in älteren Versionen (< 1.6.0) schmiert DB bei zu vielen
Duplicate Key Errors ab
Lösung: Upsert verwenden
31. db.serverStatus()
Wieviel memory-Verbrauch, wieviele Connections, ...
globalLock Wie lange Collections gesperrt waren, ...
connections Wieviel Verbindungen offen / verfügbar, ...
backgroundFlushing Wann war der letzte Flush auf die Festplatte, ...
... Mehr Info in der Dokumentation:
http://www.mongodb.org/display/DOCS/Monitoring+and+Diagnostics
32. Pro ling
db.setPro lingLevel(0) off
log slow operations (>100ms), optional „slow“
db.setPro lingLevel(1)
de nieren mit db.setPro lingLevel(1, 10)
db.setPro lingLevel(2) log all operations
system.pro le
{ "ts" : "Tue Aug 10 2010 00:25:33 GMT+0200 (CEST)", "info" : "update musweet.media query:
{ _id: ObjId(4c607ef2a68299079400b5ea) } nscanned:1 moved ", "millis" : 0 }
{ "ts" : "Tue Aug 10 2010 00:25:33 GMT+0200 (CEST)", "info" : "update musweet.media query:
{ _id: ObjId(4c607ef2a68299079400b468) } nscanned:1 moved ", "millis" : 0 }
{ "ts" : "Tue Aug 10 2010 00:25:33 GMT+0200 (CEST)", "info" : "update musweet.media query:
{ _id: ObjId(4c607fd9a68299079400c067) } nscanned:1", "millis" : 0 }
{ "ts" : "Tue Aug 10 2010 00:25:33 GMT+0200 (CEST)", "info" : "update musweet.media query:
{ _id: ObjId(4c607ef2a68299079400b6a6) } nscanned:1 moved ", "millis" : 0 }
36. Abschließend...
• Fragen?
• Mehr über uns:
http://compuccino.com
http://facebook.com/compuccino
• Personen:
Grischa Andreew, @grischaandreew
Nader Cserny, @nadr
Notas do Editor
Erweiterbarkeit und Handling von gro&#xDF;en Datenmengen im Rahmen unseres Projekts musweet.com
Was ist musweet?
Warum wir uns f&#xFC;r MongoDB entschieden haben
Vergleich zw. dem alten System mit MySQL u. MongoDB
Interessante Abfragen
Welche Tools & Debugging Methoden wir verwenden
Website rund um Musik und deren Akteure im Social Web
misst und bewertet Online-Aktivit&#xE4;t in Echtzeit
analysiert Datenquellen und stellt diese dar
zeigt Fotos, Musik, Videos von Bands u. Musikern
Erfahrungen von wahl.de mit MySQL jetzt mit MongoDB bei musweet.com umgesetzt
Media Stream mit Link Expander (=Enthaltene Medien werden direkt auf der Seite dargestellt)
Aktuell crawlen wir myspace, facebook, twitter -> sp&#xE4;ter erweiterung auf blogs, youtube
Stream nach Genre filterbar
Meist diskutierte Themen der letzten 7 Tage
Wer hat die meisten Freunde dazugewonnen (Big Mover)
Wer die meisten Nachrichten geschrieben (Big Shaker)
Filterbar nach Genre
Tagesaktuell
Stamminformationen eines K&#xFC;nstlers
Social Media Profile => Wo bewegt sich der Musiker im Netz
Media Stream vom Musiker
Zuk&#xFC;nftige Konzerte
Related Artists: &#xE4;hnliche im Genre und &#xE4;hnliche Kontaktzahlen
Wachsende Datenbasis
Aktivit&#xE4;t aus dem Social Web verlangt hohe Performance bei den Inserts
Erstmal mit bekannten K&#xFC;nstlern gestartet, sp&#xE4;ter Erweiterung
Wir haben K&#xFC;nstler mit versch. Social Profiles die jeweils wieder unterschiedliche Profile / Stream Informationen haben
der Stream / die Profileinformationen sollen nach den Attributen (genres,..) vom K&#xFC;nstler sortierbar sein
F&#xFC;r jeden weiteren Service brauchen wir zwei Tabellen ( Profileinformation, Stream ) mehr, f&#xFC;r jedes weitere Attribut beim K&#xFC;nstler / Scoialprofile was mehrdimensional sein soll brauchen wir eine Join und einen Daten Tabelle ( artist -> artists_genres -> genres ).
Durch die vielen Tabellen ist es nicht einfach die Daten abzufragen / jede &#xC4;nderung muss im Backend und im Frontend implementiert werden
Drastisch reduziertes Schema m&#xF6;glich
Neues Attribut erfordert nur einen neuen Eintrag im Objekt (ohne dass man an die DB ran muss)
die &#xC4;nderungen werden im Backend implementiert, das Frontend muss nicht ge&#xE4;ndert werden.
Crawler ist eine eigenst&#xE4;ndige Application und verwaltet die Crawls f&#xFC;r mehrere Client-Apps wie musweet.com.
musweet.com registriert die Socialprofiles im Crawler und bekommt eine Push Notfication wenn sich ein Profil &#xE4;ndert oder eine neue Nachricht geschrieben wird.
numbers Object ist festgesetzt und immer gleich aufgebaut
meta Object ist mit plattformspezifischen Daten gef&#xFC;llt.
Bei Twitter haben wir andere Infos als bei Myspace
&#x201E;profile_image_url&#x201C; bezeichnet das Profil-Bild des K&#xFC;nstlers auf der Plattform.
Bei Facebook haben wir meist mehr Informationen als bei den anderen Plattformen, je nach Facebook Account Type (Fanpage/User Profile)
MySQL: entweder mit JOIN oder 3 SELECTs
MongoDB Abfragen gestalten sich viel einfacher und performanter
MySQL: Noch mehr JOINs oder SELECT statements
MongoDB mit DBRef auf Genre
Viele unterschiedliche Indizes notwendig => viele GB an Daten
Indizes platzsparender und einfacher anwendbar
MongoDB kann in einem Index nur einen multiindex (Array als Daten) haben
Fehlermeldungen die wir w&#xE4;hrend der Entwicklung hatten
Fehler &#x201E;too much data for sort()&#x201C; tritt erst sp&#xE4;ter auf, wenn man viele Daten in der DB hat
globalLock: wie lange gesperrt
mem: wieviel Speicher verbraucht wird
IndexCounters: wieviele Hits, wieviele Misses
connections: wieviele offen, wieviele verf&#xFC;gbar
opcounters: wieviel inserts, updates, deletes
backgroundFlushing: wann war der letzte Flush
langsame Datenbank-Abfragen oder alle Abfragen
Profiling auf Datenbank-Ebene
N&#xFC;tzliches Tool um herauszufinden wieviele unterschiedliche Objekt Strukturen man in der Collection hat und deren Aufbau zu sehen.