Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Inne aspekty Memcached & MySQL

Inne aspekty Memcached & MySQL

Presentation abstract:

Memcached and MySQL probably needs no introduction to anyone. They are working great standalone but together they can solve most of the performance issues related to the database layer. It should be noted that both projects complement each other perfectly well in other situations, far from typical caching of data.

In the first part of the presentation we will see HandlerSocket which introduces simplified and directe access to database table's storage engine, which can greatly improve performance of primary key seeks even up to several hundred thousand reads per second. HandlerSocket inspired the memcached API introduced in MySQL 5.6, that we will dicuss a bit more.

The second part will be focused on using MySQL to transfer data between memcached clusters in different locations. When scaling applications with different server room locations there is often a need to place in each of them local, consistent copy of data cache to provide fast and easy access to key data. On the example of Facebook architecture we will look at the problems of fault resistant method to solve this problem, which in addition can also be used in smaller projects, such as session data redundancy.

Abstrakt prezentacji:

Memcached i MySQL to rozwiązania, których chyba nie trzeba przedstawiać nikomu. Idealnie działają solo, a w typowym połączeniu potrafią skutecznie rozwiązać większość problemów wydajnościowych związanych z warstwą bazy danych. Warto jednak zwrócić uwagę, iż oba projekty świetnie uzupełniają się także w innych zastosowaniach, dalekich od typowego cache’owania danych.

W pierwszej części prezentacji poznamy m.in. rozwiązanie HandlerSocket, które wprowadza do bazy danych MySQL uproszczony i bezpośredni dostęp do storage-engine’u tabeli, co w konsekwencji pozwala osiągnąć ilość odczytów względem klucza głównego na poziomie kilkuset tysięcy operacji na sekundę. HandlerSocket stał się pierwowzorem wprowadzonego w MySQL 5.6 memcached API, którego możliwościom poświęcimy znacznie więcej uwagi.

Druga część skoncentrowana będzie na wykorzystaniu MySQL do przenoszenia danych pomiędzy klastrami memcached zlokalizowanych w odległych centrach danych.W przypadku skalowania aplikacji na poziomie osobnych serwerowni często zachodzi potrzeba umieszczenia w każdej z nich lokalnych, spójnych kopii danych cache, aby zapewnić szybki i łatwy dostęp do kluczowych danych. Na przykładzie zastosowanej przez Facebook architektury zapoznamy się pełni odporną na problemy metodą rozwiązania tego problemu, którą dodatkowo można zastosować także w mniejszych projektach, np. do redundancji danych sesyjnych.

Mariusz Gil

August 06, 2012
Tweet

More Decks by Mariusz Gil

Other Decks in Programming

