Memcached высокая вставка / обновление вызывают взаимоблокировки

#php #memcached

#php #memcached

Вопрос:

Я записываю уникальные просмотры страниц с использованием memcached и сохраняю их в БД с интервалом в 15 минут. Всякий раз, когда число пользователей растет, memcached выдает мне следующую ошибку:

 Memcache::get(): Server localhost (tcp 10106) failed with: Failed reading line from stream (0)
  

Я использую следующий код для вставки / обновления просмотров страниц в memcached

 if($memcached->is_valid_cache("visiors")) {
    $log_views = $memcached->get_cache("visiors");
    if(!is_array($log_views)) $log_views = array();
}
else {
    $log_views = array();
}
$log_views[] = array($page_id, $time, $other_Stuff);
$memcached->set_cache("visiors", $log_views, $cache_expire_time);
  

Следующий код извлекает массив из memcached, обновляет X количество просмотров страниц в БД и устанавливает оставшиеся просмотры страниц в memcached

 if($memcached->is_valid_cache("visiors")) {
   $log_views = $memcached->get_cache("visiors");
   if(is_array($log_views) amp;amp; count($log_views) > 0) {
        $logs = array_slice($log_views, 0, $insert_limit);        
        $insert_array = array();
        foreach($logs as $log) {
            $insert_array[] = '('. $log[0]. ',' . $log[1] . ', NOW())';
        }
        $insert_sql = implode(',',$insert_array);
        if(mysql_query('INSERT SQL CODE')) {
            $memcached->set_cache("visiors", array_slice($log_views, $insert_limit), $cache_expire_time); //store new values
        }
    }
 }
  

Вставка / обновление вызывают блокировку потока, потому что я вижу много сценариев, ожидающих своей очереди. Я думаю, что я теряю просмотры страниц во время процесса обновления. Любые предложения, как избежать ошибок чтения memcached и сделать этот код идеальным?

Комментарии:

1. Memcached блокируется. Это особенность. Переключитесь на правильно настроенный сервер MySQL, он может быть намного быстрее с согласованным доступом и лучше обрабатывает блокировку.

2. Mysql плохо работает с высокими вставками, поэтому я добавил memcached layer.

3. Я позволю себе не согласиться. Но в любом случае, если memcached блокирует вас с высокими вставками (сейчас), вам нужно снова переключиться на что-то другое, чего нет. Как уже было сказано, это можно сделать с помощью MySQL, но, естественно, вы не привязаны к MySQL.

4. Как вы предлагаете решение MySQL? Просто простые инструкции INSERT? Средняя скорость вставки составляет 500-600 в секунду.

5. 500-600 — это не предел воображения «высокий». Я могу поддерживать скорость 400 000 / с (чуть менее чем в 100 000 раз превышающую вашу скорость) на моем ноутбуке на неопределенный срок с последней версией, и скоро появятся новые оптимизации, которые приблизят вас к 800 000 / с — 900 000 / с на этом же оборудовании. Ваше использование может быть неоптимальным, но это не так.

Ответ №1:

Вероятно, вы столкнулись с ограничением соединения в memcached, вашем брандмауэре, сети и т. Д. У нас есть простой обзор наиболее распространенных сценариев: http://code.google.com/p/memcached/wiki/Timeouts

Нет внутренней блокировки, которая могла бы привести к блокировке наборов или get на какое-то время.