Pull to refresh
0
0

User

Send message

Memcached, PHP, Ketama. Если нет, но очень хочется.

Reading time 7 min
Views 1.4K
Хочется.
Кетаму в PHP, да еще чтобы хоть из чего доступ был.
Это я про не PHP. В смысле про доступ. Ну и из PHP тоже.

Ну ладно, приступим.
Что имеем.
Инет, Google …
… все :(
Аааа, чуть не забыл. Самое главное. Потолок, чтобы было куда тупо уставиться.

Итак гуглим.
В PHP кетама нет. А где есть то.
Гы, на last.fm.
www.lastfm.ru/user/RJ/journal/2007/04/10/rz_libketama_-_a_consistent_hashing_algo_for_memcache_clients
Вот только после 10 апреля 2007 версию 0.1.1 никто не обновлял, да и набор функционала какой-то куцый. На danga. com вон уже gets’ы, cas’ы и т.п. дребедени полно. Мож оно и можно, да вот только разбираться влом.

Гуглим дальше …
tangent.org

Что имеем.
Memcached Functions for MySQL
libmemcached 0.23

WOW!!!!
Clients using the library:
Ruby: github.com/fauna/memcached/tree/master
Perl: code.google.com/p/perl-libmemcached
Python: code.google.com/p/python-libmemcached
PHP: (In Japanese) labs.gree.jp/Top/OpenSource/libmemcached.html

Идем туда где PHP.
КАРАУЛ!!! Шалашики.
Блин и версия 0.1.0. Зато свежая, от 18.09.2008. Короче глюки в ней еще не исправлены, потому что никто их поискать не успел.
… все.
Больше нету ничего.

Ну что, будем пробовать.
Наверное с шалашиков лучше не начинать.
Хоть у меня по буржуйски весь словарный запас это: hi, yes, no, problem, thank и все.
… ну не все конечно, есть еще fuck, но он мне не поможет.
По японски он всяко короче.

Ставлю libmemcached и Memcached Functions for MySQL на сервер БД. На вебсервер libmemcached.
Поднимаю четырех демонов memcached. Одного на вебсервере, трех на сервере БД. Почему? А фиг его знает, так получилось.
Инсталлирую функции.

Хм, список впечатляет
memc_add
memc_add_by_key
memc_servers_set
memc_server_count
memc_set
memc_set_by_key
memc_cas
memc_cas_by_key
memc_get
memc_get_by_key
memc_delete
memc_delete_by_key
memc_append
memc_append_by_key
memc_prepend
memc_prepend_by_key
memc_increment
memc_decrement
memc_replace
memc_replace_by_key
memc_servers_behavior_set
memc_udf_version
memc_list_behaviors
memc_stats
memc_stat_get_keys
memc_stat_get_value

Не понял. Если есть cas? Где gets? На кой мне сдался cas без gets’а!!!
Ладно, мы им это припомним. Наверное.

Определяем сервера
SELECT memc_servers_set(‘192.168.0.10:11211, 192.168.0.11:11211, 192.168.0.11:11212, 192.168.0.11:11213);

Пихаем в кэш десяток ключей
SELECT memc_set(‘key1’, ‘val1’);

SELECT memc_set(‘key10’, ‘val10’);


Берем их из кэша
SELECT memc_get(‘key1’);

SELECT memc_get(‘key10’);


Вроде нормально, отдает то, что положили.

Теперь валим одного демона memcached. Как и следовало ожидать – два ключа накрылись. Снова ложим в кэш 10 этих же ключей.
Фиг вам. Те же пропавшие два, так и не объявились. Кетамой и не пахнет. Ну ничего, readme почитать мне не западло.

В Memcached Functions for MySQL ничего умного не нашел. Пойдем на tangent.org.
Блин, как все запущено.

Ага вот оно про оно кажется
docs.tangent.org/libmemcached/memcached_behavior.html
Согласно translate.ru behavior это поведение.
По дефолту MEMCACHED_BEHAVIOR_DISTRIBUTION стоит MEMCACHED_DISTRIBUTION_MODULA, а нам надо MEMCACHED_DISTRIBUTION_CONSISTENT, и MEMCACHED_BEHAVIOR_HASH чтоб было MEMCACHED_HASH_KETAMA.

И делает это memcached_behavior_set(). В MySQL это надо полагать memc_servers_behavior_set.
Бррр, стоп. А это что такое в доке memcached_behavior.pod

=item MEMCACHED_BEHAVIOR_DISTRIBUTION
Using this you can enable different means of distributing values to servers.
The default method is MEMCACHED_DISTRIBUTION_MODULA. You can enable
consistent hashing by setting MEMCACHED_DISTRIBUTION_CONSISTENT.
Consistent hashing delivers better distribution and allows servers to be
added to the cluster with minimal cache losses. Currently
MEMCACHED_DISTRIBUTION_CONSISTENT is an alias for the value
MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA.

=item MEMCACHED_BEHAVIOR_KETAMA
Sets the default distribution to MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA
and the hash to MEMCACHED_HASH_MD5.

Что-то каша в голове начинается.
Ага, наверное понял, надо сделать MEMCACHED_BEHAVIOR_KETAMA …
Как это?
Пошли дальше читать. Похоже тупо надо все подряд. Еще по буржуйски понимать быыыы.

Похоже это оно
For simple on or off options you just need to pass in a value of 1.
Значит надо MEMCACHED_BEHAVIOR_KETAMA set 1.

Ну что попробуем.
SELECT memc_servers_behavior_set (‘MEMCACHED_BEHAVIOR_KETAMA’, 1);

Мдааа. Кирдык фулльный.
mysql>SELECT memc_servers_behavior_set('MEMCACHED_BEHAVIOR_KETAMA', 1);
ERROR 2013 (HY000): Lost connection to MySQL server during query
mysql>

Лечится только рестартом MySQL сервера …

Ну ладно. Напишем разработчикам
forums.mysql.com/read.php?150,231325,231325#msg-231325

Быстро … отписался
forums.mysql.com/read.php?150,231325,231359#msg-231359

А если так
forums.mysql.com/read.php?150,231325,231442#msg-231442
То-то же.

Это похоже надолго.
Придется тупо смотреть в потолок. Может там что есть?
Точно. Есть. Только вот мысли какие-то не умные, а грязные.
Если откуда то берется не то, что мне нужно. Значит где то это туда положили. Нужно всего-то найти это где то и положить туда то, что мне нужно.

Ой блин. Лезть в исходники. А они на сях. А я про С только название знаю. В смысле, что язык так называется.
Ну да ладно. Делать нечего, будем искать знакомые слова.
В MySQL библиотеке наверное не стоит, она так, прокладка. Лезем в саму libmemcached.

Ага вот оно. В memcached.c. строка 29
ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA;
целых два знакомых слова.

И конструкция название имеет многообещающее: memcached_st *memcached_create(memcached_st *ptr).
Теперь попытаемся понять кто такой memcached_st.
Наверное понятно. Согласно libmemcached.pod, если translate.ru мне все правильно объяснил, это то самое место, где лежит не то что мне надо.
Сходим еще раз на на tangent.org. Конфы там нет, но есть майлин глист lists.tangent.org/mailman/listinfo/libmemcached. Там не так много чего. Тупо поищем знакомые слова.

Что то есть.
lists.tangent.org/pipermail/libmemcached/2008-September/000434.html
Если правильно понял, надо MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT’у сделать set сколько-нибудь. Там пишут 10, я попробую 3.

lists.tangent.org/pipermail/libmemcached/2008-August/000429.html
ну и мы так же сделаем.

Итак. Попытаемся подправить исходники. В смысле положить то что надо.

Вместо ptr->distribution= MEMCACHED_DISTRIBUTION_MODULA;
Напишем ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA;
Надо же. Мои первые в жизни 0,5 строки на C.

Вместо ptr->retry_timeout= 0;
Напишем ptr->retry_timeout= 60;

Ыыыыыыыыы. Вместо чего написать про MEMCACHED_BEHAVIOR_SERVER_FAILURE_LIMIT?
Опять тупо смотрим в потолок.

А че смотреть то. Искать про SERVER_FAILURE_LIMIT в исходниках.
Есть. В memcached_behavior.c. Стр.166, называется ptr->server_failure_limit.
Добавим по аналогии с остальным
ptr->server_failure_limit= 3;
Может прокатит. В принципе если что – сервер раком ляжет. Дык так же его и поставим.

Вот что получилось

memcached_st *memcached_create(memcached_st *ptr)
{
memcached_result_st *result_ptr;

if (ptr == NULL)
{
ptr= (memcached_st *)malloc(sizeof(memcached_st));

if (!ptr)
return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */

memset(ptr, 0, sizeof(memcached_st));
ptr->is_allocated= MEMCACHED_ALLOCATED;
}
else
{
memset(ptr, 0, sizeof(memcached_st));
}
result_ptr= memcached_result_create(ptr, &ptr->result);
WATCHPOINT_ASSERT(result_ptr);
ptr->poll_timeout= MEMCACHED_DEFAULT_TIMEOUT;
ptr->connect_timeout= MEMCACHED_DEFAULT_TIMEOUT;
ptr->retry_timeout= 60;
ptr->distribution= MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA;
ptr->server_failure_limit= 3;

return ptr;
}

Все. Перекомпилим либу и вперед. Приступаем к онани… ну вы поняли, к итерациям.

Определяем сервера
SELECT memc_servers_set(‘192.168.0.10:11211, 192.168.0.11:11211, 192.168.0.11:11212, 192.168.0.11:11213);

Пихаем в кэш десяток ключей
SELECT memc_set(‘key1’, ‘val1’);

SELECT memc_set(‘key10’, ‘val10’);


Берем их из кэша
SELECT memc_get(‘key1’);

SELECT memc_get(‘key10’);


Вроде нормально, отдает то, что положили.

Валим одного демона memcached.
Не понял. Какого черта. Почему они ВСЕ живые? Это я про данные которые в кэш положил.

Ладно. Валим второго.
Ну мы так не договаривались. Они ВСЕ живые.

Ну а если третьего.
Блин, все живые.

Ну нас так просто не возьмешь. Против лома нет приема. Валим последнего четвертого демона memcached.
То то же. Живых не осталось.
Начинаем убивать, поднимать, сохранять в, доставать из …
… короче итерациями заниматься.
НЕ МОГУ УБИТЬ!!!

Мда. Работает. Даже больше того.

Ну нет. Нас так просто не возьмешь.
Все УБИЛ!!!
Оставил живой одну ноду. По тихому поднял вторую. Не устраивая никаких обращений к memcached, свалил первую.
Все, не пережила. Знай наших, кого хочешь раком положим.

Уфф. О чем это я.
Вообще то про PHP.

Ну что, пойдем в шалашики labs.gree.jp/Top/OpenSource/libmemcached.html

Так, слава богу хоть исходники не в шалаше
github.com/kajidai/php-libmemcached/tree/master

Привинчиваем.
labs.gree.jp/Top/OpenSource/libmemcached/Document.html

Пробуем

<?php
$memcached = new Memcached();
$memcached->addserver('192.168.0.10', 11211);
$memcached->addserver('192.168.0.11', 11211);
$memcached->addserver('192.168.0.11', 11212);
$memcached->addserver('192.168.0.11', 11213);
$memcached->set('key1', 'val1');
$ret = $memcached->get('key1');
Echo $ret. “<br>”;


Работает сволочь…
Вместе с MySQL работает.
Корректно данные отрабатывают в паре.
Валим, поднимаем, пишем, читаем – все корректно.

Да кстати. На вебсервере подпиленную libmemcached привинтил.

А что по функционалу мы тут имеем?

Не плохо
memcached_ctor
memcached_server_add
memcached_add
memcached_add_by_key
memcached_append
memcached_append_by_key
memcached_behavior_get
memcached_behavior_set
memcached_cas
memcached_cas_by_key
memcached_delete
memcached_delete_by_key
memcached_get
memcached_get_by_key
memcached_set
memcached_set_by_key
memcached_increment
memcached_decrement
memcached_prepend
memcached_prepend_by_key
memcached_replace
memcached_replace_by_key
memcached_server_list
memcached_mget
memcached_fetch
memcached_server_list_append
memcached_server_push

gets’а тоже нету.

А как с глюками …
А фиг его знает.
Узнать бы. Ну в самом деле не писать же автору на моем русском английском в Японию. Ответит ведь мне на своем японском английском.
Так и война ведь начнется.

Ладно, полезем в исходники. Я ведь на С уже целых 2,5 строки в сумме в своей жизни написал.

Блин, как то все просто …
Аааа, въехал. Он же просто по zend’у обертку для трансляции вызовов написал. Блин и накосячить то наверное особо здесь негде.

Ну что.
Подведем итоги.

Во первых. Я написал свои первые 2,5 строки на С.
Во вторых. У меня теперь кетама в PHP есть.
В третьих. Хрен этот кэш так просто свалишь.
В четвертых. Похрену из чего, нормальный доступ к данным в memcached, хоть из С, хоть из Perl, хоть из PHP c MySQL. Один ложит, пофигу откуда и кто другой корректно читает.

PS. Снимаю шляпу перед Brian Aker brian.krow.net
Total votes 117: ↑23 and ↓94 -71
Comments 23

Information

Rating
Does not participate
Registered
Activity