Оптимизация трекера — сообщеньки !

И так , продолжим . Теперь у нас на сервере есть установленый memcached , вууухууу , зупер .  Начнем его использовать по назначению и первой жертвой будут сообщеньки .

Запрос выглядит следующим образом  —

  if ($msgalert && $CURUSER) {
		$res = sql_query("SELECT COUNT(*) FROM messages WHERE receiver = " . $CURUSER["id"] . " AND unread='yes'") or die("OopppsY!");
		$arr = mysql_fetch_row($res);
		$unread = $arr[0];
	  }

Че он делает ?! Он проверяет, есть ли у пользователя непрочитанные личные сообщения и если таковые имеются , то оповещают его о сие чуде .

Ползая по сайта , несколько сотен пользователей постоянно опрашиваю базу на наличие новой почты, ему приходиться отвечать , даже если таковой нету . Нахерам ?
Пускай за базу это делает memcached , а в нужный момент данные будут браться из базы . И как нам это сделать ?
Для начала , в файле
include/secrets.php
пропишим параметры нашего memcached сервера

$memcache_obj = new Memcache;
$memcache_obj->connect('127.0.0.1', 11211);

Затем , в function stdhead к global дописываем — $memcache_obj и заменяем стандартную проверку модифицированой с отправкой в memcached

if ($CURUSER) {
	$mem_get_m = $memcache_obj->get('messages_'.$CURUSER['id']);
        if ($mem_get_m === false) {
	$res = sql_query("SELECT COUNT(id) FROM messages WHERE receiver = " . $CURUSER["id"] . " AND unread='yes'") or die("OopppsY!");
	$arr = mysql_fetch_row($res);
	$date = $arr[0];
	$memcache_obj->set('messages_'.$CURUSER['id'], $date, MEMCACHE_COMPRESSED, 300);
	} else $unread = $mem_get_m;
	}

Вуаля ! Теперь , раз в 10 минут будет происходить проверка , есть новые сообщеньки или нету . У меня вообще установлено на пожизненно , но для этого во всех местах , где у вас идет отправка сообщений (будь то оповещение о новом комментарие или системные сообщение или кто то прислал личку) вам надо будет добавить функцию , которая будет удалять этот кеш , для его обновления и затем дальнейшего оповещения пользователя . Как этого добиться ?!
Для начала , что бы при просмотре новых сообщений не висела табличка о том что оно есть , так как данные в кеше , мы этот кеш удалим .
В файле message.php в самом начале , под строку

require_once ("include/bittorrent.php");

добавляем

global $memcache_obj;
$memcache_obj->delete('messages_'.$CURUSER['id'],1);

Это сбросит ключ кеша и обновит далее в нем данные .
Затем , что бы после отправки пользователь сразу же при рефреше страницы получал уведомление, после внесения сообщение в базу, удаляем ключ с кешем получателя . Ищем запрос

sql_query("INSERT INTO messages (poster, sender, receiver, added, msg, subject, saved, location) VALUES(" . $CURUSER["id"] . ", " . $CURUSER["id"] . ",
        $receiver, '" . get_date_time() . "', " . sqlesc($msg) . ", " . sqlesc($subject) . ", " . sqlesc($save) . ", 1)") or sqlerr(__FILE__, __LINE__);

и прям под ним вписываем

$memcache_obj->delete('messages_'.$receiver,1);

