Memcache предоставляет возможность получения значений нескольких ключей сразу. Зачем это может понадобиться и в каких случаях это нужно использовать? Посмотрим на структуру запросов от приложения к Memcache, когда идет получение нескольких ключей:
Запрос к каждому ключу — это отдельный сетевой запрос:
Когда количество таких запросов переваливает за десятки с одной страницы Web сайта, следует подумать об оптимизации. Обычная функция memcache_get() позволяет передавать в параметры не один ключ, а массив ключей. Этот режим называется Multi Get. Тогда на сервер кэширования будет отправлен только один запрос и получен только один ответ с массивом значений:
Рассмотрим небольшой пример. Пусть у нас есть список новостей. Каждая новость будет храниться в ключе под именем “news_item_[id]”, где [id] — ID новости. Используя Multi Get мы сможем получить все новости за один запрос вместо нескольких десятков. Для этого достаточно передать массив ключей в функцию memcache_get() (либо метод get()):
<? # Получаем список ID новостей (например, из базы данных) $news_ids = [1, 2, 3, 4, 5]; $m = new Memcache; foreach ( $news_ids as $id ) $keys[] = 'news_item_' . $id; $news = $m->get($keys);
Переменная $keys содержит список ключей, в переменную $news попадет список данных новостей
Сравним скорость Multi GET и обычного memcache_get() для каждого ключа. Скрипт для сравнения на PHP:
<? $tests = 15000; $m = new Memcache; $m->connect('localhost', '11211'); for ( $i = 0; $i < $tests; $i ++ ) { $m->set('test' . $i, md5($i)); } $t = microtime(true); for ( $i = 0; $i < $tests; $i ++ ) { $list_get[] = $m->get('test' . $i); $keys[] = 'test' . $i; } echo 'Fetched ' . $tests . ' objects with standard get in ' . (microtime(true) - $t) . 's'; echo "\n"; $t = microtime(true); $list_mget = $m->get($keys); echo 'Fetched ' . $tests . ' objects with multiple get in ' . (microtime(true) - $t) . 's'; echo "\n";
Отправим 15 тысяч запросов одним запросом и несколькими
Результаты будут приблизительно такими:
Fetched 15000 objects with standard get in 0.47441411018372s Fetched 15000 objects with multiple get in 0.023789882659912s
В случае Multi Get мы потратили на порядок меньше времени. Тестирование выполнялось на одном сервере. Это значит, что подключение к Memcache по сети даст еще большее отличие.
На практике у Вас не будет возможности собрать все ключи и отправить запрос на сервер из одного участка кода. Это неудобно, т.к. приведет к крайне плохой гибкости приложения. Однако есть ряд случаев, когда это все же следует применять.
Как в примере с новостям, логика Web приложения часто содержит перебор списков пользователей, картинок, новостей, комментариев и т.п. В этом случае Multi Get будет очень полезен и прост в реализации. Нужно отметить, что на практике необходимо дополнительно проверять наличие значений в возвращаемых ключах, т.к. каких-то значений может не быть:
<? $news_ids = [1, 2, 3, 4, 5]; $m = new Memcache; foreach ( $news_ids as $id ) $keys[] = 'news_item_' . $id; $news = $m->get($keys); foreach ( $news as $i => $post ) { if ( !$post ) $post = get_post( $keys[$i] ); echo $post['title'] . '<br/>'; }
Функция get_post() должна вернуть данные новости из базы данных
В отдельной Cron задаче намного проще собрать необходимые для выборки ключи, чем в целом приложении. Их можно собирать и обрабатывать частями, например по 10 штук. Популярный пример — рассылка новостей по почте:
<? $users_ids = [1, 2, 3, 4, 5, ...]; foreach ( $users_ids as $i => $id ) { if ( count($keys) < 10 ) { # собираем список ключей по 10 штук максимум $keys[] = 'user' . $id; # продолжаем, только если еще не конец списка if ( $keys[$i+1] ) continue; } # получаем данные пользователей $users = $m->get($keys); foreach ( $users as $user ) { mail($user['email'], 'Э', 'Чо'); } # очищаем массив ключей $keys = []; }
Получаем сразу по 10 значений данных пользователей вместо одного
Использование множественного запроса Multi Get в Memcache позволяет снизить количество обращений от приложения к серверу кэша. Это уменьшает сетевой трафик и ускоряет работу приложения.
Этот текст был написан несколько лет назад. С тех пор упомянутые здесь инструменты и софт могли получить обновления. Пожалуйста, проверяйте их актуальность.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…