Transcript

  1. Mariusz Gil, WebClusters 2012, Szczecin
    inne aspekty
    MEMCACHED&MySQL
    poniedziałek, 6 sierpnia 2012

    View Slide

  2. DEVELOPER, ARCHITEKT
    poniedziałek, 6 sierpnia 2012

    View Slide

  3. AGENDA
    o czym własciwie porozmawiamy
    poniedziałek, 6 sierpnia 2012

    View Slide

  4. MEMCACHED
    MySQL
    poniedziałek, 6 sierpnia 2012

    View Slide

  5. MEMCACHED
    MySQL
    poniedziałek, 6 sierpnia 2012

    View Slide

  6. memcached
    MySQL
    aplikacja
    poniedziałek, 6 sierpnia 2012

    View Slide

  7. function pobierz_dane(int userid) {
    /* Najpierw próba pobrania danych z cache */
    data = memcached_fetch("userrow:" + userid);
    if (!data) {
    /* Nie znaleziono wymaganych danych => pobranie danych
    z bazy danych, */
    data = db_select("SELECT * FROM users WHERE userid = ?", userid);
    /* następnie po pobraniu danych, przechowywanie ich w cache. */
    memcached_add("userrow:" + userid, data);
    }
    return data;
    }
    function aktualizuj_dane(int userid, string dbUpdateString) {
    /* Najpierw aktualizacja bazy danych */
    result = db_execute(dbUpdateString);
    if (result) {
    /* Aktualizacja bazy danych powiodła się => pobranie danych
    przechowywanych w bazie danych, */
    data = db_select("SELECT * FROM users WHERE userid = ?", userid);
    /* następnie wprowadzenie danych do pamięci podręcznej. */
    memcached_set("userrow:" + userid, data);
    /* ostatnia linia powinna wyglądać:
    //data = createDataFromDBString(dbUpdateString); */
    }
    }
    prosty przykład
    poniedziałek, 6 sierpnia 2012

    View Slide

  8. memcached i MySQL to nie tylko prosty cache
    poniedziałek, 6 sierpnia 2012

    View Slide

  9. FACEBOOK
    jak MySQL pomaga w spójnosci memcached
    `
    poniedziałek, 6 sierpnia 2012

    View Slide

  10. California data center
    MySQL master
    memcached
    poniedziałek, 6 sierpnia 2012

    View Slide

  11. California data center Virginia data center
    MySQL master
    memcached MySQL slave memcached
    replikacja
    poniedziałek, 6 sierpnia 2012

    View Slide

  12. California data center Virginia data center
    MySQL master
    memcached MySQL slave memcached
    aktualizacja
    profilu
    aktualizacja
    danych
    replikacja
    usuniecie
    danych
    usuniecie
    danych
    poniedziałek, 6 sierpnia 2012

    View Slide

  13. replikacja MySQL w czasie ponizej 1 sek
    okresowo nawet powyzej 20 sek
    `
    .
    .
    poniedziałek, 6 sierpnia 2012

    View Slide

  14. rozwiazanie?
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  15. replikacja
    MySQL
    cache
    CONSISTENCY
    multi DC
    MEMCACHED + =
    poniedziałek, 6 sierpnia 2012

    View Slide

  16. California data center Virginia data center
    MySQL master
    memcached MySQL slave memcached
    aktualizacja
    profilu
    aktualizacja
    danych
    replikacja rozszerzona
    o dane memcached
    usuniecie
    danych
    usuniecie
    danych
    aktualizacja
    danych
    poniedziałek, 6 sierpnia 2012

    View Slide

  17. MySQL master
    memcached
    MySQL slave memcached
    aktualizacja
    danych
    replikacja rozszerzona
    o dane memcached
    usuniecie
    danych
    danych
    aktualizacja
    danych
    query
    : statement END_OF_INPUT {}
    ;
    statement
    : alter
    | analyze
    | backup
    | call
    | insert
    | replace
    | select
    | update
    ...
    ;
    query
    : statement mc_dirty END_OF_INPUT {}
    ;
    mc_dirty
    :
    {}
    | MEMCACHE_DIRTY mc_key_list
    ;
    mc_key_list
    : mc_key_list ‘,’ text_string { Lex->mc_key_list.push_back($3); }
    | text_string { Lex->mc_key_list.push_back($1); }
    ;
    mysql_execute_command()
    poniedziałek, 6 sierpnia 2012

    View Slide

  18. alternative.to
    poniedziałek, 6 sierpnia 2012

    View Slide

  19. MySQL master
    tabela BlackHole
    binlog
    MySQL slave
    watek replikacji
    tabela BlackHole
    trigger
    memcached
    MySQL slave
    watek replikacji
    tabela BlackHole
    trigger
    memcached
    MySQL slave
    watek replikacji
    tabela BlackHole
    trigger
    memcached
    SET key foo 1 } zapis przez aplikacje lub
    memcached API
    GET key
    http://golanzakai.blogspot.com/2008/11/memcached-replication-and-namespaces.html
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  20. przydatne jako replikacja multi DC
    replikacja sesji
    ochrona przed hot keys
    poniedziałek, 6 sierpnia 2012

    View Slide

  21. HandlerSocket
    alternatywny dostep do danych MySQL
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  22. aplikacje duzej skali nie stosuja JOIN-ów
    a odczyt jest głównie wzgledem PK
    nawet kosztem redundancji danych
    .
    ,
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  23. DeNA HandlerSocket
    750.000qps
    poniedziałek, 6 sierpnia 2012

    View Slide

  24. mysql> CREATE TABLE t (
    id int(11) NOT NULL,
    col varchar(20) NOT NULL,
    PRIMARY KEY (id)
    ) ENGINE=InnoDB;
    dostep do tych
    samych danych
    $ telnet 127.0.0.1 9999
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    P 1 test t PRIMARY id col
    0 1
    1 + 2 1 test value
    0 1
    mysql> SELECT * FROM t;
    +----+------------+
    | id | col |
    +----+------------+
    | 1 | test value |
    +----+------------+
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  25. MySQL API
    dla złozonych
    zapytan
    HandlerSocket
    dla zapytan
    szybkich lub
    index scan
    wątek workera
    wątek na połączenie
    Akceptacja protokolu
    Parsowanie SQL
    Optymalizacja SQL
    Otwarcie tabel
    Query Plan
    Query Cache
    Dostep do danych
    Zamkniecie tabel
    Zwrócenie wyników
    Akceptacja protokołu
    Dostep do danych
    Zwrócenie wyników
    Storage
    Engine
    3306
    9998 9999
    InnoDB
    MyISAM
    ...
    .
    `
    `
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  26. handler
    SOCKET
    serwer
    MySQL + demon
    MEMCACHED
    serwer
    MySQL +

    poniedziałek, 6 sierpnia 2012

    View Slide

  27. PERCONA
    SERVER with XtraDB
    poniedziałek, 6 sierpnia 2012

    View Slide

  28. InnoDB
    implementacja protokołu memcached
    poniedziałek, 6 sierpnia 2012

    View Slide

  29. dostep do tych
    samych danych
    telnet localhost 11211
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    set mykey 0 0 14
    abcd|1234|WXYZ
    STORED
    get mykey
    VALUE mykey 0 14
    abcd|1234|WXYZ
    END
    mysql> SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT * FROM kvstore WHERE `key`="mykey";
    +-------+-------+-------+------+---------+------+------+
    | key | value | flags | cas | expires | val2 | val3 |
    +-------+-------+-------+------+---------+------+------+
    | mykey | abcd | 0 | 1 | 0 | 1234 | WXYZ |
    +-------+-------+-------+------+---------+------+------+
    1 row in set (0.00 sec)
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  30. InnoDB memcached internals
    poniedziałek, 6 sierpnia 2012

    View Slide

  31. InnoDB Storage Engine
    InnoDB API
    Handler API
    MySQL Server
    Memcached Plugin
    proces mysqld
    proces php/java/ruby
    Aplikacja
    protokół SQL protokół memcached
    innodb_memcache local cache
    poniedziałek, 6 sierpnia 2012

    View Slide

  32. definicja mapowania InnoDB / memcached
    polityki wykonań operacji
    SET/GET/DELETE/FLUSH
    opcje konfiguracyjne
    np. separator wartości
    poniedziałek, 6 sierpnia 2012

    View Slide

  33. ograniczenia? batchowy zapis zmian*
    mapowanie na jedna tabele
    ,
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  34. NDB Cluster
    implementacja protokołu memcached
    http://www.clusterdb.com/mysql-cluster/scalabale-persistent-ha-nosql-memcache-storage-using-mysql-cluster/
    poniedziałek, 6 sierpnia 2012

    View Slide

  35. memcached 1.6 engines
    poniedziałek, 6 sierpnia 2012

    View Slide

  36. Memcached Listener
    proces memcached
    proces php/java/ruby
    protokół memcached
    Memcached Driver dla NDB
    NDB API C++
    Aplikacja
    siec lokalna
    NDB data NDB data NDB data NDB data NDB data
    NDB Cluster
    poniedziałek, 6 sierpnia 2012

    View Slide

  37. proces memcached
    proces php/java/ruby
    Aplikacja
    NDB data NDB data NDB data NDB data NDB data
    NDB Cluster
    GET key_1 key_2
    NDB API
    GET key_1 key_3
    ndb-only cache
    poniedziałek, 6 sierpnia 2012

    View Slide

  38. dostep do tych
    samych danych
    mysql> CREATE DATABASE clusterdb;
    mysql> USE clusterdb;
    mysql> CREATE TABLE towns_tab (
    town VARCHAR(30) NOT NULL PRIMARY KEY,
    zip VARCHAR(10),
    population INT,
    county VARCHAR(10)
    ) ENGINE=NDB;
    mysql> INSERT INTO towns_tab VALUES ('Marlow', 'SL7', 14004, 'Berkshire');
    mysql> USE ndbmemcache;
    mysql> INSERT INTO containers VALUES ('towns_cnt', 'clusterdb',
    'towns_tab', 'town', 'zip', 0, NULL, NULL, NULL, NULL);
    mysql> INSERT INTO containers VALUES ('pop_cnt', 'clusterdb',
    'towns_tab', 'town', 'population', 0, NULL, NULL, NULL, NULL);
    mysql> SELECT * FROM containers;
    +------------+-------------+------------------+-------------+----------------
    | name | db_schema | db_table | key_columns | value_columns
    +------------+-------------+------------------+-------------+----------------
    | towns_cnt | clusterdb | towns_tab | town | zip
    | pop_cnt | clusterdb | towns_tab | town | population
    +------------+-------------+------------------+-------------+----------------
    mysql> INSERT INTO key_prefixes VALUES (1, 'twn_pr:', 0,
    'ndb-only', 'towns_cnt');
    mysql> INSERT INTO key_prefixes VALUES (1, 'pop_pr:', 0,
    'ndb-only', 'pop_cnt');
    mysql> SELECT * FROM key_prefixes;
    +----------------+------------+------------+---------------+------------+
    | server_role_id | key_prefix | cluster_id | policy | container |
    +----------------+------------+------------+---------------+------------+
    | 1 | pop_pr: | 0 | ndb-only | pop_cnt |
    | 1 | twn_pr: | 0 | ndb-only | towns_cnt |
    +----------------+------------+------------+---------------+------------+
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  39. dostep do tych
    samych danych
    memcached -E /usr/local/mysql/lib/ndb_engine.so
    -e "connectstring=localhost:1186;role=db-only"
    -vv
    -c 20
    Contacting primary management server (localhost:1186) ...
    Connected to "localhost:1186" as node id 51.
    Retrieved 2 key prefixes for server role "db-only".
    The default behavior is that:
    GET uses NDB only
    SET uses NDB only
    DELETE uses NDB only.
    The 2 explicitly defined key prefixes are
    "pop_pr:" (towns_tab),
    "twn_pr:" (towns_tab)
    telnet localhost 11211
    get twn_pr:Marlow
    VALUE twn_pr:Marlow 0 3
    SL7
    END
    set twn_pr:Maidenhead 0 0 3
    SL6
    STORED
    set pop_pr:Maidenhead 0 0 5
    42827
    STORED
    mysql> SELECT * FROM clusterdb.towns_tab;
    +------------+------+------------+-----------+
    | town | zip | population | county |
    +------------+------+------------+-----------+
    | Maidenhead | SL6 | 42827 | NULL |
    | Marlow | SL7 | 14004 | Berkshire |
    +------------+------+------------+-----------+
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide

  40. ograniczenia? limit rozmiaru wiersza NDB
    poniedziałek, 6 sierpnia 2012

    View Slide

  41. email: [email protected]
    twitter: @mariuszgil
    Dziekuje za uwage
    Pytania?
    ,
    ,
    poniedziałek, 6 sierpnia 2012

    View Slide