developer.studivz.net where the VZ developers blog

Archive for the ‘Database’ Category

Apache Hadoop Get Together Berlin

with one comment

We would like to announce the December-2009 Hadoop Get Together in newthinking store Berlin.

When: 16. December 2009 at 5:00pm
Where: newthinking store, Tucholskystr. 48, Berlin, Germany

As always there will be slots of 20min each for talks on your Hadoop topic. After each talk there will be a lot time to discuss. You can order drinks directly at the bar in the newthinking store. If you like, you can order pizza. We will go to Cafe Aufsturz after the event for some beer and something to eat.

Talks scheduled so far:

Richard Hutton (nugg.ad): “Moving from five days to one hour.” – This talk explains how we made data processing scalable at nugg.ad. The company’s core business is online advertisement targeting. Our servers receive 10,000 requests per second resulting in data of 100GB per day.

As the classical data warehouse solution reached its limit, we moved to a framework built on top of Hadoop to make analytics speedy, data mining detailed and all of our lives easier. We will give an overview of our solution involving file system structures, scheduling, messaging and programming languages from the future.

Jörg Möllenkamp (Sun): “Hadoop on Sun”
Abstract: Hadoop is a well known technology inside of Sun. This talk want to show some interesting use cases of Hadoop in conjunction with Sun technologies. The first show case wants to demonstrate how Hadoop can used to load massive multicore system with up to 256 threads in a single system to the max. The second use case shows how several mechanisms integrated in Solaris can ease the deployment and operation of Hadoop even in non-dedicated environments. The last usecase will show the combination of the Sun Grid Engine and Hadoop. Talk may contain command-line demonstrations ;).

Nikolaus Pohle (nurago): “M/R for MR – Online Market Research powered by Apache Hadoop. Enable consultants to analyze online behavior for audience segmentation, advertising effects and usage patterns.”

We would like to invite you, the visitor to also tell your Hadoop story, if you like, you can bring slides – there will be a beamer. Thanks for Isabel Drost who is organizing this event and for Newthinking Store for providing Space. VZnet Netzwerke is sponsoring the video recording of the talks.

