Как выносите выполнение логики, которая не влияет на ответ клиенту?

fixxxer

К.О.
Партнер клуба
не, ну я так то знаю :) но для начала надо бы спросить какие объемы у тредстартера ;))
 

andry

Новичок
Автор оригинала: fixxxer

в этом плане все нормально, взятие-удаление атомарное.
единственная проблема в том, что если почему-то обработать элемент не получилось, то его часто надо бы положить обратно дабы попробовать еще раз, а если посреди обработки скрипт вылетел, то "ой".
Не понял, как сразу взять, обработать и удалить атомарно %)
 

fixxxer

К.О.
Партнер клуба
ну я может быть чего-то не понял, но судя по мануалу, memcacheq работает так

set(имя очереди, элемент) - добавляем элемент в конец очереди, если очереди не было то автоматически создаем

get(имя очереди) - получаем первый элемент из очереди и сразу его выкидываем (атомарно, в пределах запроса get)
 

andry

Новичок
Автор оригинала: fixxxer
не, ну я так то знаю :) но для начала надо бы спросить какие объемы у тредстартера ;))
Пока не понятно, проектирую только, заклад на высокую производительность полюбому надо делать, проект такой. Как раз вещей, которые никак не влияют на респонс уже набралось.
 

fixxxer

К.О.
Партнер клуба
ну, если указанная мной проблема с возможной потерей элемента очереди при вылете php-скрипта не критична, то бери memcacheq, это самое простое решение :) масштабировать его легко просто размещая разные очереди на разных серверах, одна очередь то уж наверняка на один влезет. хотя скорее всего и одного сервера хватит с запасом.

если через базу, то скорее всего со временем понадобится делать несколько очередей, например - если совсем уж хайлоад брать - на каждом сервере с данными своя локальная очередь, из нее выгребаешь в разные очереди по тому же скажем subscriber_id и уже на выделенном для этой задачи сервере (или серверах) обрабатываешь.
 

andry

Новичок
Автор оригинала: fixxxer
ну я может быть чего-то не понял, но судя по мануалу, memcacheq работает так

set(имя очереди, элемент) - добавляем элемент в конец очереди, если очереди не было то автоматически создаем

get(имя очереди) - получаем первый элемент из очереди и сразу его выкидываем (атомарно, в пределах запроса get)
Т.е. он лочит чтоль?
 

fixxxer

К.О.
Партнер клуба
нет, он не многопоточный, там конечный автомат. так что лочить ничего не надо.
 

andry

Новичок
Автор оригинала: fixxxer
ну, если указанная мной проблема с возможной потерей элемента очереди при вылете php-скрипта не критична, то бери memcacheq, это самое простое решение :) масштабировать его легко просто размещая разные очереди на разных серверах, одна очередь то уж наверняка на один влезет. хотя скорее всего и одного сервера хватит с запасом.
.
Кто-нить этого зверя memcacheq в продакшене использует?

-~{}~ 08.10.08 21:00:

09/22/2008 - MemcacheQ 0.1.0 is released
совсем не внушает доверия
 

fixxxer

К.О.
Партнер клуба
да там ничего особенного, основа - memcachedb который в свою очередь memcached + bdb, накосячить негде =)
 

fixxxer

К.О.
Партнер клуба
посмотрел, собрал, выглядит вменяемо и шустро.
порт для freebsd, кстати, элементарно делается из порта memcachedb.

тестировал так (запуская параллельно разные комбинации):
PHP:
srv01 ~/mcq$ cat test_put.php 
<?
function exitparams() { exit("Usage: {$_SERVER['argv'][0]} queue_name number_of_sets\n"); }
$queue_name = $_SERVER['argv'][1] or exitparams();
$count = $_SERVER['argv'][2] or exitparams();
$mc = memcache_connect('localhost', 11212);
for ($i=0; $i<$count; ++$i) {
    memcache_set($mc, $queue_name, "queue element # $i");
    if (0 == $i%100) echo '.';
}
echo "Done\n";
PHP:
srv01 ~/mcq$ cat test_get.php 
<?
function exitparams() { exit("Usage: {$_SERVER['argv'][0]} queue_name\n"); }
$queue_name = $_SERVER['argv'][1] or exitparams();
$mc = memcache_connect('localhost', 11212);
for ($i=0;;$i++) {
    $item = memcache_get($mc, $queue_name);
    if (false===$item) break;
    //var_dump($item);
} 
echo "$i items read\n";
 

andry

Новичок
Под нагрузкой смотрел? Пробовал разгребать в несколько процессов?
 

Фанат

oncle terrible
Команда форума
andry, ты, случайно не перепутал, кто из вас автор этого топика? %)
 

andry

Новичок
Автор оригинала: *****
andry, ты, случайно не перепутал, кто из вас автор этого топика? %)
просто интересно, почему бы и не поделить, если да
я не заводил этот топик чтоб мне дали готовый ответ. Мне интересно обсудить, все остальное я вполне способен сделать сам

-~{}~ 16.10.08 17:18:

Кому интересно
Оказывается ActiveMQ (реализация JMS) вполне работает с php
http://stomp.codehaus.org/PHP

Был там один непрятный баг, а в целом отличный инструмент для этих вещей, так сказать из коробки, обкатанный годами.
 

no_alex

Новичок
Моё мнение: если важно как можно быстрее завершить основной скрипт, а время обработки не важно, то данные лучше класть не в базу, а в лог-файл. Например, при помощи команды: error_log("data", 3, "filename");

Это сработает намного быстрее, чем "коннект к БД" + "INSERT".

При желании в лог можно положить и какие-то "сложные данные", типа массивов или объектов, только предварительно сериализуйте их. Во многих случаях это потом облегчит обработку лога.
Я, конечно, не призываю специально создавать объекты или массивы, только для того чтобы положить их в лог. Как правило, они уже у вас есть на тот момент, когда возникла необходимость их сохранить. Просто сериализуем их и кладем в лог "как есть", а "разбор полетов" начинаем уже после извлечения данных из лога.
Исключением для такого подхода могут быть только ситуации, когда в лог попадает много "лишних данных". Тогда лучше данные специально готовить "под лог".

Если побеспокоится о том чтобы в логгируемых данных не было переводов строк (например, предварительно заменить их на сочетание '\n') и каждую новую запись в лог делать с новой строки, то анализ лога станет вообще простой процедурой - команда file ("filename") вернет нам удобный массив. В цикле десериализуем каждый его элемент и выполняем необходимые действия.
Если Вы считаете, что такие действия сильно замедлят подготовку лога - просто вставляйте разделительные маркеры перед или после каждой логгируемой записи. Это конечно замедлит парсинг лога, но упростит его подготовку.

И последнее замечание - побеспокойтесь о том, чтобы пока идёт анализа сформированного лога, новые данные могли записываться в новый лог.
Тут советы могут быть разные, но я предпочитаю перед началом анализа, файл лога переименовывать, а по окончанию - удалять переименованный файл. Это позволяет в случае каких-то ошибок, возникающих при анализе - не потерять данные.
 

no_alex

Новичок
Для тех, кто собирается сериализовать объекты советую обратить серьезное внимание на "Магические методы" __sleep и __wakeup.

В свое время мне они очень помогли (не загонять в лог "мусор", динамически подгружать недостающие классы и т.п.).
 
Сверху