<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Highload Web</title>
	<atom:link href="http://highload.com.ua/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://highload.com.ua</link>
	<description>Масштабирование и производительность Web систем, высокие нагрузки, архитектурные решения</description>
	<pubDate>Wed, 21 Jul 2010 15:20:00 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Используем Nginx как &#8220;long polling&#8221; (Comet) сервер</title>
		<link>http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/</link>
		<comments>http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 15:14:38 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Теория и практика]]></category>

		<category><![CDATA[long polling]]></category>

		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1191</guid>
		<description><![CDATA[
Принцип &#8220;Long Polling&#8221; (или &#8220;Comet&#8220;) позволяет сделать возможным установление постоянного соединения клиента с Web приложением и также периодичной отправки данных клиенту в рамках этого соединения (без необходимости клиента постоянно делать HTTP запросы для проверки новых данных). Другими словами, эта модель позволяет реализовать постоянные HTTP соединения для получения данных порциями. Наиболее популярное применение - чаты, твиттеры [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/07/comet.jpg" alt="comet" title="comet" width="85" height="200" class="alignleft size-full wp-image-1192" /></p>
<p>Принцип &#8220;<strong>Long Polling</strong>&#8221; (или &#8220;<strong>Comet</strong>&#8220;) позволяет сделать возможным установление постоянного соединения клиента с Web приложением и также периодичной отправки данных клиенту в рамках этого соединения (без необходимости клиента постоянно делать HTTP запросы для проверки новых данных). Другими словами, эта модель позволяет реализовать постоянные HTTP соединения для получения данных порциями. Наиболее популярное применение - чаты, твиттеры и другие live-updated потоки - клиент постоянно &#8220;слушает&#8221; сервер на предмет появления новых сообщений, и как только новые сообщения появляются - они мгновенно доставляются ему.</p>
<p>Сам принцип не несет в себе инноваций в HTTP протоколе, т.к. этот подход реализуем обычными средствами. Проблема заключается в том, что стандартное решение - установка постоянного соединения с обычным Web сервером (а значит и с обслуживающей платформой, например php-бекендом) - крайне ресурсоемкое и не применимо на практике. Другой подход - постоянно опрашивать приложение на предмет появления новых данных является еще более ресурсоемким.</p>
<p>Решением этой проблеммы стали т.н. HTTP-PUSH (или comet) сервера, позволяющие облуживать огромное количество постоянных соединений эффективно расходуя ресурсы. Как они устроены и как применяются на практике?<br />
<span id="more-1191"></span></p>
<h2>Принцип работы Comet-сервера</h2>
<p>Необходимо отметить, что Comet сервер решает задачу отправки клиенту определенных данных порциями. Comet сервера реализуют т.н. HTTP Push Relay протокол (например, <a href="http://pushmodule.slact.net/protocol.html">Basic HTTP Push Relay Protocol</a>). Принцип работы такого протокола заключается в следующем:</p>
<ul>
<li>На Web сервере создается т.н. &#8220;канал&#8221; с уникальным ключем. Это делается на стороне приложения путем посылки запроса к Comet-серверу</li>
<li>Клиент устанавливает обычное HTTP соединение с Comet-сервером, передавая в параметры ключ канала, из которого он будет получать данные. Сервер удерживает такое соединение, пока не отправит очередную порцию данных</li>
<li>Основное приложение, по определенному событию (например, кто-то написал сообщение клиенту), шлет в канал Comet сервера с нужным ключем это сообщение</li>
<li>Как только в канале появляется сообщение, Comet сервер отправляет его соответствующему клиенту и закрывает HTTP соединение (иногда соединения не закрываются, а продолжают быть активными)</li>
</ul>
<p>Таким образом, сервер реализует &#8220;стэки&#8221; сообещений, а их раздача происходит без участия тяжелых бекендов. Бекенды вступают в силу только тогда, когда необходимо отправить сообщение.</p>
<h2>Nginx и модуль HTTP Push</h2>
<p>Модуль <strong>nginx_http_push_module</strong> позволяет превратить <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >Nginx</a> в Comet сервер, реализуя протокол Basic HTTP Push Relay Protocol. Преимущества этого модуля и протокола - в его простоте по сравнению с альтернативными решениями (например, протоколом <a href="http://svn.cometd.com/trunk/bayeux/bayeux.html">Bayeux</a> и сервером CometD).</p>
<h4>Установка</h4>
<p>Для установки модуля необходимо скачать его исходники и перекомпилировать <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >Nginx</a>, т.к. модуль является внешней разработкой:</p>
<pre>
wget http://pushmodule.slact.net/downloads/nginx_http_push_module-0.692.tar.gz
tar -xvf nginx_http_push_module-0.692.tar.gz
...
cd /where/<a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >nginx</a>/sources/are
./configure \
  --add-module=/path/to/<a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >nginx</a>/modules/sources/nginx_http_push_module-0.692/
make; make install
</pre>
<h4>Конфигурация</h4>
<p>Для базовой конфигурации нам необходимо объявить две рабочих точки в <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >Nginx</a>&#8217;e: точка публикации сообщений (приватная - доступна только для самого приложения) и точка раздачи сообщений (публичная - к которой будут подключаться клиенты):</p>
<pre>
	location /publish {
		# Название переменной с идентификатором канала
		# в нашем примере "cid", т.е. запрос будет таким:
		# http://example.com/publish?cid=s42378fwe
		set $push_channel_id $arg_cid;
		push_publisher;

		# Отключаем хранение очереди (сообщение удаляется после доставки)
		push_store_messages off;
	}

	location /listen {
		push_subscriber;

		# Обслуживать только первого "слушателя"
		# Остальным отправляем 403
		push_subscriber_concurrency first;

		# Идентификатор канала
		set $push_channel_id $arg_cid;

		# Тип ответа
		default_type text/plain;
	}
</pre>
<p>После этого при отправке сообщения нужно будет посылать его в соотв. канал, делая POST запрос на &#8220;/publish&#8221;. Клиент же отправляет GET запрос на &#8220;/listen&#8221; и ждет ответа. Когда приходит ответ, клиент делает повторный запрос на &#8220;/listen&#8221; и т.д.</p>
<p>Все параметры конфигурации с подробным описанием смотрите на <a href="http://pushmodule.slact.net/#configure">официальном сайте</a>.</p>
<h2>Пример</h2>
<p>В качестве примера ниже приведен код на PHP, который используется для отправки сообщения в канал:</p>
<pre>

# Определяем ID канала
$channel_id = 12345;

# Сообщение
$message = 'Привет тебе!';

# Отправляем сообщение в канал
$c = curl_init( 'http://localhost/publish?cid=' . $channel_id );
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, json_encode($message));
$r = curl_exec($c);
</pre>
<p>Для получения сообщения код на Javascript будет выглядеть где-то так (на основе <a href="http://jquery.com">Jquery</a>):</p>
<pre>
var channelId = 12345;
function check_messages() {
	$.get('/listen?cid=' + channelId, {}, function(r) {
		// Считаем, что у нас есть div c id=messages,
		// куда мы дописываем сообщения
		$('#messages').append(r);
		setTimeout(check_messages, 500);
	}, 'json');
}

check_messages();
</pre>
<p>В каких случаях Вам приходилось пользоваться comet-серверами?</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&t=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&u_data[name]=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/&title=%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D0%B5%D0%BC+Nginx+%D0%BA%D0%B0%D0%BA+%22long+polling%22+%28Comet%29+%D1%81%D0%B5%D1%80%D0%B2%D0%B5%D1%80+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2009/04/24/%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-nginx/' rel='bookmark' title='Permanent Link: Настройка nginx'>Настройка nginx</a></li><li><a href='http://highload.com.ua/index.php/2009/10/31/nginx-dlya-otdaci-failov/' rel='bookmark' title='Permanent Link: Настройка nginx для отдачи файлов'>Настройка nginx для отдачи файлов</a></li><li><a href='http://highload.com.ua/index.php/2009/05/09/%d1%80%d0%b5%d1%81%d0%b0%d0%b9%d0%b7%d0%b8%d0%bd%d0%b3-%d0%ba%d0%b0%d1%80%d1%82%d0%b8%d0%bd%d0%be%d0%ba-%d0%b2-nginx/' rel='bookmark' title='Permanent Link: Ресайзинг картинок в nginx'>Ресайзинг картинок в nginx</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/07/21/%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d0%b5%d0%bc-nginx-%d0%ba%d0%b0%d0%ba-long-polling-comet-%d1%81%d0%b5%d1%80%d0%b2%d0%b5%d1%80/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Gearman и PHP - асинхронные задачи</title>
		<link>http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/</link>
		<comments>http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 16:38:54 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Технологии]]></category>

		<category><![CDATA[gearman]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[очереди сообщений]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1178</guid>
		<description><![CDATA[
Gearman - это сервер организации и распределения задач, или проще говоря сервер очереди сообщений. Gearman включает множество функциональных особенностей - балансировка, асинхронное/синхронное выполнение, приоритеты и т.п. В этой статье, на примере с PHP, реализуем простой механизм отложенной отправки почты.

Суть
Зачем вообще нужны такие решения, как Gearman, читайте в статье &#8220;Очередь сообщений - что это и зачем?&#8220;. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/07/gearman.gif" alt="gearman" title="gearman" width="300" height="50" class="alignleft size-full wp-image-1179" /></p>
<p><b>Gearman</b> - это сервер организации и распределения задач, или проще говоря сервер очереди сообщений. Gearman включает множество функциональных особенностей - балансировка, асинхронное/синхронное выполнение, приоритеты и т.п. В этой статье, на примере с PHP, реализуем простой механизм отложенной отправки почты.<br />
<span id="more-1178"></span></p>
<h2>Суть</h2>
<p>Зачем вообще нужны такие решения, как Gearman, читайте в статье &#8220;<a href="highload.com.ua/index.php/2009/05/15/очередь-сообщений-что-это-и-зачем/">Очередь сообщений - что это и зачем?</a>&#8220;. Наша задача реализовать отложенную отправку почты, т.к. это довольно ресурсоемкая операция и может сильно влиять на скорость ответа приложения клиенту.</p>
<h2>Установка</h2>
<p>Установка происходит в два этапа. Сначала ставим сам сервер (исходники качаем <a href="http://gearman.org/index.php?id=download">тут</a>):</p>
<pre>
tar -xvzf  gearmand-version.tar.gz
cd gearmand
./configure
make; make install
</pre>
<p>Теперь устанавливаем php расширение:</p>
<pre>
pecl download gearman-0.7.0
tar -xvf gearman-0.7.0.tgz
cd gearman-0.7.0
phpize
./configure
make
make install
</pre>
<p>Не забываем добавить &#8220;extension=gearman.so&#8221; в php.ini. Если все хорошо, то phpinfo() покажет нам:<br />
<img src="http://highload.com.ua/wp-content/uploads/2010/07/php-info-gearman.png" alt="php-info-gearman" title="php-info-gearman" width="662" height="179" class="aligncenter size-full wp-image-1182" /></p>
<h2>Клиент</h2>
<p>В нашем клиенте (основное приложение) отправка email сообщений будет осуществляться путем регистрации новых задач на сервере Gearman:</p>
<pre>

...
$mail = array(
  'to' => 'test@gmail.com',
  'subject' => 'Привет',
  'body' => 'Это тестовое сообщение',
);
...

# Подключаемся к серверу
$client= new GearmanClient();
$client->addServer();

# Регистрируем задачу для фонового выполнения
# "sendmail" - это тип задачи
# $mail - это данные письма
$result = $client->doBackground("sendmail", serialize($mail));
</pre>
<p>Обратите внимание, что PHP клиент принимает только строку в качестве данных о задаче, поэтому необходимо любой другой тип объектов сериализовать. Мы использовали асинхронное выполнение задач (метод <strong>doBackground</strong>), поэтому реальное время отправки почты не повлияет на скорость выполнения нашего приложения.</p>
<h2>Обработчик задачи</h2>
<p>Обработчик - это отдельное приложение (скрипт), который &#8220;слушает&#8221; сервер на предмет появления новых задач. Как только задача приходит - он выполняет связанную с ней логику (в нашем случае это будет отправка письма с помощью почтового сервера).</p>
<pre>

# Создаем "воркера" и подключаемся к серверу задач
$worker= new GearmanWorker();
$worker->addServer();

# Регистрируем обработчик события "sendmail"
# "send_mail" - это имя функции, объявленной ниже
$worker->addFunction("sendmail", "send_mail");

while (1)
{
  echo "Ждем работы...\n";

  $ret= $worker->work();
  if ($worker->returnCode() != GEARMAN_SUCCESS) break;
}

# Функция реальной отправки почты
# В аргумент ей передается объект задачи
function send_mail($job)
{
  $workload= $job->workload();
  $data = unserialize($workload);

  mail($data['to'], $data['subject'], $data['body']);
}
</pre>
<h2>Полезные ссылки</h2>
<ul>
<li><a href="http://gearman.org/">Официальный сайт</a>
<li><a href="http://php.net/gearman">PHP клиент</a>
</ul>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&title=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&title=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&title=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&t=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&title=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&u_data[name]=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/&title=Gearman+%D0%B8+PHP+-+%D0%B0%D1%81%D0%B8%D0%BD%D1%85%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2009/05/21/%d0%be%d1%87%d0%b5%d1%80%d0%b5%d0%b4%d1%8c-%d1%81%d0%be%d0%be%d0%b1%d1%89%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%b5-php-%d0%b8-memcacheq/' rel='bookmark' title='Permanent Link: Очередь сообщений на основе PHP и MemcacheQ'>Очередь сообщений на основе PHP и MemcacheQ</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/07/09/gearman-%d0%b8-php-%d0%b0%d1%81%d0%b8%d0%bd%d1%85%d1%80%d0%be%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87%d0%b8/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Оптимизация картинок в Web</title>
		<link>http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/</link>
		<comments>http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/#comments</comments>
		<pubDate>Fri, 02 Jul 2010 15:02:01 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Tips and tricks]]></category>

		<category><![CDATA[оптимизация]]></category>

		<category><![CDATA[статика]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1161</guid>
		<description><![CDATA[
Когда речь идет об оптимизации Web приложений, большое внимание следует уделять оптимизации клиентской части. Размер статических данных обычно в разы превосходит размер динамически генерируемых. Большинство этих данных - это медиа данные. Чаще всего это изображения (картинки для верстки и фотографии), кроме того есть flash, видео, аудио и т.п. 
В этой статье рассмотрим основные инструменты оптимизации [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/07/jpeg-icon.png" alt="jpeg icon" title="jpeg icon" width="128" height="128" class="alignleft size-full wp-image-1162" /></p>
<p>Когда речь идет об <a href="http://highload.com.ua/index.php/tag/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/" >оптимизации</a> Web приложений, большое внимание следует уделять <a href="http://highload.com.ua/index.php/2009/06/07/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%81%D0%BA%D0%BE%D0%B9-%D1%87%D0%B0%D1%81%D1%82%D0%B8/">оптимизации клиентской части</a>. Размер статических данных обычно в разы превосходит размер динамически генерируемых. Большинство этих данных - это медиа данные. Чаще всего это изображения (картинки для верстки и фотографии), кроме того есть flash, видео, аудио и т.п. </p>
<p>В этой статье рассмотрим основные инструменты <a href="http://highload.com.ua/index.php/tag/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/" >оптимизации</a> картинок для Web приложений.<br />
<span id="more-1161"></span></p>
<h3>Суть оптимизации картинок</h3>
<p>Зачастую файлы изображений хранят множество дополнительной информации, например детали о съемке фото, комментарии, текстовое описание, географические данные и т.п. При использовании в Web практически всегда эти данные не нужны. Существуют инструменты, которые позволяют вырезать всю ненужные мета данные, а также делать определенную <a href="http://highload.com.ua/index.php/tag/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/" >оптимизацию</a> изображения без потери качества. В некоторых случаях это может привести к 90% уменьшению размеров изображений.</p>
<p>Кроме этого, важно выбирать подходящий формат для каждой конкретной картинки, что позволит использовать максимально эффективное сжатие.</p>
<h3>Форматы</h3>
<p>В Web можно использовать три формата изображений:</p>
<ul>
<li><b>PNG</b> - сегодня это основной формат, ввиду эффективности сжатия и функциональных особенностей. Поддерживается всеми современными браузерами. Этот формат следует всегда выбирать по умолчанию для графики</li>
<li><b>GIF</b> - этот формат следует использовать, когда необходима анимация. Также в некоторых случаях (очень маленькие файлы - менее 10х10 пикселей) этот формат обеспечивает лучшее сжатие, чем PNG</li>
<li><b>JPEG</b> - выбирайте всегда для фотографий. Этот выбор лучше, чем PNG, т.к. JPEG позволяет выбрать более эффективную стратегию сжатия благодаря размытию (экономия за счет небольшой потери качества)</li>
</ul>
<h3>Инструменты для оптимизации</h3>
<h4>imagemagick</h4>
<p>Если Вы используете imagemagick для генерации превью (thumbnails), то включайте опцию &#8220;-strip&#8221; для вырезания всех ненужных метаданных из изображений:</p>
<pre>convert test.jpg -resize 100x100 <b>-strip</b> test_100.jpg</pre>
<p>Особенно хороший эффект дает для фотографий (в которых размер метаданных может достигать десятков килобайтов)</p>
<h4>Оптимизация JPEG с помощью jpegoptim</h4>
<p>В Debian системах эта утилита доступна в пакетах:</p>
<pre>apt-get install jpegoptim</pre>
<p>Для <a href="http://highload.com.ua/index.php/tag/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/" >оптимизации</a> файлов нужно указать их в параметрах с опцией &#8220;&#8211;strip-all&#8221;:</p>
<pre>jpegoptim --strip-all test.jpg</pre>
<h4>Оптимизация PNG с помощью pngnq</h4>
<p>В Debian системах эта утилита также доступна в пакетах:</p>
<pre>apt-get install pngnq</pre>
<p>Работает так (в результате создает новый файл - старый <B>не</b> перезаписывает):</p>
<pre>pngnq test.png</pre>
<h3>Опыт</h3>
<p>На одном из наших проектов простой обработкой картинок (не фотографий) вышеперечисленными инструментами удалось уменьшить общий их размер более чем на 15%. И это при том, что почти все картинки создавались с помощью специальных инструментов с оптимальными настройками. Таким образом процедура оказалась очень полезной, к тому же крайне простой.</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&t=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&u_data[name]=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/&title=%D0%9E%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F+%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BE%D0%BA+%D0%B2+Web+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2009/07/03/%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%ba%d0%b0%d1%80%d1%82%d0%b8%d0%bd%d0%be%d0%ba-%d0%b4%d0%bb%d1%8f-web/' rel='bookmark' title='Permanent Link: Оптимизация картинок для Web'>Оптимизация картинок для Web</a></li><li><a href='http://highload.com.ua/index.php/2009/06/07/%d0%be%d0%bf%d1%82%d0%b8%d0%bc%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%81%d0%ba%d0%be%d0%b9-%d1%87%d0%b0%d1%81%d1%82%d0%b8/' rel='bookmark' title='Permanent Link: Оптимизация клиентской части'>Оптимизация клиентской части</a></li><li><a href='http://highload.com.ua/index.php/2009/05/09/%d1%80%d0%b5%d1%81%d0%b0%d0%b9%d0%b7%d0%b8%d0%bd%d0%b3-%d0%ba%d0%b0%d1%80%d1%82%d0%b8%d0%bd%d0%be%d0%ba-%d0%b2-nginx/' rel='bookmark' title='Permanent Link: Ресайзинг картинок в nginx'>Ресайзинг картинок в nginx</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/07/02/optimizaciya-kartinok/feed/</wfw:commentRss>
		</item>
		<item>
		<title>NoSQL - подходы к решению типичных задач</title>
		<link>http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/</link>
		<comments>http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 16:30:54 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Теория и практика]]></category>

		<category><![CDATA[key-value]]></category>

		<category><![CDATA[memcachedb]]></category>

		<category><![CDATA[nosql]]></category>

		<category><![CDATA[redis]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=876</guid>
		<description><![CDATA[
Врядли сегодня найдется тот, кто еще не слышал про key-value базы данных, или, как их называют в народе, NoSQL. Те, кто успел попробовать продукты вроде Redis, MemcacheDB и других, обнаружили некторые сложности при решении привычных задач - выборка списков и поиск.
В этой статье мы рассмотрим принципы решения типичных задач в key-value базах данных.

Основная сложность
Восновном, все [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/06/nosql.jpg" alt="nosql" title="nosql" width="150" height="132" class="alignleft size-full wp-image-1138" /></p>
<p>Врядли сегодня найдется тот, кто еще не слышал про <a href="http://highload.com.ua/index.php/tag/key-value/">key-value базы данных</a>, или, как их называют в народе, <b>NoSQL</b>. Те, кто успел попробовать продукты вроде <a href="http://highload.com.ua/index.php/2009/05/01/redis/" >Redis</a>, <a href="http://highload.com.ua/index.php/2009/04/27/memcachedb/" >MemcacheDB</a> и других, обнаружили некторые сложности при решении привычных задач - выборка списков и поиск.</p>
<p>В этой статье мы рассмотрим принципы решения типичных задач в key-value базах данных.</p>
<p><span id="more-876"></span></p>
<h2>Основная сложность</h2>
<p>Восновном, все key-value базы данных представляют из себя распределенные хеш-таблицы. Это самая сильная их сторона, т.к. предоставляет высокую <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> и крайне упрощает <a href="http://highload.com.ua/index.php/tag/%D0%BC%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/" >масштабирование</a>. Тем не менее, это свойство всплывает на поверхность, когда Вам необходимо работать со списками. В MySQL следующие задачи решаются в два счета:</p>
<ul>
<li>Выбрать 10 последних пользователей</li>
<li>Выбрать Самые популярные посты в блоге</li>
<li>Найти продукты, для которых оставлено более 3х комментариев</li>
<li>Полнотекстовый поиск</li>
<li>Поиск по любому свойству (найти пользователя, email которого такой-то)</li>
</ul>
<p>Но в key-value подобные задачи вызывают удивление и большие трудности. В двух словах, key-value базы данных совсем не предназначены для таких задач. Но это только на первый взгляд, ведь формулировать задачи можно по-разному. Стратегия решения будет зависеть от конкретной ситуации.</p>
<p>И так, по порядку:</p>
<h4>Поиск по ключу</h4>
<p>Существует класс задач, когда Вам необходимо делать выборку одного объекта не по первичному, а вторичному ключу (например, поиск пользователя по email&#8217;у, поиск автора по никнейму т.п.). Принцип решения этой задачи следующий: после создания нового объекта, Вам необходимо создать ссылки на его первичный ключ для всех его свойств, по которым придется делать выборку. Например мы создаем пользователя:</p>
<pre>
user_134: {
  name: Den,
  email: golotyuk@gmail.com
}
</pre>
<p>И дублируем ключ email:</p>
<pre>
user_email_golotyuk@gmail.com: {
  id: 134
}
</pre>
<p>Теперь, Вы сможете сделать выборку данных пользователя по его почтовому адресу в два этапа.</p>
<h4>Использование РСУБД</h4>
<p>Если Вам нужен MySQL - используйте его, не стреляйте по воробьям их танка</p>
<p>Существует класс задач, для которых можно и нужно использовать РСУБД, такие как MySQL и Postgres. Если Вам необходимо делать выборки списков с фильтрами и сортировками, то Вам следует использовать более подходящую для этого РСУБД. Хороший пример - это посты в блоге. (выборки, которые скорее всего нужно будет делать - самые новые, самые популярные, самые комментируемые записи и т.п.).</p>
<p>Подход довольно простой, но на практике очень часто задачи сильно переплетены, и в итоге Вы можете прийти к тому, что РСУБД возьмет все задачи обратно на себя. В этом случае следует подумать о гибридном решении:</p>
<h4>Гибридное решение - дополнительная РСУБД</h4>
<p>Это решение представляет из себя смесь key-value и РСУБД. Все данные Вы храните в key-value, но те свойства, по которым понадобиться делать агрегатные выборки дублируете в РСУБД (с указателем на ключ). Т.о. Вы сохраните <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> key-value базы данных и сможете решить свою задачу. Сложность тут заключается в том, что Вам придется следить за синхронизацией данных в обоих базах данных, что может сильно усложнить логику приложения.</p>
<h4>Полнотекстовый поиск и выборки с задержками</h4>
<p>Одна из частых задач - полнотекстовый поиск. Существуют отличные решения - Sphinxsearch, Solr и другие. К сожалению, ни одно из них еще не поддерживает индексацию key-value баз данных, но зато все предоставляют интерфейсы для ручной индексации. Вам нужно будет только описать реализацию для конкретного набора данных (например, с помощью XmlPipe в Sphinx&#8217;e).</p>
<p>Наряду с полнотекстовым поиском часто стоят и задачи, связанные с агрегатными выборками, которые не критичны к текущему состоянию данных. Например, когда Вы строите рейтинг пользователей (или постов в блоге, или продуктов в магазине или &#8230;), Вы можете спокойно использовать данные по состоянию на прошлый час(день/неделю/&#8230;). В качестве решения Вы можете использовать полнотекстовые серверы по их непрямому назначению. Многие из них поддерживают разнообразные фильтры и сортировки, которых достаточно для решения 90% задач подобного рода.</p>
<h4>Распределенные выборки</h4>
<p>Некоторые key-value базы данных позволяют делать выборки списков встроенными средствами. Масштабирование этого решения будет выглядеть как запросы ко всем узлам сети и агрегирование результатов на бекенде. В крупных масштабах это может быть очень затратная операция, поэтому это решени слеудет оптимизировать. Во многих случаях Вы можете обойтись без запросов ко всем узлам, а сделать выборку только на одном из них (например - выбрать случайное фото).</p>
<p>Что еще сюда можно добавить?</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&title=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&title=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&title=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&t=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&title=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&u_data[name]=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/&title=NoSQL+-+%D0%BF%D0%BE%D0%B4%D1%85%D0%BE%D0%B4%D1%8B+%D0%BA+%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D1%8E+%D1%82%D0%B8%D0%BF%D0%B8%D1%87%D0%BD%D1%8B%D1%85+%D0%B7%D0%B0%D0%B4%D0%B0%D1%87+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2009/04/27/keyvalue-%d0%ba%d0%bb%d1%8e%d1%87%d0%b7%d0%bd%d0%b0%d1%87%d0%b5%d0%bd%d0%b8%d0%b5-%d0%b1%d0%b0%d0%b7%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85/' rel='bookmark' title='Permanent Link: Key=value (ключ=значение) базы данных'>Key=value (ключ=значение) базы данных</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/06/03/nosql-%d0%bf%d0%be%d0%b4%d1%85%d0%be%d0%b4%d1%8b-%d0%ba-%d1%80%d0%b5%d1%88%d0%b5%d0%bd%d0%b8%d1%8e-%d1%82%d0%b8%d0%bf%d0%b8%d1%87%d0%bd%d1%8b%d1%85-%d0%b7%d0%b0%d0%b4%d0%b0%d1%87/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Полнотекстовый поиск в MongoDB используя Sphinx</title>
		<link>http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/</link>
		<comments>http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/#comments</comments>
		<pubDate>Thu, 27 May 2010 11:07:28 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Tips and tricks]]></category>

		<category><![CDATA[mongo]]></category>

		<category><![CDATA[sphinx]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1103</guid>
		<description><![CDATA[ Многие из тех, кто успел попробовать MongoDB в действии, столкнулись с трудностями с полнотекстовым поиском. Встроенный механизм полнотекстового поиска в MongoDB (его так можно назвать с большой натяжкой) не пригоден для реальных потребностей.
Основная проблема заключается в том, что sphinx не позволяет использовать буквенно-цифровые значения в качестве ID документов. Есть несколько вариантов решения этой проблемы.


Строим [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/05/sphinx.jpg" alt="sphinx" title="sphinx" width="200" height="51" class="alignleft size-full wp-image-1104" /> Многие из тех, кто успел попробовать <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> в действии, столкнулись с трудностями с полнотекстовым поиском. Встроенный механизм полнотекстового поиска в <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> (его так можно назвать с большой натяжкой) не пригоден для реальных потребностей.</p>
<p>Основная проблема заключается в том, что sphinx не позволяет использовать буквенно-цифровые значения в качестве ID документов. Есть несколько вариантов решения этой проблемы.<br />
<!--CCXK9FK4MEZY--><br />
<span id="more-1103"></span></p>
<h2>Строим индекс с помощью xmlpipe</h2>
<p>Поскольку в Sphinx пока нет реализации источника данных для mongo, то придется использовать XMLpipe для индексации:</p>
<pre>
source src_test {
    type = xmlpipe
    xmlpipe_command = php /home/golotyuk/www/mongosphinx/index.php
}

index test {
        morphology              = stem_enru
        charset_type            = utf-8
        source                  = src_test
        path                    = /var/lib/sphinxsearch/data/test
}
</pre>
<p>Реализация XML генератора может быть приблизительно такая:</p>
<pre>
&lt;?='&lt;?xml version="1.0" encoding="utf-8"?>&lt;sphinx:docset>'?>

&lt;sphinx:schema>
&lt;sphinx:field name="content"/>
&lt;/sphinx:schema>

&lt;?

$m = new Mongo();
$c = $m->test->documents;
$list = $c->find();

?>

&lt;? foreach ( $list as $document ) { ?>
&lt;sphinx:document id="&lt;?=$document['numeric_id']?>">
&lt;content>&lt;![CDATA[[&lt;?=$document['text']?>]]&gt;&lt;/content>
&lt;/sphinx:document>
&lt;? } ?>

&lt;/sphinx:docset>
</pre>
<p>Все предельно просто кроме одной проблемы - ID mongo документа представлен в буквенно-цифровом виде, чего не понимает сфинкс. Есть несколько подходов:</p>
<h2>Решение проблемы с ID документа</h2>
<h4>Пользовательский ID</h4>
<p>Первый вариант - хранить в каждом mongo-документе пользовательский (сгенерированный руками) цифровой ID отдельным свойством:</p>
<pre>
{
	"_id" : ObjectId("4bf2c7f38ead0e0d05070000"),
	"sid" : 7,
	"text" : "Много текста"
}
</pre>
<p>В этом случае свойство sid будет использоваться для индексации в качестве ID документа (в примере выше атрибут называется &#8220;numeric_id&#8221;).</p>
<p>Неудобство этого решения заключается в ручной реализации всех примитивных функций касательно идентификатора - проверка на уникальность, инкремент, выборка по новому идентификатору. Поэтому данное решение лучше подойдет для статичных данных (справочная документация), но несколько усложнит динамику (форумы и т.п.).</p>
<p>В качестве альтернативного решения можно использовать таблицы соответствий ID документа Mongo и ID документа Sphinx (например в MySQL). В этом случае не нужно будет руками реализовывать механизм автоинкремента, но придется использовать дополнительную СУБД.</p>
<h4>Выборка ID, как атрибута</h4>
<p>ID mongo-документа можно выбирать как атрибут при индексации. Это наиболее верное решение, но учитывая, что атрибут строчный, понадобится обновиться до версии <b>0.9.10</b> (на этот момент эта версия еще не в релизе).</p>
<p>В этом случае Вам просто придется генерировать уникальные ID для сфинкса (которые будут фактически бесполезными для Вас - их можно генерировать на этапе индексации), а mongo ID доставать как свойство. Схема индекса будет следующая:</p>
<pre>
&lt;sphinx:schema>
&lt;sphinx:field name="content"/>
&lt;sphinx:attr name="_id" type="string"/>
&lt;/sphinx:schema>
</pre>
<p>Как видно, id mongo-документа описан как строчный атрибут. Для генерации id документа sphinx можно использовать простой инкремент, например:</p>
<pre>
&lt;? $i = 0; foreach ( $list as $document ) { ?>
&lt;sphinx:document <b>id="&lt;?=$i + 1?>"</b>>
&lt;content>&lt;![CDATA[[&lt;?=$document['text']?>]]&gt;&lt;/content>
&lt;_id>&lt;?=$document['_id']?>&lt;/_id>
&lt;/sphinx:document>
&lt;? } ?>
</pre>
<p>В результате sphinx будет возвращать атрибут &#8220;_id&#8221;, в котором будет находится идентификатор документа Mongo.</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&title=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&title=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&title=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&t=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&title=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&u_data[name]=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/&title=%D0%9F%D0%BE%D0%BB%D0%BD%D0%BE%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9+%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%B2+MongoDB+%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D1%83%D1%8F+Sphinx+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2009/06/25/%d0%b4%d0%b5%d0%bb%d1%8c%d1%82%d0%b0-%d0%b8%d0%bd%d0%b4%d0%b5%d0%ba%d1%81-%d0%b2-sphinx/' rel='bookmark' title='Permanent Link: Дельта индекс в Sphinx'>Дельта индекс в Sphinx</a></li><li><a href='http://highload.com.ua/index.php/2010/01/13/solr-%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%be%d1%82-apache-%d0%bd%d0%b0-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%b5-lucene/' rel='bookmark' title='Permanent Link: Solr - полнотекстовый поиск от Apache (на основе Lucene)'>Solr - полнотекстовый поиск от Apache (на основе Lucene)</a></li><li><a href='http://highload.com.ua/index.php/2009/11/30/sphinxsearch-index-merging/' rel='bookmark' title='Permanent Link: Sphinxsearch - объединение индексов (index merging)'>Sphinxsearch - объединение индексов (index merging)</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/feed/</wfw:commentRss>
		</item>
		<item>
		<title>memcache vs memached - сравниваем клиенты для PHP</title>
		<link>http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/</link>
		<comments>http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/#comments</comments>
		<pubDate>Fri, 07 May 2010 14:46:49 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Теория и практика]]></category>

		<category><![CDATA[memcached]]></category>

		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1074</guid>
		<description><![CDATA[
Какой клиент лучше использовать при разработке на PHP - php-memcached или php-memcache? Все зависит от того, какие особенности Вам нужны (неужели?). Давайте сравним в двух аспектах - функциональность и производительность.

Функциональность
Клиентская библиотека php-memcache была разработана еще в 2004 году и сегодня существует уже довольно стабильная версия, которая используется в 99.9% проектах (использующих сервер Memcache). Большим недостатком [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/05/performance.png" alt="performance" title="performance" width="126" height="75" class="alignleft size-full wp-image-1092" /></p>
<p>Какой клиент лучше использовать при разработке на PHP - php-memcache<strong style="color:red">d</strong> или php-memcache? Все зависит от того, какие особенности Вам нужны (неужели?). Давайте сравним в двух аспектах - функциональность и <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a>.<br clear="all" /><br />
<span id="more-1074"></span></p>
<h2>Функциональность</h2>
<p>Клиентская библиотека <a href="http://pecl.php.net/package/memcache"><strong>php-memcache</strong></a> была разработана еще в 2004 году и сегодня существует уже довольно стабильная версия, которая используется в 99.9% проектах (использующих сервер Memcache). Большим недостатком этой библиотеки является ее ограниченные способности - она реализует только часть протокола мемкеша, и не позволяет использовать его дополнительные возможности (какие именно - чуть ниже).</p>
<p>Библиотека <a href="http://pecl.php.net/package/memcached"><strong>php-memcached</strong></a> была разработана сравнительно недавно, но уже успешно используется на некоторых крупных проектах (например, digg.com - из которого и вышла эта разработка). Самое главное ее преимущество - это полная реализация протокола, в том числе:</p>
<ul>
<li><a href="http://www.php.net/manual/en/memcached.cas.php">CAS</a> токены для версионирования ключей</li>
<li>Обратные вызовы (callbacks)</li>
<li>Метод getDelayed() позволяющий уменьшить время ожидания откладывая фактическое чтение ключей</li>
<li>Поддержка бинарного протокола</li>
<li>Возможность избежать сериализации используя <a href="http://github.com/phadej/igbinary">igbinary</a></li>
</ul>
<h2>Производительность</h2>
<p>Теперь давайте сравним <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> на практике.<br />
Для этого напишем небольшой скрипт, который делает одинаковые операции с обоими клиентами:</p>
<pre>
&lt;?

$ops = 10000;

$m = new Memcache();
$m->addServer('localhost');

$md = new Memcached();
$md->addServer('localhost', 11211);

echo "Test operations: {$ops}";
echo "&lt;h3>get test&lt;/h3>";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ ) $m->get( md5(rand(1000, 99999)) );
echo "Memcache: " . ($res['memcache']['set'] = microtime(true) - $s ) . "&lt;br />";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ ) $md->get( md5(rand(1000, 99999)) );
echo "Memcached: " . ($res['memcached']['set'] = microtime(true) - $s );

echo "&lt;h3>set test&lt;/h3>";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ ) $m->set(md5(rand(1000, 99999)), 2);
echo "Memcache: " . ($res['memcache']['get'] = microtime(true) - $s ) . "&lt;br />";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ ) $md->set(md5(rand(1000, 99999)), 2);
echo "Memcached: " . ($res['memcached']['get'] = microtime(true) - $s );

echo "&lt;h3>delete test&lt;/h3>";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ ) $m->delete(md5(rand(1000, 99999)));
echo "Memcache: " . ($res['memcache']['delete'] = microtime(true) - $s ) . "&lt;br />";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ ) $md->delete(md5(rand(1000, 99999)));
echo "Memcached: " . ($res['memcached']['delete'] = microtime(true) - $s );

echo "&lt;h3>combined test&lt;/h3>";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ )
{
	$key = md5(rand(1000, 99999));
	$m->set($key, 2);
	$m->get($key);
	$m->delete($key);
}
echo "Memcache: " . ($res['memcache']['combined'] = microtime(true) - $s ) . "&lt;br />";

$s = microtime(true);
for ( $i = 0; $i &lt; $ops; $i++ )
{
	$key = md5(rand(1000, 99999));
	$md->set($key, 2);
	$md->get($key);
	$md->delete($key);
}
echo "Memcached: " . ($res['memcached']['combined'] = microtime(true) - $s );
</pre>
<p>Как видно, скрипт просто выполняет основные операции сохранения, чтения и удаления ключей 10 тыс. раз и замерает их время для каждого клиента.</p>
<h4>Результаты работы теста</h4>
<p><img src="http://chart.apis.google.com/chart?cht=bvg&#038;chs=590x250&#038;chd=t:0.40687584877014,0.4399950504303,0.39915299415588,1.1763441562653|1.1071889400482,1.1130468845367,1.0788090229034,3.1984331607819&#038;chds=0,120&#038;chco=4d89f9,c6d9fd&#038;chbh=5&#038;chds=0,5&#038;chbh=48,5,48&#038;chxs=0,000000,0,0,_&#038;chxt=x,x&#038;chm=N,000000,0,,10|N,000000,1,,10&#038;chxl=1:|set|get|delete|combined&#038;chdl=memcache|memcached&#038;chdlp=bv" /></p>
<p>Как видно из графика, <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> клиента <strong>php-memcache</strong> почти втрое выше, чем <strong>php-memcached</strong>. Следует учесть, что показатели при работе с бинарным протоколом почти не отличалась по времени от ASCII протокола.</p>
<h3 style="color: red">Обновление</h3>
<p>Благодаря внимательному читателю этого блога удалось выяснить, что сильные отличия в показателях тестов связаны с конкретными версиями и настройками библиотек. Проверка на других платформах дает отличие в <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a> не более 10%.</p>
<p>В качестве вывода следует сказать, что клиент <strong>php-memcache</strong> лучше использовать, если функционала приложению полностью хватает (лучше, т.к. он быстрее). Если нужны расширенные возможности, то нужно использовать <strong>php-memcached</strong>. Но в этом случае нужно учесть понижение <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a>.</p>
<p><em>Хотя важно заметить</em>: даже не смотря на трехкратное различие в скорости работы, операции общения с сервером Memcache обычно занимают доли процента от времени исполнения приложения. Различие в скорости работ библиотек может быть заметно только при массовой работе с кешом, или же на огромных объемах данных.</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&title=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&title=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&title=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&t=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&title=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&u_data[name]=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/&title=memcache+vs+memached+-+%D1%81%D1%80%D0%B0%D0%B2%D0%BD%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC+%D0%BA%D0%BB%D0%B8%D0%B5%D0%BD%D1%82%D1%8B+%D0%B4%D0%BB%D1%8F+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2009/08/05/memcache-multi-get-%d0%b7%d0%b0%d1%87%d0%b5%d0%bc/' rel='bookmark' title='Permanent Link: Memcached Multi-Get, зачем?'>Memcached Multi-Get, зачем?</a></li><li><a href='http://highload.com.ua/index.php/2009/04/28/%d1%82%d0%b2%d0%b8%d1%82%d1%82%d0%b5%d1%80-%d0%bd%d0%b0-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%b5-memcachedb-%d0%b8-php/' rel='bookmark' title='Permanent Link: Твиттер на основе MemcacheDB и PHP'>Твиттер на основе MemcacheDB и PHP</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/05/07/memcache-vs-memached-%d1%81%d1%80%d0%b0%d0%b2%d0%bd%d0%b8%d0%b2%d0%b0%d0%b5%d0%bc-%d0%ba%d0%bb%d0%b8%d0%b5%d0%bd%d1%82%d1%8b-%d0%b4%d0%bb%d1%8f-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Делаем ленту обновлений на MongoDB + PHP</title>
		<link>http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/</link>
		<comments>http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/#comments</comments>
		<pubDate>Sat, 24 Apr 2010 09:00:25 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Теория и практика]]></category>

		<category><![CDATA[mongo]]></category>

		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1038</guid>
		<description><![CDATA[
Вы, конечно, много раз видели ленту обновлений на фейсбуке и твиттере. В двух словах - это список событий, которые произошли недвано на сайте и касаются Вас (чаще всего это деятельность Ваших друзей). Это очень удобный инструмент информирования пользователей и неотъемлемая часть современных социальных проектов. А как обстоит дело с реализацией?
На первый взгляд все очень просто, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/04/rss.png" alt="Делаем ленту обновлений на MongoDB + PHP" title="Делаем ленту обновлений на MongoDB + PHP" width="252" height="148" class="alignleft size-full wp-image-1063" /></p>
<p>Вы, конечно, много раз видели ленту обновлений на фейсбуке и твиттере. В двух словах - это список событий, которые произошли недвано на сайте и касаются Вас (чаще всего это деятельность Ваших друзей). Это очень удобный инструмент информирования пользователей и неотъемлемая часть современных социальных проектов. А как обстоит дело с реализацией?</p>
<p>На первый взгляд все очень просто, а на практике все сложно. Давайте разберемся детально (на примере <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> + PHP, заодно посмотрим на эту новую шумную СУБД).<br />
<span id="more-1038"></span></p>
<h2>Что такое эта &#8220;лента обновлений&#8221;?</h2>
<p><img src="http://highload.com.ua/wp-content/uploads/2010/04/facebook_news_feed.jpg" alt="лента обновлений" title="лента обновлений" width="400" height="322" class="aligncenter size-full wp-image-1041" /></p>
<p>На этом скрине Вы видите ленту обновлений или &#8220;news feed&#8221; с фейсбука (facebook.com). Там представлены все события Ваших друзей.</p>
<p>Как будем делать? На первый взгляд все кажется довольно просто. У нас есть ограниченный набор действий (загрузить фото, обновить статус и т.п.). Для реализации подобной ленты новостей нужно выбрать все такие действия для каждого друга и отсортировать их по времени. Но сразу же становится видна недальновидность такого подхода:</p>
<ul>
<li>Очень тяжелые выборки в нескольких таблицах (выбрать все фотки, все статусы и т.п.)</li>
<li>Требуется дополнительная сортировка и агрегирование данных на стороне системы (а не СУБД)</li>
<li>Кеширование будет неоправданным, т.к. сделает ленту неактуальной</li>
<li>Решение не масштабируется (не возможен шардинг)</li>
</ul>
<p>Проведем небольшой анализ:</p>
<ol>
<li>Новые события в ленте могут появляться довольно динамично и <b>сразу должны становиться доступны</b> друзьям (загрузил фотку - друзья сразу об этом узнали). Тем не менее короткие задержки тут не критичны (в пределах минут).</li>
<li>Продвинутый функционал ленты обычно включает в себя управление приватностью (кто из друзей и какие действия может видеть)</li>
<li>Решение <b>должно горизонтально масштабироваться</b>. Учитывая то, что в больших системах количество генерируемых событий будет огромным, это самый важный момент</li>
</ol>
<h2>Архитектурное решение</h2>
<p>Для начала уйдем от необходимости собирать все события с разных таблиц. Создадим одну таблицу типа &#8220;обновления&#8221; и будем складывать туда <b>все</b> события с такой информацией:</p>
<ul>
<li>кто совершил действие (автор)</li>
<li>время действия</li>
<li>доп. данные о действии (напр., список загруженных фоток)</li>
</ul>
<p>Для генерации ленты обновлений нам нужно выбрать из этой таблицы все действия, совершенные друзьями пользователя:</p>
<pre>SELECT * FROM updates WHERE user_id IN (1,2,3,4) ORDER BY time DESC</pre>
<p>Тут 1,2,3,4 - это ID друзей пользователя</p>
<p>Уже лучше. Сортировку можно делать прямо на стороне СУБД, не нужно делать дополнительную агрегацию. Но остаются следующие проблемы:</p>
<ul>
<li>Таблица не шардится (ее невозможно разделить по какому-либо критерию для горизонтального <a href="http://highload.com.ua/index.php/tag/%D0%BC%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/" >масштабирования</a> ввиду неопределенности списков друзей)</li>
<li>Учитывая возможный большой размер таблицы, запросы к ней могут быть очень медленными</li>
<li>Если понадобится учитывать приватность сообщений, запросы будут крайне тяжелыми</li>
</ul>
<p>Опять не подойдет, думаем дальше:</p>
<h4>Генерация пользовательской ленты</h4>
<p>Необходимо устранить всякую записимость генерации ленты от количества данных и сложности функционала. Это возможно только тогда, когда мы для каждого пользователя генерируем ленту на лету. Т.е. при очередном событии делаем следующее:</p>
<ol>
<li>Выбераем список друзей пользователя</li>
<li>Проверяем правила приватности для каждого из них</li>
<li>Вставляем событие в персональную ленту тем, кому нужно</li>
</ol>
<p>В этом случае мы избавляемся от проблемы медленной генерации ленты, т.к. ее теперь не нужно генерировать. Мы просто читаем ее из СУБД (элементарный запрос, никаких преобразований). Самое важное - пользовательская лента теперь на 100% персональная (из нее даже можно что-нибудь удалить, не затронув остальных пользователей).</p>
<p>Но теперь при каждом событии будет выполняться довольно много операций проверок и вставки события в нужную ленту. Это может очень замедлить работу сайта. Выход очень простой. Все эти действия очень хорошо подходят для выполения на фоне (смотрите <a href="http://highload.com.ua/index.php/tag/очереди-сообщений/">очереди сообщений</a>). Например:</p>
<ol>
<li>Пользователь загружает фотку</li>
<li>Обрабатываем его запрос, сохраняем фото и отправляем пользователю ответ</li>
<li>В фоне (асинхронно) выполняем обработку события и обновляем ленты его друзей</li>
</ol>
<h2>Платформа</h2>
<p>Для управления лентами нам понадобятся простые операции работы со списками: добавить/удалить элемент, сортировка и возможно фильтрация.<br />
Понятно, что использовать тяжелую СУБД, такую как MySQL, нецелесообразно для таких простых операций. Очень хорошо в этом случае подойдет, например, <a href="http://highload.com.ua/index.php/2009/05/01/redis/" >Redis</a> или же <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a>.</p>
<p>В этом примере мы рассмотрим реализацию на основе <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a>. Для хранения ленты будем использовать внутренний массив документа. В качестве клиентской реализации используем <a href="http://php.net/mongo" target="_blank">PHPMongo</a>.</p>
<p>Для выполнения задач на фоне можно использовать любую удобную систему очередей (например, <a href="http://www.rabbitmq.com/" target="_blank">RabbitMQ</a>).</p>
<h2>Пример</h2>
<p>Для начала опишем главную функцию - вывод ленты обновлений (функцию <b>get_feed()</b> опишем позже):</p>
<pre>
&lt;?
# Получаем ленту
# $user_id содержит идентификатор текущего пользователя
$feed = get_feed($user_id);

echo "&lt;h3>Что делают Ваши друзья&lt;/h3>";

# Выводим все события из ленты
foreach ( $feed as $feed_item )
{
	# Время, имя пользователя и текст события
	echo "{$feed_item['time']} :: {$feed_item['user_name']} {$feed_item['text']}&lt;br />";
}
</pre>
<h4>Обновление ленты</h4>
<p>Теперь посмотрим, как будет выглядет типичное действие, которое обновляет ленты друзей пользователя. Например, пользователь меняет свой статус. Обработчик будет выглядеть следующим образом:</p>
<pre>
&lt;?
$status = $_POST['status'];

# коннектимся к Mongo (по умолчанию - localhost:27017)
$m = new Mongo();

# Обновляем статус пользователя (БД user, коллекция status)
# "'upsert' => true" - вставить запись, если ее нет
$m->user->status->update(
	array('user_id' => $user_id),
	array('$set' => array('status' => $status)),
	array('upsert' => true)
);

# Регистрируем событие для лент (реализация дальше)
update_feed($user_id, 'обновил статус: ' . $status );
</pre>
<h4>Регистрация события</h4>
<p>В предыдущем кусочке кода функция <strong>update_feed()</strong> регистрировала событие для добавления в ленты друзей. Реализация этой функции будет следующая:</p>
<pre>
&lt;?
function update_feed($user_id, $text )
{
	# Получаем список друзей пользователя
	$friends = get_friends($user_id);

	$m = new Mongo();	

	# Вставляем событие каждому другу в ленту
	foreach ( $friends as $id )
	{
		# Получаем имя друга
		$user_name = get_user_name($id);

		# $data = array(
			'time' => date('H:i (m.d)'),
			'user_name' => $user_name,
			'text' => $text
		);

		# Вставляем событие в массив Mongo-объекта "list"
		# БД user, коллекция feed
		$m->user->feed->update(
			array('user_id' => $user_id),
			array('$push' => array('list' => $data)),
			array('upsert' => true)
		);
	}
}
</pre>
<h4>Чтение ленты</h4>
<p>Осталось описать функцию чтения ленты для пользователя:</p>
<pre>
&lt;?
function get_feed($user_id)
{
	$m = new Mongo();	

	# Выбираем события из БД
	$data = $m->user->feed->findOne( array('user_id' => $user_id) );

	return $data['list'];
}
</pre>
<h2>Некоторые замечания</h2>
<p>Нужно следить, чтобы количество элементов в массиве не росло очень сильно (например, сотни тысяч), иначе объекты будут очень тяжелыми. Массивы необходимо периодически обрезать (пока в <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> нет удобного механизма это делать - надеюсь, появится).</p>
<p>Для реализации приватности необходимо в функцию <strong>update_feed()</strong> добавить функционал по проверке прав доступа для каждого пользователя.</p>
<p>В <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> пока довольно ограниченный набор функционала с вложенными массивами, поэтому фильтрацию ленты (если понадобится) придется делать на стороне PHP. Будем следить за развитием <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a>.</p>
<p>Не забудьте поставить индексы на колонки по которым делаете выборки в Mongo (<a href="http://www.mongodb.org/display/DOCS/Indexes" target="_blank">как это делать?</a>).</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&title=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&title=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&title=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&t=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&title=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&u_data[name]=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/&title=%D0%94%D0%B5%D0%BB%D0%B0%D0%B5%D0%BC+%D0%BB%D0%B5%D0%BD%D1%82%D1%83+%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B9+%D0%BD%D0%B0+MongoDB+%2B+PHP+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2010/05/27/%d0%bf%d0%be%d0%bb%d0%bd%d0%be%d1%82%d0%b5%d0%ba%d1%81%d1%82%d0%be%d0%b2%d1%8b%d0%b9-%d0%bf%d0%be%d0%b8%d1%81%d0%ba-%d0%b2-mongodb-%d0%b8%d1%81%d0%bf%d0%be%d0%bb%d1%8c%d0%b7%d1%83%d1%8f-sphinx/' rel='bookmark' title='Permanent Link: Полнотекстовый поиск в MongoDB используя Sphinx'>Полнотекстовый поиск в MongoDB используя Sphinx</a></li><li><a href='http://highload.com.ua/index.php/2009/04/28/%d1%82%d0%b2%d0%b8%d1%82%d1%82%d0%b5%d1%80-%d0%bd%d0%b0-%d0%be%d1%81%d0%bd%d0%be%d0%b2%d0%b5-memcachedb-%d0%b8-php/' rel='bookmark' title='Permanent Link: Твиттер на основе MemcacheDB и PHP'>Твиттер на основе MemcacheDB и PHP</a></li><li><a href='http://highload.com.ua/index.php/2009/10/06/php-redis-%d0%bf%d0%bb%d0%b0%d1%82%d1%84%d0%be%d1%80%d0%bc%d0%b0-%d0%ba%d0%bb%d1%8e%d1%87%d0%b7%d0%bd%d0%b0%d1%87%d0%b5%d0%bd%d0%b8%d0%b5/' rel='bookmark' title='Permanent Link: PHP + Redis платформа &#8220;Ключ=Значение&#8221;'>PHP + Redis платформа &#8220;Ключ=Значение&#8221;</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/04/24/%d0%b4%d0%b5%d0%bb%d0%b0%d0%b5%d0%bc-%d0%bb%d0%b5%d0%bd%d1%82%d1%83-%d0%be%d0%b1%d0%bd%d0%be%d0%b2%d0%bb%d0%b5%d0%bd%d0%b8%d0%b9-%d0%bd%d0%b0-mongodb-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nginx + Memcached + SSI - кеширование страниц и блоков (partials)</title>
		<link>http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/</link>
		<comments>http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 15:40:17 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Теория и практика]]></category>

		<category><![CDATA[memcached]]></category>

		<category><![CDATA[nginx]]></category>

		<category><![CDATA[кеширование]]></category>

		<category><![CDATA[оптимизация]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=1005</guid>
		<description><![CDATA[
В одной из предыдущих статей мы рассмотрели, каким образом можно реализовать кеширование страниц с помощью Varnish и ESI. В этой статье рассмотрим альтернативное решение - на основе двух суперзнаменитых продуктов - nginx и memcached.
Оба не нуждаются в представлении, а о том, как на основе их можно значительно увеличить эффективность работы Вашего сайта, поговорим ниже.

Зачем нужно [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://highload.com.ua/wp-content/uploads/2010/04/nginx-logo.png" alt="nginx-logo" title="nginx-logo" width="250" height="64" class="alignleft size-full wp-image-1008" /></p>
<p>В одной из предыдущих статей мы рассмотрели, каким образом можно реализовать <a href="http://highload.com.ua/index.php/2010/01/22/кеширование-страниц-ускоряем-сайт-в-100/">кеширование страниц с помощью Varnish и ESI</a>. В этой статье рассмотрим альтернативное решение - на основе двух суперзнаменитых продуктов - <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >nginx</a> и <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a>.<br />
Оба не нуждаются в представлении, а о том, как на основе их можно значительно увеличить эффективность работы Вашего сайта, поговорим ниже.</p>
<p><span id="more-1005"></span></p>
<h2>Зачем нужно кешировать страницы?</h2>
<p>Довольно детально принципы кеширования страниц и блоков были рассмотрены в <a href="http://highload.com.ua/index.php/2010/01/22/кеширование-страниц-ускоряем-сайт-в-100/">предыдущей статье (Varnish + ESI)</a>.</p>
<p>В качестве краткого повторения, несколько основных идей и преимуществ кеширования на уровне странц:</p>
<ul>
<li>Кешируя страницы на отдающем сервере, Вы освобождаете ощутимое количество ресурсов на бекендах</li>
<li>В случае медленных страниц, значительно уменьшается время ожидания страниц Вашего сайта (ускоряется его работа)</li>
<li><em>Как показывает практика, во многих случаях внедрять систему кеширования странц в <strong>готовый проект</strong> легче, чем систему кеширования запросов</em></li>
</ul>
<h2>Nginx и memcached</h2>
<p><a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >Nginx</a> позволяет читать данные из Мemcached - для этого Вам необходим модуль <a target="_blank" href="http://wiki.nginx.org/NginxHttpMemcachedModule">HttpMemcachedModule</a>.</p>
<p>Самый простой пример - проверяем есть ли страница в кеше и, если есть, достаем из кеша, иначе - делаем запрос к бекенду.</p>
<pre>
server {
  location / {
    set $memcached_key $uri; # Ключ для проверки в <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a>
    memcached_pass     127.0.0.1:11211; # Параметры подключения
    default_type       text/html; # Заголовок по умолчанию
    error_page         404 = @fallback; # 404 - данные в кеше не найдены
  }

  location @fallback {
    proxy_pass backend; # Бекенд
  }
}
</pre>
<p>В данный момент <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >Nginx</a> не умеет сохранять значения в <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a> - только читать данные. Значит задача по сохранению страниц в кеш ложится на бекенд. Выглядит это приблизительно так (PHP):</p>
<pre>
&lt;?
$memcache = new Memcache();
# какой-то код

ob_start();
# визуализация страницы - html
$html = ob_get_clean();

$memcache->set($_SERVER['REQUEST_URI'], $html);
echo $html;
?>
</pre>
<h2>Кеширование блоков и SSI</h2>
<p>Если у Вас не самый примитивный сайт (а он у Вас не такой), логика кеширования страниц будет несколько усложнена различными динамическими элементами страницы (блок авторизации, динамическое меню и т.п.). Подобные задачи решаются c помощью SSI - server side includes. Кроме всего прочего использование SSI экономит память, т.к. для каждой страницы Вы не будете хранить ее исходник целиком, а только внутреннюю (изменяемую) часть.</p>
<p>Синтаксис SSI очень простой и выглядит так:</p>
<pre>
&lt;!--# include virtual="/authentication.php" --&gt;
</pre>
<p>Следует отметить, что SSI - это уровень Web сервера. Для прилжения этот механизм полностью прозрачен. В приведенном примере, на месте вызова SSI, Web сервер (<a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >nginx</a>) просто сделает еще один запрос к бекенду. Например, если у Вас два SSI вызова на страницу, то клиентский запрос к каждой странице будет генерировать три запроса к бекенду. Конечно, само по себе это бессмысленно, но в связке с кешированием представляет из себя мощный инструмент <a href="http://highload.com.ua/index.php/tag/%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F/" >оптимизации</a> систем.</p>
<h2>Практический пример</h2>
<p>Теперь соберем все выше изложенное в последовательный рецепт решения рассматриваемой задачи.</p>
<p>Для начала Вам необходимо выделить блоки в Вашем базовом (глобальном) шаблоне и заменить их вызовами SSI. Пример на PHP:</p>
<pre>
&lt;html>
&lt;body>

&lt;h1>Тестируем nginx + memcached + ssi&lt;/h1>

&lt;div class="auth">
<!--Блок авторизации!-->
&lt;!--# include virtual="/authentication.php" --&gt;
&lt;/div>

<!--Тело конкретной страницы!-->
&lt;!--# include virtual="/somepage.php" --&gt;

&lt;/body>
&lt;/html>
</pre>
<p>Как видно, на странице есть два блока - блок авторизации и контентный блок (содержимое странички). В нашем примере блок авторизации будет персональным (допустим, после входа, там будет имя пользователя). Блок содержимого не будет персональным (т.е. он будет общим для всех пользователей).</p>
<p>Теперь необходимо настроить <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >nginx</a> для обработки SSI вызовов и использованию <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a>:</p>
<pre>
# Upstream бекенда
upstream backend {
    server 127.0.0.1:8081;
}

server {
	listen 80;
	server_name test.com;

	root /var/www/test;
	index index.php;

	location / {
		# Все POST запросы отправляем на бекенд (не кешируя)
		if ($request_method = POST) {
			proxy_pass http://backend;
			break;
	        }

		# Включаем обработку SSI
		ssi on;
		default_type text/html;

		# Проверяем в мемкеше
		set $memcached_key "$uri";
		memcached_pass localhost:11211;
		proxy_intercept_errors  on;
		error_page 404 502 = @process;
	}

	# Сюда запрос приходит, если его небыло в кеше
	location @process
	{
		proxy_pass http://backend;
		ssi on;
	}
}

# Обычный бекенд
server {
	listen 8081;

	location ~* \.(php)$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/test$fastcgi_script_name;
    }
}
</pre>
<p>Следующим шагом в приложении необходимо будет реализовать сохранение исходников страниц в <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a>.</p>
<h4>Кеширование персонализированных блоков</h4>
<p>Ясно, что для кеширования персонализированных блоков необходимо добавить идентификатор пользователя (не вздумайте использовать внутренний ID пользователя) в ключ <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a>. SSI вызов необходимо пометить, чтобы отличать персональные блоки от общих. Т.е. персональный вызов SSI будет иметь такой вид:</p>
<pre>
<!--Блок авторизации!-->
&lt;!--# include virtual="/uid/authentication.php" --&gt;
&lt;/div>
</pre>
<p>Для генерации <a href="http://highload.com.ua/index.php/2009/04/21/memcached/" >memcached</a> ключей с идентификатором пользователя можно использовать куки (устанавливать его будет приложение при авторизации пользователя):</p>
<pre>
set $memcached_key "$uri:$cookie_uid";
</pre>
<p>Соответственно, необходимо в <a href="http://highload.com.ua/index.php/2009/04/23/nginx/" >nginx</a> добавить обработчик для &#8220;/uid&#8221; запросов:</p>
<pre>
        location /uid {
                ssi on;
                default_type text/html;

                set $memcached_key "$uri:$cookie_uid";
                memcached_pass localhost:11211;
                proxy_intercept_errors  on;
                error_page 404 502 = @process;
        }
</pre>
<p>Естественно, в самом приложении все &#8220;/uid&#8221; запросы должны кешироваться с идентификатором пользователя:</p>
<pre>
$m->set($_SERVER['REQUEST_URI'] . ':' . $_COOKIE['uid'], $html);
</pre>
<h3>Следует обратить внимание</h3>
<p>Недавно появился продукт, который должен стать типичным решением при кешировании страниц - <a href="http://code.google.com/p/twicecache/" target="_blank">Twicecache</a>. Пока он на очень ранней стадии и доступны только его исходники. Будем внимательно следить.</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&title=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&title=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&title=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&t=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&title=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&u_data[name]=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/&title=Nginx+%2B+Memcached+%2B+SSI+-+%D0%BA%D0%B5%D1%88%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86+%D0%B8+%D0%B1%D0%BB%D0%BE%D0%BA%D0%BE%D0%B2+%28partials%29+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2010/01/22/%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d1%83%d1%81%d0%ba%d0%be%d1%80%d1%8f%d0%b5%d0%bc-%d1%81%d0%b0%d0%b9%d1%82-%d0%b2-100/' rel='bookmark' title='Permanent Link: Кеширование страниц - ускоряем сайт в 100 раз (Varnish + ESI)'>Кеширование страниц - ускоряем сайт в 100 раз (Varnish + ESI)</a></li><li><a href='http://highload.com.ua/index.php/2009/04/24/%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-nginx/' rel='bookmark' title='Permanent Link: Настройка nginx'>Настройка nginx</a></li><li><a href='http://highload.com.ua/index.php/2009/05/09/%d1%80%d0%b5%d1%81%d0%b0%d0%b9%d0%b7%d0%b8%d0%bd%d0%b3-%d0%ba%d0%b0%d1%80%d1%82%d0%b8%d0%bd%d0%be%d0%ba-%d0%b2-nginx/' rel='bookmark' title='Permanent Link: Ресайзинг картинок в nginx'>Ресайзинг картинок в nginx</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/04/06/nginx-memcached-ssi-%d0%ba%d0%b5%d1%88%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%81%d1%82%d1%80%d0%b0%d0%bd%d0%b8%d1%86-%d0%b8-%d0%b1%d0%bb%d0%be%d0%ba%d0%be%d0%b2-partials/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sysbench - тестируем производительность MySQL и платформы</title>
		<link>http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/</link>
		<comments>http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 13:49:05 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Технологии]]></category>

		<category><![CDATA[mysql]]></category>

		<category><![CDATA[sysbench]]></category>

		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=976</guid>
		<description><![CDATA[Sysbench - утилита для тестирования производительности MySQL (и других СУБД), а также параметров операционной системы. Подобный инструмент незаменим для предварительного тестирования эффективности системы с (потенциально) высокой нагрузкой. Sysbench позволяет оценить производительность сервера СУБД и операционной системы в различных условиях при различной нагрузке.


Особенности sysbench
Из преимуществ этого продукта следует отметить его простоту, гибкость, а также:

Кроссплатформенность
Мультипоточность
Набор тестов для [...]]]></description>
			<content:encoded><![CDATA[<p><b>Sysbench</b> - утилита для тестирования <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a> MySQL (и других СУБД), а также параметров операционной системы. Подобный инструмент незаменим для предварительного тестирования эффективности системы с (потенциально) высокой нагрузкой. Sysbench позволяет оценить <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> сервера СУБД и операционной системы в различных условиях при различной нагрузке.</p>
<p><span id="more-976"></span></p>
<p><br clear="all" /></p>
<h2>Особенности sysbench</h2>
<p>Из преимуществ этого продукта следует отметить его простоту, гибкость, а также:</p>
<ul>
<li>Кроссплатформенность</li>
<li>Мультипоточность</li>
<li>Набор тестов для параметров уровня ОС (память, файловая система, процессор и т.п.)</li>
</ul>
<p>Другими словами эта утилита нужна для решения следующих задач:</p>
<ul>
<li>Тестирование параметры ОС (даже без установки СУБД) для предварительной их оценки и последующей настройке</li>
<li>Проверка <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a> СУБД с различной конфигурацией и нагрузкой</li>
</ul>
<p><br clear="all" /></p>
<h2>Установка</h2>
<p>Эта популярная утилита присутствует в пакетах многих дистрибутивов, поэтому:</p>
<pre>sudo apt-get install sysbench</pre>
<p>Или собираем из исходников (<a href="http://sf.net/projects/sysbench/" target="_blank">скачать можно тут</a>):</p>
<pre>
./configure
make
make install
</pre>
<p>После этого утилита готова к работе.</p>
<p><br clear="all" /></p>
<h2>Обзор функциональности</h2>
<p>Синтаксис вызова утилиты:</p>
<pre>sysbench --test=имя-теста [опции] команда</pre>
<p>Команды, которые можно использовать в тестах:</p>
<ul>
<li><b>prepare</b> - подготовка теста (создание таблиц, вставка данных и т.п.) если актуально</li>
<li><b>run</b> - выполнение теста</li>
<li><b>cleanup</b> - очистка данных (после этапа подготовки)</li>
<li><b>help</b> - выводит дополнительные параметры теста</li>
</ul>
<p>Параметр &#8220;&#8211;test&#8221; задает имя теста, который следует выполнять. Sysbench включает в себя несколько тестов:</p>
<h4>cpu</h4>
<p>Этот тест проверит <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> процессоров, используя вычисления с 64-разрядными числами. Например:</p>
<pre>sysbench --test=cpu --cpu-max-prime=20000 run</pre>
<h4>memory</h4>
<p>Этот тест служит для измерения <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a> последовательных операций чтения/записи в оперативную память.</p>
<h4>fileio</h4>
<p>Этот тест используется для симуляции разнообразной нагрузки на файловую подсистему. При подготовке теста создается определенное количество файлов (указанного размера). Затем, при выполнении теста, над этими файлами происходят операции чтения/записи в несколько потоков.</p>
<pre>
sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw prepare
sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw run
sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw cleanup
</pre>
<h4>threads</h4>
<p>Служит для проверки работы в условиях большого количества конкурирующих потоков. Тест заключается в создании нескольких потоков и нескольких <a href="http://en.wikipedia.org/wiki/Mutual_exclusion">мутексов</a>. Далее каждый поток начинает генерировать запросы, которые блокируют мутекс, исполняют процессорные задачи (для симуляции реальной работы) и разблокируют мутекс.</p>
<pre>sysbench --num-threads=64 --test=threads --thread-yields=100 --thread-locks=2 run</pre>
<h4>oltp (Online transaction processing)</h4>
<p>Этот тест служит для оценки <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a> СУБД, о нем подробнее дальше:</p>
<p><br clear="all" /></p>
<h2>OLTP тестирование - производительность MySQL</h2>
<p>Этот тест проводится в несколько этапов. На этапе <b>prepare</b создается тестовая таблица и заполняется данными (в указанных количествах). Например:</p>
<pre>sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp prepare</pre>
<p>Эта операция создаст innoDB таблицу на 10000 записей. По умолчанию таблица создается в базе данных sbtest (не забудьте создать эту БД либо указать другую).</p>
<p>Далее выполняются тесты:</p>
<pre>sysbench --num-threads=8 --max-requests=500 --oltp-table-size=10000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp run</pre>
<p>Эта команда выполнит тест с 8 клиентами (максимальное количество запросов - 500) на таблице, которая была создана на предыдущем этапе. После окончания теста не забудьте выполнить команду <strong>cleanup</strong>. После выполнения Вы увидите подробные результаты тестирования. Далее - живой пример.</p>
<h2>Пример</h2>
<p>Посмотрим на <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительность</a> innoDB таблицы с разными значениями конфигурационных параметров (проведем эксперимент со сбросом лога). Для начала подготовим innoDB таблицу (50 тыс. записей):</p>
<pre>sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=50000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp prepare</pre>
<p>.</p>
<p>Включим сброс лога на диск после каждой транзакции (используем стандартный метод сброса лога):</p>
<pre>
innodb_flush_log_at_trx_commit = 1
innodb_flush_method=fdatasync
</pre>
<p>Выполним тест:</p>
<pre>sysbench --num-threads=8 --max-requests=1000 --oltp-table-size=50000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp run</pre>
<p>И увидим следующие результаты:</p>
<pre>
OLTP test statistics:
    queries performed:
        read:                            14000
        write:                           5000
        other:                           2000
        total:                           21000
    <b>transactions:                        1000   (263.49 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 19000  (5006.24 per sec.)
    other operations:                    2000   (526.97 per sec.)</b>

Test execution summary:
    total time:                          3.7953s
    total number of events:              1000
    total time taken by event execution: 30.2361
    per-request statistics:
         min:                                  4.80ms
         avg:                                 30.24ms
         max:                                 53.01ms
         approx.  95 percentile:              33.07ms

Threads fairness:
    events (avg/stddev):           125.0000/0.00
    execution time (avg/stddev):   3.7795/0.01
</pre>
<p>Убедимя, что пропускная способность операций чтения/записи около 5 тыс в секунду. Теперь изменим параметры сброса лога:</p>
<pre>
innodb_flush_log_at_trx_commit = 0
innodb_flush_method=O_DIRECT
</pre>
<p>и проверим результаты:</p>
<pre>
OLTP test statistics:
    queries performed:
        read:                            14000
        write:                           5000
        other:                           2000
        total:                           21000
    <b>transactions:                        1000   (485.37 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 19000  (9222.00 per sec.)
    other operations:                    2000   (970.74 per sec.)</b>

Test execution summary:
    total time:                          2.0603s
    total number of events:              1000
    total time taken by event execution: 16.4255
    per-request statistics:
         min:                                  2.69ms
         avg:                                 16.43ms
         max:                                235.49ms
         approx.  95 percentile:              42.15ms

Threads fairness:
    events (avg/stddev):           125.0000/6.16
    execution time (avg/stddev):   2.0532/0.00
</pre>
<p>Убеждаемся, что во втором случае пропускная способность СУБД вдвое выше, чем в первом (о параметрах подробнее в статье <a href="http://highload.com.ua/index.php/2009/04/23/оптимальная-настройка-mysql-сервера/">Оптимальная настройка Mysql сервера</a>).</p>
<p><br clear="all" /></p>
<h2>Альтернативные утилиты</h2>
<p>Кроме <strong>Sysbench</strong>, есть еще ряд инструментов, на который следует обратить внимание:</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/mysql-benchmarks.html" target="_blank">MySQL Benchmark Suite (“sql-bench”)</a> - входит в стандартную поставку MySQL (Perl)</li>
<li><a href="http://vegan.net/tony/supersmack/" target="_blank">Super Smack</a> - утилита для стресс тестирования/генерации нагрузки для MySQL</li>
<li><a href="http://jeremy.zawodny.com/mysql/mybench/" target="_blank">Mybench</a> - маленькая и простая утилита для тестирования <a href="http://highload.com.ua/index.php/tag/%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C/" >производительности</a> (Perl)</li>
</ul>
<p><br clear="all" /></p>
<h2>Ссылки</h2>
<p><a href="http://sysbench.sourceforge.net" target="_blank">Официальный сайт Sysbench</a></p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&title=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&title=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&title=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&t=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&title=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&u_data[name]=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/&title=Sysbench+-+%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D1%83%D0%B5%D0%BC+%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C+MySQL+%D0%B8+%D0%BF%D0%BB%D0%B0%D1%82%D1%84%D0%BE%D1%80%D0%BC%D1%8B+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/' rel='bookmark' title='Permanent Link: Mongo DB - документо-ориентированная база данных и MySQL'>Mongo DB - документо-ориентированная база данных и MySQL</a></li><li><a href='http://highload.com.ua/index.php/2009/11/26/check-unused-keys-proverka-neispolzuemyh-indeksov-mysql/' rel='bookmark' title='Permanent Link: check-unused-keys - проверка неиспользуемых индексов в MySQL'>check-unused-keys - проверка неиспользуемых индексов в MySQL</a></li><li><a href='http://highload.com.ua/index.php/2009/07/28/maatkit-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8-mysql/' rel='bookmark' title='Permanent Link: Maatkit - расширенные возможности MySQL'>Maatkit - расширенные возможности MySQL</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Mongo DB - документо-ориентированная база данных и MySQL</title>
		<link>http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/</link>
		<comments>http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 17:37:00 +0000</pubDate>
		<dc:creator>Den Golotyuk</dc:creator>
		
		<category><![CDATA[Технологии]]></category>

		<category><![CDATA[mongo]]></category>

		<category><![CDATA[mysql]]></category>

		<category><![CDATA[производительность]]></category>

		<category><![CDATA[СУБД]]></category>

		<guid isPermaLink="false">http://highload.com.ua/?p=958</guid>
		<description><![CDATA[
Одним из основных принципов разработки масштабируемых и эффективных приложений является выбор подходящих технологий для решения той или иной задачи. Многие современные РСУБД представляют из себя решения универсальные, но во многих случаях в них просто нет необходимости.
Одним из альтернативных решений для хранения и обработки данных является СУБД Mongo DB (&#8221;humongous&#8221; - огромный, невероятный).

Что такое Mongo DB?
Mongo [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-959" title="screenshot-home-mongodb-10gen-confluence-chromium" src="http://highload.com.ua/wp-content/uploads/2010/03/screenshot-home-mongodb-10gen-confluence-chromium.png" alt="screenshot-home-mongodb-10gen-confluence-chromium" width="242" height="116" /></p>
<p>Одним из основных <a href="http://highload.com.ua/index.php/2009/08/12/масштабирование-и-производительност/">принципов разработки масштабируемых и эффективных приложений</a> является выбор подходящих технологий для решения той или иной задачи. Многие современные РСУБД представляют из себя решения универсальные, но во многих случаях в них просто нет необходимости.</p>
<p>Одним из альтернативных решений для хранения и обработки данных является СУБД Mongo DB (&#8221;hu<strong>mongo</strong>us&#8221; - огромный, невероятный).</p>
<p><span id="more-958"></span></p>
<h2>Что такое Mongo DB?</h2>
<p><strong>Mongo DB</strong> - высокопроизводительная документо-ориентированная база данных. Особенности этой СУБД:</p>
<ul>
<li>Документное хранилище, не требующее создания схем (таблиц)</li>
<li>Запросы в стиле JSON (очень удобно)</li>
<li>Широкий набор (атомарных) операций над данными (условный поиск, сложная вставка/обновление и т.п.)</li>
<li>Разные типы данных (поддержка массивов)</li>
<li>Поддержка индексов (B-Tree)</li>
<li>Автовосстановление, шардинг и репликация в коробке</li>
<li>Профилирование, хранение больших объектов, административный интерфейс, серверные функции, Map/Reduce и многое другое</li>
</ul>
<h2>Mongo DB и MySQL</h2>
<p>Многое из вышеперечисленного есть и в решениях более знакомых, таких, как MySQL. Давайте сравнивать:</p>
<table class='confluenceTable'>
<tbody>
<tr>
<th class='confluenceTh'>&nbsp;</th>
<th class='confluenceTh'> <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> </th>
<th class='confluenceTh'> MySQL </th>
</tr>
<tr>
<td class='confluenceTd'> Модель данных </td>
<td class='confluenceTd'> Документная </td>
<td class='confluenceTd'> Реляционная </td>
</tr>
<tr>
<td class='confluenceTd'> Типы </td>
<td class='confluenceTd'> string, int, double, boolean, date, bytearray, object, array </td>
<td class='confluenceTd'> <a href="http://dev.mysql.com/doc/refman/5.0/en/data-types.html" target="_blank">Типы MysQL</a> </td>
</tr>
<tr>
<td class='confluenceTd'> Большие объекты </td>
<td class='confluenceTd'> Да </td>
<td class='confluenceTd'> Да </td>
</tr>
<tr>
<td class='confluenceTd'> Репликация </td>
<td class='confluenceTd'> Master-slave </td>
<td class='confluenceTd'> Master-slave </td>
</tr>
<tr>
<td class='confluenceTd'> Хранилище наборов данных </td>
<td class='confluenceTd'> Коллекции </td>
<td class='confluenceTd'> Таблицы </td>
</tr>
<tr>
<td class='confluenceTd'> Метод запросов </td>
<td class='confluenceTd'> объектный язык запросов </td>
<td class='confluenceTd'> SQL </td>
</tr>
<tr>
<td class='confluenceTd'> Дополнительные индексы </td>
<td class='confluenceTd'> Да </td>
<td class='confluenceTd'> Да </td>
</tr>
<tr>
<td class='confluenceTd'> Атомарность </td>
<td class='confluenceTd'> Документ </td>
<td class='confluenceTd'> Расширенная </td>
</tr>
<tr>
<td class='confluenceTd'> Манипулирование наборами данных на сервере </td>
<td class='confluenceTd'> Map/Reduce, серверный javascript </td>
<td class='confluenceTd'> SQL </td>
</tr>
<tr>
<td class='confluenceTd'> Платформа </td>
<td class='confluenceTd'> C+&#43; </td>
<td class='confluenceTd'> C </td>
</tr>
<tr>
<td class='confluenceTd'> Контроль конкурентности (Concurrency Control) </td>
<td class='confluenceTd'> Update in Place </td>
<td class='confluenceTd'>MVCC</td>
</tr>
</tbody>
</table>
<p>Итак преимущества Mongo:</p>
<ul>
<li>Объектный язык запросов (который намного легче SQL, что является важным преимуществом для большинства задач, не требующих сложных выборок)</li>
<li>Поддержка Map/Reduce для распределенных операций над данным</li>
<li>Документы, не требующие определения схемы. Одно из самых важных преимуществ. Преимущество заключается в том, что у Вас нет нужды хранить пустые ячейки данных в каждом документе.</li>
<li>Поддержка сложных массивов. Каждый элемент массива может представлять из себя объект</li>
<li>Поддержка шардинга на уровне платформы</li>
</ul>
<h2>Производительность</h2>
<p>Для тестирования возьмем таблицу в MySQL (messages) с простой структурой (таблица личных сообщений пользователей одного из моих проектов). Количество записей в ней - около 200 тыс. Все данные скопированны в mongo с соотв. индексами.</p>
<p>Для тестирования будем использовать следующий скрипт:</p>
<pre>
&lt;?php
$m = new Mongo();
$col = $m->messages->threads;

$s = microtime(true);
for ( $i = 0; $i < 5000; $i++ )
        $cursor = $col->find( array('user_id' => $i) );

$t = microtime(true) - $s;

echo "Mongo: " .  $t . "\n\n";

mysql_connect('localhost');
mysql_select_db('messages');

$s = microtime(true);
for ( $i = 0; $i < 5000; $i++ )
        mysql_query('SELECT id FROM messages WHERE mailed_by = ' . $i);
$t = microtime(true) - $s;

echo 'MySQL: ' . $t . "\n\n";
</pre>
<p>Как видно из скрипта, мы сделали по 5000 выборок из обеих СУБД. Поля, по которым проходила выборка являются индексными. Ниже приведены результаты второго запуска скрипта (в первый раз значения были гораздо б<em>о</em>льшими, т.к. таблицы не были подтянуты в память):</p>
<pre>
Mongo: 0.010502815246582
MySQL: 0.27930092811584
</pre>
<p>Как видим MySQL справился с однотипной задачей на порядок медленее. <em>Для тестирования были использованы стандартные конфигурации обоих платформ, поэтому настройка может внести изменения в эти результаты.</em></p>
<h2>Когда выбирать Mongo DB, а когда MySQL?</h2>
<p>Mongo представляет из себя очень функциональное решение, тем не менее обладает рядом ограничений. Например, возможность сделать JOIN (а нужен ли он?). Также язык запросов Mongo конечно устапает SQL в гибкосте и возможностях. Но нужна ли Вам эта гибкость в Ваших задачах? Одним словом, Mongo подходит почти под любой класс задач, не требующих сложных выборок.</p>
<p>Что же касается MySQL (или родственных продуктов), то он остается решением для задач требующих нетривиальных выборок (например, статистические или аналитически запросы).</p>
<h2>Личное впечатление</h2>
<p>После первого знакомства с Mongo DB, этот продукт оставил очень хорошее впечатление и заставил вернуться к нему еще раз. Помимо прочих преимуществ:</p>
<ul>
<li>Очень легкий и интуитивно понятный</li>
<li>Простая установка, все заработало с первого раза</li>
<li>Отличная документация, хорошее сообщество</li>
<li>Множество клиентских разработок, в т.ч. под PHP</li>
</ul>
<p>При детальном рассмотрении, выяснилось, что сам продукт обладает очень обширным функционалом (например, полнотекстовый поиск). Кажущийся простым на поверхности, <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a> представляет из себя очень мощную платформу для работы с данными.</p>
<p>Совсем недавно мы переписали несколько фукнциональных частей проекта на Mongo. В процессе работы проблем почти не возникало, за исключением некоторых:</p>
<ul>
<li>Mongo строго типизирован и не приводит типы автоматически (такой возможности впринципе нет, учитывая отсуствие каких-либо метаданных о коллекциях и документах). Поэтому в динамически типизированном PHP приходится приводить данные к нужным типам (например, когда они приходят из формы).</li>
<li>Не хватило возможностей для работы с массивами, что немного сбило с толку. С одной стороны - вложенные массивы - очень удобная вещь, с другой стороны - нет таких штук, как их фильтрация или сортировка. Надеюсь все это будет вскоре, хотя сейчас есть возможность реализовать это с помощью серверных функций.</li>
</ul>
<p>Интересно узнать мнение и опыт читателей, кто использовал или знаком с <a href="http://highload.com.ua/index.php/tag/mongo/" >MongoDB</a>.</p>

<div class="zakladka"><noindex><a href="http://www.google.com/bookmarks/mark?op=add&bkmk=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&title=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/google.png" border="0" width="16" height="16" alt="Google Bookmarks" title="Google Bookmarks"></a></noindex> <noindex><a href="http://digg.com/submit?url=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/digg.png" border="0" width="16" height="16" alt="Digg" title="Digg"></a></noindex> <noindex><a href="http://links.i.ua/add/?_rand=149669598http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ua.png" border="0" width="16" height="16" alt="I.ua" title="I.ua"></a></noindex> <noindex><a href="http://www.ru-marks.net/bookmarks.php/?action=addhttp://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ru-marks.png" border="0" width="16" height="16" alt="Ru-marks" title="Ru-marks"></a></noindex> <noindex><a href="http://www.ruspace.ru/index.php?link=bookmark&action=bookmarkNewhttp://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/ruspace.png" border="0" width="16" height="16" alt="Ruspace" title="Ruspace"></a></noindex> <noindex><a href="http://www.zakladok.net/add_link.php?folder_id=0http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/zakladok.png" border="0" width="16" height="16" alt="Zakladok.net" title="Zakladok.net"></a></noindex> <noindex><a href="http://reddit.com/submit?url=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&title=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/reddit.png" border="0" width="16" height="16" alt="Reddit" title="Reddit"></a></noindex> <noindex><a href="http://delicious.com/post?url=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&title=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/delicious.png" border="0" width="16" height="16" alt="delicious" title="delicious"></a></noindex> <noindex><a href="http://www.technorati.com/faves?add=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/technorati.png" border="0" width="16" height="16" alt="Technorati" title="Technorati"></a></noindex> <noindex><a href="http://myweb2.search.yahoo.com/myresults/bookmarklet?u=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&t=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/yahoo.png" border="0" width="16" height="16" alt="Yahoo My Web" title="Yahoo My Web"></a></noindex> <noindex><a href="http://news2.ru/add_story.php?url=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/news2ru.png" border="0" width="16" height="16" alt="News2.ru" title="News2.ru"></a></noindex> <noindex><a href="http://www.bobrdobr.ru/addext.html?url=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&title=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/bobrdobr.png" border="0" width="16" height="16" alt="БобрДобр.ru" title="БобрДобр.ru"></a></noindex> <noindex><a href="http://memori.ru/link/?sm=1&u_data[url]=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&u_data[name]=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/memori.png" border="0" width="16" height="16" alt="Memori.ru" title="Memori.ru"></a></noindex> <noindex><a href="http://www.rucity.com/bookmarks.php?action=add&address=http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/&title=Mongo+DB+-+%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%B0%D1%8F+%D0%B1%D0%B0%D0%B7%D0%B0+%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85+%D0%B8+MySQL+-+Highload+Web" rel="nofollow" target="_blank"><img src="http://highload.com.ua/wp-content/plugins/zakladka/images/rucity.png" border="0" width="16" height="16" alt="rucity.com" title="rucity.com"></a></noindex> </div>


<p>Related posts:<ol><li><a href='http://highload.com.ua/index.php/2010/03/05/sysbench-testiruem-proizvoditelnost-mysql/' rel='bookmark' title='Permanent Link: Sysbench - тестируем производительность MySQL и платформы'>Sysbench - тестируем производительность MySQL и платформы</a></li><li><a href='http://highload.com.ua/index.php/2009/07/28/maatkit-%d1%80%d0%b0%d1%81%d1%88%d0%b8%d1%80%d0%b5%d0%bd%d0%bd%d1%8b%d0%b5-%d0%b2%d0%be%d0%b7%d0%bc%d0%be%d0%b6%d0%bd%d0%be%d1%81%d1%82%d0%b8-mysql/' rel='bookmark' title='Permanent Link: Maatkit - расширенные возможности MySQL'>Maatkit - расширенные возможности MySQL</a></li><li><a href='http://highload.com.ua/index.php/2009/11/26/check-unused-keys-proverka-neispolzuemyh-indeksov-mysql/' rel='bookmark' title='Permanent Link: check-unused-keys - проверка неиспользуемых индексов в MySQL'>check-unused-keys - проверка неиспользуемых индексов в MySQL</a></li></ol></p>]]></content:encoded>
			<wfw:commentRss>http://highload.com.ua/index.php/2010/03/02/mongodb-document-oriented-db-and-mysql/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 1.945 seconds -->