Так же вам надо проделать во всех местах , где идет отправка сообщений пользователю, что бы не было тупых задержек . Так что начинайте постепенно переписывать движок .
Надеюсь что ничего не забыл .
Огромное спасибо за помощь reketir`у !

Оптимизация трекера — сообщеньки !: 25 комментариев

  1. Hannnn

    Все хорошо да и на -1 запрос меньше
    только вот одного не могу понять сделал в message.php все проделал но серавно на главной при рефреше не появляется оповещение о новом ЛС.

  2. drug

    Спасибо. Но также сделал все как тут написано и на 1 запрос меньше стало,но также не появляется табличка о новом сообщении.Что не так у нас?

  3. webnet Автор записи

    токи шо проверил на чистой версии , все воркает .
    Проверьте , он закинул в кеш ключик ?

  4. leito

    Лучше везде понапихать(где это нужно) $memcache_obj->delete(‘messages_’.$receiver,1); и убрать что-бы обновлялос каждые 10 минут => кеш будет обновляться только когда отправили ЛС и без видимых последствий кеша.

  5. leito

    Сори не заметил.
    PS выложил-бы ты лучше announce.php(хотя без изменений в бд его не оптимизировать)..

  6. webnet Автор записи

    ты же там вроде даже свою оптимизацию продавал ?! не уж то ли мозгов нету почитать код аннонса и переписать . 😕

  7. leito

    У меня и так вроде как оптимизирован анонсер,но каждый делает по разному вдруг узнаю что-то новое для себя.

  8. XXX

    Fatal error: Class ‘Memcache’ not found in C:\AppServ\www\include\secrets.php on line 8

  9. Ku6ep

    Есть несколько запросов (например позвать скачавших), где сообщение посылается сразу нескольким пользователям в одном запросе. Как в этом случае проще очистить им всем кеш?

  10. Hannnn

    webnet извеняюсь
    ща посидел переделал опять нашел свою ошибку щас все робит на уря! 😆

  11. Footbit

    Не подскажите чем может быть вызвана ошибка?:

    Memcache::connect() [memcache.connect]: Can’t connect to 127.0.0.1:11211

  12. webnet Автор записи

    не может подключиться к мемкеш серверу . Проверь включен ли он или локальный ип смени на localhost

  13. Footbit

    Мемкеш сервер включен. Localhost прописывал тоже не помогает.

  14. den_in

    Fatal error: Class ‘Memcache’ not found in D:\AppServ\www\include\secrets.php on line 8

    что делать?
    Мемкеш установлен.
    мб что не так прописываю?

  15. NeoN

    Думаю в message.php будет правильно разместить
    global $memcache_obj;
    $memcache_obj->delete(‘messages_’.$CURUSER[‘id’],1);

    под

    dbconn();

    дабы определялся ID — $CURUSER[‘id’]

  16. Gono

    А у меня не каких ошибок, но зато почему то не приходит сообщение 🙁

  17. sadsa

    А как это под кеш загнать?:

    if ($CURUSER) {
    $msgs = sql_query(«SELECT location, sender, receiver, unread, saved FROM messages WHERE receiver = » . $CURUSER[«id»] . » OR sender = » . $CURUSER[«id»]) or sqlerr(__FILE__,__LINE__);
    $CURUSER[‘unread’]=$CURUSER[‘messages’]=$CURUSER[‘outmessages’]=0;
    while ($message = mysql_fetch_array($msgs)) {
    if ($message[«unread»] && $message[«location»] == 1 && $message[«receiver»] == $CURUSER[«id»])
    $CURUSER[‘unread’]++;
    if ($message[«location»] == 1 && $message[«receiver»] == $CURUSER[«id»])
    $CURUSER[‘messages’]++;
    if ($message[«saved»] && $message[«location»] != 0 && $message[«sender»] == $CURUSER[«id»])
    $CURUSER[‘outmessages’]++;
    }
    }

  18. Андрей

    У меня вот такая ошибка ..

    Ошибка в SQL
    Ответ от сервера MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘.1,1); 1, ‘2010-09-05 18:20:14’, 5, 5, ‘no’, 1)’ at line 2

    в /usr/local/www/apache22/data/бла бла бла/message.php, линия 371

    Запрос номер 1.

  19. admin Автор записи

    а как ты так ? что ты там менял ?

  20. Некит

    Все поставил как описано, но после прочтения сообещния, все равно весит «У вас новое сообщение» потом через время исчезает

Комментарии запрещены.