Registration:

  • http://upcoming.yahoo.com/event/4842528/
  • https://www.xing.com/events/apache-hadoop-berlin-426025
  • Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • VZ
    • Digg
    • del.icio.us
    • Google Bookmarks
    • Technorati
    • TwitThis

    Written by nils November 11th, 2009 at 6:02 pm.


    Posted in Database, Operations

    Tags:

    N✮SQL Berlin Roundup

    with one comment

    Key-value-stores and other non-relational databases are a hot topic right now, as it increasingly turns out that the traditional (= relational) approach is difficult to scale horizontally. In other words, it may be time — as Bob Ippolito put it — to “Drop ACID and think about data”.

    If you couldn’t make it to the first “NoSQL Meetup Berlin” which recently took place at newthinking store — all the talks have been recorded and are on vimeo now:

    Heise has a good summary (in german).

    Here at StudiVZ we are following this topic very closely and are actively investigating some of the alternatives. At the moment, Cassandra looks very promising to us.

    Some more links:

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • VZ
    • Digg
    • del.icio.us
    • Google Bookmarks
    • Technorati
    • TwitThis

    Memcache Feeds

    with 13 comments

    Buschfunk, die Möglichkeit die Statusnachrichten (”Ist gerade…”) deiner Freunde auf unseren VZ’s anzuzeigen, ist nun/nur der Beginn der VZ Feeds. Letzlich ist der Buschfunk nur die Zusammenführung aller Statusnachrichten deiner Freunde auf der Startseite.

    Nach dem Launch der ersten Version des Buschfunks, gab es bereits wenige Minuten später einen riesigen Impakt auf unserer Serverfarm. Dies führte dazu, dass wir bereits nach einem Tag die Statusnachrichtendatenbank auf eigene Server umziehen mussten. Ihr seht hier die absolute Anzahl von Statusaktualisierungen pro Minute (getrennt nach studiVZ/meinVZ = blau/flacher Graph und schuelerVZ = rot/steiler Graph):

    zugriffe_mb2

    Man kann Feeds, also Mitteilungen über Statusaktualisierungen eines Freundes, unterschiedlich implementieren und stellt sich dabei einigen Herausforderungen, gerade wenn es nicht nur um die optimale Speicherung, sondern auch um performante Zugriffe und logisches Zusammenführen von ähnlichen Feedeinträgen geht.

    Wir haben uns für erste Tests in Richtung Social-Feeds für eine reine Memcache-Implementierung entschieden. Man hat den Vorteil, dass man die ohnehin nur momentan interessanten Posts von Usern nicht in der Datenbank vorhalten muss und Memcacheoperationen dazu noch um einiges schneller sind. Für einen Feed baut man sich im einfachsten Fall eine Queue pro User mit sortierten Einträgen auf, die man als Entity im Memcache ablegt. Da man nicht unendlich viele Einträge vorhalten muss und ein Memcacheobjekt per default eh nur 1 MB pro Eintrag groß sein darf, limitiert man die Queue auf eine feste Anzahl und wirft bei einem neuen Eintrag einfach alte Einträge weg.

    Ok, genug der Einleitung, kommen wir zu ein paar Codeschnippseln. Am besten baut man sich ein Interface, welches sich um das Handling von Feedeinträgen kümmert:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    interface FeedEntry {
     
    //referenziertes Memcacheobject, also eigentlicher Inhalt
    public function getFeedEntryReference(...);
     
    //ist der Eintrag sichtbar -> Privacy
    public function isFeedEntryHidden(...);
     
    //initialer Aufbau
    public function initializeFeedEntry(...);
     
    [...]
     
    }

    Jetzt haben wir einen beliebig erweiterbaren Feed Typen und können mit Implementierungen, wie zum Beispiel Statusänderungen von Nutzerprofilen, Microblogeinträgen etc, beginnen.

    Was man jetzt noch braucht, ist das eigentliche Aufbauen der Queue, also Füllen des Feeds mit Feed Typen. Man sollte sich überlegen, woraus ein Eintrag innerhalb der Queue aussehen soll. Es sollte die id des Users, einen Zeitstempel, sowie den eigentlichen Inhalt enthalten. Wir haben uns dafür entschieden, den Inhalt des Eintrages nur als Referenz in der Queue zu halten, damit bei Änderungen nicht jedes Queueobjekt, sondern lediglich das referenzierte Memcacheobjekt geändert werden muss. Ausserdem will man die Daten nicht doppelt im Speicher halten.

    Beispielhaft könnte eine vereinfachte Queue folgendermaßen aussehen:

    1
    2
    3
    4
    5
    
    $queue = array(
    0 => array ('timestamp' => time(), 'userId' => 123456789, 'contentId' => 1000, 'type' => TYPE_MICROBLOG),
    1 => array ('timestamp' => time(), 'userId' => 1234567910, 'contentId' => 1001, 'type'  => TYPE_PHOTOCOMMENT)
    [...]
    );

    Mit Hilfe des Typs und dessen konkreter Implementierung eines Feed Entries kann nun der eigentliche Inhalt aus einem weiteren Memcacheobjekt oder aus der Datenbank geholt werden. Sortiert ist die Queue bereits nach dem Einfügen eines neuen Entries. Wird nun der Content hinter einer solchen Referenz gelöscht, so braucht man die Queues der User, dessen Feeds beeinflusst werden, nicht updaten, da der Feed beim Einlesen automatisch merkt, dass die Referenz nicht mehr gültig ist und diese “überspringt”.

    Für’s Aufbauen der Queue noch ein Tipp: Verwendet lieber mehrmaliges array_reverse im Zusammenhang mit array_push, anstatt ein array_shift! Das ist um Welten schneller, wenn man ein Element vorn ranhängt bzw. hinten anfügt.

    (Quelle: http://www.ingo-schramm.de/blog/archives/9-PHP-array_shift-does-not-scale.html)

    Da der Memcache, wenn der ihm zugewiesene Speicher vollläuft, wenig frequentierte Bereiche freigibt, muss man sich zwangsweise überlegen, wie man mit Datenverlusten innerhalb der Queue umgeht. Dazu könnte man zyklische Backups der Queueeinträge oder ein initiales Befüllen der Feedeinträge implementieren (im Interface bereits vorgesehen). Die eigentlichen Daten (bsp. das konkrete Statusupdate) bleiben natürlich erhalten und liegen in der Datenbank persistent vor, es geht hierbei nur um die Referenzen auf diese Einträge.

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • VZ
    • Digg
    • del.icio.us
    • Google Bookmarks
    • Technorati
    • TwitThis

    MySQL DBA Tools

    without comments

    Als MySQL Datenbankadministrator ist man täglich damit beschäftigt, unzählige Datenbank-Server am Laufen zu halten. Hier eine Auswahl an Werkzeugen, die man unbedingt in der täglichen Arbeit braucht:

    Aus Maatkit eignet sich mk-query-digest besonders gut, um ein System nach einem Neustart der Datenbank “aufzuwärmen”.

    mk-query-digest --processlist h=d-mm-05-1-svz --execute h=d-mm-05-2-svz \
       --filter '$event->{fingerprint} =~ m/^select/

    Außerdem kann man damit sehr elegant an einem Zweitsystem verschiedene Dinge testen und die Auswirkungen direkt beobachten.
    Es bietet sich dazu an, dass man sein System damit immer genau im Blick hat:

    • Ganglia (Distributiertes Grid Monitoring)

    ganglia-view

    Ganglia ist eine Allzweckwaffe, um ein Gefühl dafür zu bekommen, wie eine Datenbank “lebt”. Es visualisiert quasi den Herzschlag des Systems. Durch gmetric bekommt man zudem die Möglichkeit mit wenig Aufwand alle möglichen Parameter vom System oder der Datenbank an Ganglia zu übergeben und damit zu visualisieren. Basics dabei sind die Queries per Second, Slave Lag und Slow Queries per Second.

    • iostat -x

    Was ist auf meinen Platten los? Wie verteilt sich das await auf die einzelnen Devices? Viel sieht man damit leider nicht, aber es gibt deswegen Erweiterungen für MySQL, die das IO bis auf Tabellen und Indizes runterbrechen können.

    • Nagios – damit man den Fehler auch mitbekommt

    Kristian Köhntopp hat dafür was Nettes gebaut. Man braucht an der Stelle also nicht mehr ganz so viel tun.

    Nicht zu vergessen der Kommandozeilenclient mysql mit einem ordentlichen Prompt, damit man nicht bei mehreren Maschinen durcheinander kommt:

    [mysql]
    prompt = \u@hostname[\d]>\_

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • VZ
    • Digg
    • del.icio.us
    • Google Bookmarks
    • Technorati
    • TwitThis

    MySQL und INNODB_IO_PATTERN

    without comments

    logo_mysql_sun_aPercona ist ein Consultingunternehmen für MySQL und hilft als remote DBA, bei Architekturplanungen, Trouble Shooting und Database Recovery. Percona wurde 2006 von Peter Zaitsev und Vadim Tkachenko gegründet.

    Seit einiger Zeit nutzen wir auf unserer Plattform die MySQL-Version von Percona, weil es unheimlich praktische Patches gibt, die uns als DBA das Leben erleichtern.

    • Session status to check fragmentation of the last InnoDB scan
    • SHOW USER/TABLE/INDEX statistics
    • SHOW PATCHES
    • Adds additional information of InnoDB internal hash table memories in SHOW INNODB STATUS
    • Information schema table of InnoDB IO counts for each datafile pages
    • Adds INFOMATION_SCHEMA.PROCESSLIST with TIME_MS column
    • Add locks held, remove locked records in SHOW INNODB STATUS
    • Extended statistics in slow.log
    • Patch allows redirect output of error.log to syslog-ng
    • Information of fsync callers in InnoDB
    • Show innodb buffer pool content

    Mit show index_statistics sieht man z.B. sehr gut, wieviele Rows durch welchen Index gelesen wurden. Ideal, um nicht benutzte Indizes aufzuspüren.
    Natürlich will man auch wissen, wie sich die IO auf einzelne Tabellen und Indizes verteilt. Dafür gibt es dann im Information-Schema die Tabelle INNODB_IO_PATTERN:

    $ describe INNODB_IO_PATTERN;
    +------------+-------------+------+-----+---------+-------+
    | Field      | Type        | Null | Key | Default | Extra |
    +------------+-------------+------+-----+---------+-------+
    | SPACE      | bigint(11)  | NO   |     | 0       |       |
    | OFFSET     | bigint(11)  | NO   |     | 0       |       |
    | INDEX_ID   | bigint(11)  | NO   |     | 0       |       |
    | TABLE_NAME | varchar(32) | NO   |     | NULL    |       |
    | INDEX_NAME | varchar(32) | NO   |     | NULL    |       |
    | N_READ     | bigint(11)  | NO   |     | 0       |       |
    | N_WRITE    | bigint(11)  | NO   |     | 0       |       |
    +------------+-------------+------+-----+---------+-------+
    7 rows in set (0.01 sec)
     

    Bevor man Auswertungen starten kann, muss MySQL erstmal Daten sammeln:

    $ set global innodb_io_pattern_trace = 1;
    $ set global innodb_io_pattern_trace_running = 1;
    $ set global innodb_io_pattern_trace_size_limit = 1;
    -- Anzahl der Pages die gesammelt werden sollen

    Man muss auch unbedingt darauf achten, dass man genug freien Hauptspeicher hat, bevor man das Tracing startet.
    Auswertung des IO für jeden Index, getrennt nach Read und Write:

    $ select sum(i.n_read) n_read, sum(i.n_write) n_write, index_name, table_name from information_schema.innodb_io_pattern i group by index_id

    Dokumenation, Sourcen und Binaries finden sich im Wiki von Percona. Großes Lob also an die verschiedenen Entwickler, die dafür sorgen, dass auch die Datenbanken bei studiVZ unheimlich gut performen. Hier aus unserem Grid Monitoring die aggregierte Datenbanklast in Queries pro Sekunden:

    qps1

    Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
    • VZ
    • Digg
    • del.icio.us
    • Google Bookmarks
    • Technorati
    • TwitThis