<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Игорь Артамонов &#187; Обработка данных</title>
	<atom:link href="http://artamonov.ru/category/data_mining/feed/" rel="self" type="application/rss+xml" />
	<link>http://artamonov.ru</link>
	<description>Посмотрим, глубока ли кроличья нора</description>
	<lastBuildDate>Fri, 21 May 2010 11:51:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Swarm DPL</title>
		<link>http://artamonov.ru/2009/10/02/swarm-dpl/</link>
		<comments>http://artamonov.ru/2009/10/02/swarm-dpl/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 09:51:46 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[gridgain]]></category>
		<category><![CDATA[map reduce]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=258</guid>
		<description><![CDATA[Нашел интересный прототип фреймворка для распределенных вычислений: Swarm-DPL 
Основная идея в том что код выполняется как можно ближе к данным, и даже больше, он постоянно мигрирует между разными машинами, старясь быть ближе к ним, без остановки основного вычислительного алгоритма. В общем это continuations с переносом состояния между нодами. Это в пику подходу map-reduce когда у [...]]]></description>
			<content:encoded><![CDATA[<p>Нашел интересный прототип фреймворка для распределенных вычислений: <a href="http://code.google.com/p/swarm-dpl/">Swarm-DPL</a> </p>
<p>Основная идея в том что код выполняется как можно ближе к данным, и даже больше, он постоянно мигрирует между разными машинами, старясь быть ближе к ним, <u>без остановки</u> основного вычислительного алгоритма. В общем это <a href="http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B4%D0%BE%D0%BB%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5">continuations</a> с переносом состояния между нодами. Это в пику подходу map-reduce когда у нас именно данные гоняются между нодами. Код все таки меньше места занимает, должно быть быстрее, это не гигабайты данных по сети гонять. </p>
<p>Рекомендую посмотреть презентацию:<br />
<object width="400" height="270"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=6614042&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=6614042&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="270"></embed></object>
<p><a href="http://vimeo.com/6614042">Swarm: Distributed Computation in the Cloud</a> from <a href="http://vimeo.com/user2266455">Ian Clarke</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<p>Реализовано на Scala, хотя думаю что никто не мешает реализовать идею на другом языке, и тем более уж под JVM. Автор, правда, утверждает обратное, но причина в том что в Scala все уже есть для этого, уже сейчас, и для прототипа как раз подходит. Ну и насколько я понимаю подобную оптимизацию можно реализовать в GridGain и сейчас, <a href="http://www.gridgainsystems.com/wiki/display/GG15UG/GridAffinityLoadBalancingSpi">указав ноды для MR</a>, но тут идея более интересная.</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2009/10/02/swarm-dpl/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PwC о Semantic Web</title>
		<link>http://artamonov.ru/2009/06/21/pwc-about-semantic-web/</link>
		<comments>http://artamonov.ru/2009/06/21/pwc-about-semantic-web/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 19:21:49 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[owl]]></category>
		<category><![CDATA[rdf]]></category>
		<category><![CDATA[semantic web]]></category>
		<category><![CDATA[sparql]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=205</guid>
		<description><![CDATA[Встретил хороший отчет PriceWaterhouseCoopers по поводу Semantic Web, где идет речь о способах хранения и обработки корпоративных данных. Заинтересовало именно то что там идет речь не только о semantic web как таковом, но о внутреннем использовании этих технологий, для хранения и обработки данные.
Все о том что для сложноструктурированных данных классический подход (со всеми нормальными формами) [...]]]></description>
			<content:encoded><![CDATA[<p>Встретил хороший <a href="http://www.pwc.com/extweb/home.nsf/docid/1308AF8EA7929CCA852575BA00720F26">отчет PriceWaterhouseCoopers по поводу Semantic Web</a>, где идет речь о способах хранения и обработки корпоративных данных. Заинтересовало именно то что там идет речь не только о semantic web как таковом, но о внутреннем использовании этих технологий, для хранения и обработки данные.</p>
<p>Все о том что для сложноструктурированных данных классический подход (со всеми нормальными формами) не всегда работает. Т.е. иногда создать отдельную таблицу в БД под каждый тип сущности и установить связи просто не реально, ну например сколько их будет в случае большого магазина, например Озона? С десяток категорий с совершенно разными товарами, где общих полей мало, лишь поля цены, названия и пр. В общем в любом случае приходится придумывать что-то универсальное. Так вот, чтобы не изобретать свой велосипед, можно посмотреть в сторону технологий Semantic Web.</p>
<p>Что есть полезного:
<ul>
<li><a href="http://ru.wikipedia.org/wiki/Resource_Description_Framework">RDF</a> &#8211; чрезвычайно простой и универсальный формат, а именно структурированеи в виде графа (и RDF это не XML)</li>
<li><a href="http://ru.wikipedia.org/wiki/Web_Ontology_Language">OWL</a> &#8211; язык для структуризации, описания предметной области, в том числе вывода неявной информации, зависимостей, связей и пр.</li>
<li><a href="http://ru.wikipedia.org/wiki/SPARQL">SPARQL</a> &#8211; язык запросов к rdf данным</li>
</ul>
<p>Хотя, если честно, эта область во-первых все еще только развивается, а во-вторых не все так просто и очень высокий порог для входа. Но чтото уже начинает <a href="http://en.wikipedia.org/wiki/Category:Semantic_Web">вырисовываться</a>.</p>
<p>PS а отчет советую прочитать</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2009/06/21/pwc-about-semantic-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Колоночные базы данных</title>
		<link>http://artamonov.ru/2009/02/17/column-oriented-databases/</link>
		<comments>http://artamonov.ru/2009/02/17/column-oriented-databases/#comments</comments>
		<pubDate>Tue, 17 Feb 2009 14:19:20 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[bigtable]]></category>
		<category><![CDATA[column oriented]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[hbase]]></category>
		<category><![CDATA[Kdb]]></category>
		<category><![CDATA[key value]]></category>
		<category><![CDATA[map reduce]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[rdbms]]></category>
		<category><![CDATA[simpledb]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=185</guid>
		<description><![CDATA[Меня, если честно, всегда смущал тот факт что Oracle пихают во все задачи, куда только можно, бытует мнение что &#171;БД это Оракл&#187;. Я лично не думаю что это прям такая &#171;серебряная пуля&#187;. MySQL занимает те же позиции немного на другом фронте. Да, Oracle в частности, MySQL, и реляционные БД в общем, это отличный инструмент, но [...]]]></description>
			<content:encoded><![CDATA[<p>Меня, если честно, всегда смущал тот факт что Oracle пихают во все задачи, куда только можно, бытует мнение что &laquo;БД это Оракл&raquo;. Я лично не думаю что это прям такая &laquo;серебряная пуля&raquo;. MySQL занимает те же позиции немного на другом фронте. Да, Oracle в частности, MySQL, и реляционные БД в общем, это отличный инструмент, но для случая когда у нас реально востребована эта реляционность.</p>
<p>Но ведь Оракл используют независимо от того нужна ли нам реляционность, просто по привычке, и потому что &laquo;<em>все так делают</em>&laquo;. Я за все свое время редко встречал нормализованные структуры, и даже больше, часто встречал таблицы БД с колонками вида col_1, col_2, col_N и пр. нарушениями всех форм, когда также разрезали таблицы на отдельные, в том числе отдельные инстансы БД. Встречал также когда в Oracle складывали черт знает что, когда использовали как хранилище лога операций, десятки гигабайт логов, ну и т.д.  И никакого серьезного положительного эффекта от реляционных возможностей во всех этих случаях не было.</p>
<p>Не знаю может это мне так всегда везло и в других проекта все всегда &laquo;красиво&raquo;, не нарушается ни одной из &laquo;нормальных форм&raquo; и пр, но у меня опыт вот такой.</p>
<p>Под реляционностью в данном случае я подразумеваю не только то что данных хранятся в виде таблице (с заранее четко оговоренным списком атрибутов). Я имею ввиду все что вертится вокруг этого: нормальные формы, внешние ключи, связи и ограничения, acid, собственно реляционная алгебра и все прочее предназначенное для облегчения хранения и соблюдения целостности структурированных данных.</p>
<p>В общем я не сторонник использования реляционной БД всегда и везде, на любой чих. Это хорошая технология, спасающая в огромном множестве случаев, но RDBMS это совсем не серебряная пуля.</p>
<p>Поэтому хотел бы обратить внимание на другой тип баз, на колоночные БД.<br />
<span id="more-185"></span></p>
<h1>Основная идея колоночных БД</h1>
<p>Вообще базовая идея колоночных БД всего лишь в том что физически (на жестком диске) данные хранятся в другом порядке. Т.е. если обычная (рядная) БД будет все хранить построчно, то в данном случае по колонкам, в начале все данные первой колонки, потом второй, потом третьей и т.д. В рядном харнении все ячейки строки хранятся рядом, и обычно могут быть прочитаны с диска за одну операцию чтения. В колоночной наоборот, значения ячеек разнесены на разные блоки, и за одну операцию мы читаем несколько подряд идущих значений идной колонки.</p>
<p>Казалось бы мелочь, но все это не просто так, и действительно подобная организация хранения данных на самом деле не такое уж из ряда вон выходящее дело. И тот же Оракл, да и прочие РСУБД, используют и этот подход, как минимум для хранения блобов. Как правильно указали мне в комментариях на самом деле есть и традиционно реляционные СУБД, хранящие данные в колоночном виде, все таки одно другому не мешает, но это скорее редкость (об исключениях см. в списке примеров и в комментариях к записи) и все равно они обладают почти теми же свойствами (реляционность скорее из маркетинговых побуждений), а разделение на реляционные и неряляционные будет более глобально, поэтому я позволил себе разделить этот мир именно по критерию рядного vs колоночного хранения данных.</p>
<p>Дело в том что тут скорее задается начальный вектор архитектуры БД, а те задачи в которых востребован такой способ хранения также имеют свои специфические потребности, поэтому эта мелочь выливается в довольно интересные системы.</p>
<p>Перечислю что у нас обычно присуще колоночными базами данных (хочу подчеркнуть что обычно, но не все это обязательно каждой конкретно):</p>
<h2>Позднее связывание</h2>
<p>Данные у нас хранятся в виде группы полей (строка в таблице), так вот при обработке этой группы можно всегда использовать всю строку (все ячейки), или лишь ту колонку которая нам нужна в данный момент. В случае традиционной БД она хранит и читает всю строку целиком, они лежат подряд, никуда не денешься, колоночная же читает данные лишь из нужной колонки, и лишь только когда находит подходящую [по критерию] строку дочитывает для этой строки значения из недостающих колонок.</p>
<p>Например для запроса <code>select col_1 from table where col_2 = 10</code> традиционная БД будет читать все строки, проверяя каждую на условие во второй колонке, и для совпавших вернет значение первой ячейки этих строк. При этому если у нас в таблице десяток колонок то будет прочитано куча лишних данных (в данном примере что-то около 80% мусора). Чтобы такого перерасхода вычислительных ресурсов не было нужно добавить индекс, который сразу ограничит набор нужных строк. Этот индекс и есть та самая дополнительная колонка, через которую пройдет позднее связывание в традиционной БД. В случае колоночной БД будет читаться лишь 2я колонка, и при совпадении условия к ней будет привязано значение из первой колонки. Очень похоже на то что у нас вся таблица состоит лишь из индексов по колонкам.</p>
<p>Как результат это то что мы можем иметь огромное количество колонок. Если для реляционной БД больше пары десятков колонок уже начинаются проблемы (неэффективное использование чтения с диска и памяти), то для колоночной таблицы имеющие сотни и тысячи колонок это вполне нормально.</p>
<p>Получается что рядная БД удобна когда нам обычно нужно использовать данные всей строки (в условиях и связях при селекте, апдейте и пр.), а колоночная когда данных много, но обычно используется лишь небольшая их часть.</p>
<h2>Разная структура данных</h2>
<p>Связанные данные хранят в одной таблице (не забываем что при этом можно использовать огромное количество колонок), а связи между таблицами здесь не приживаются, по многим причинам. Но! здесь можно не боятся хранить сложные структуры в ячейках, в том числе вложенные списки, подтаблицы, структуры XML, JSON и пр.</p>
<p>Размер отдельной ячейки часто можно не обращать внимания, пусть даже каждая ячейка столбца имеет свой размер, тут это не особо сильно влияет, в итоге не обязательно изначально жестко типизировать колонки таблицы, пусть в одной строке будет int, в другой string, а в третьей бинарная картинка в несколько мегабайт, и весь этот разброд может быть вдоль одной колонки, если, конечно, такое востребовано. К тому же вполне мы спокойно храним null значения, они просто пропускаются, тогда как рядная БД никуда не денется &#8211; место на диске займет, но оставит его пустым, но при обработке дополнительные затраты.</p>
<p>Одним из применений этого подходя является ответвление БД имеющих всего одну колонку, помимо ключа, в которой и хранится все что нужно. Внешне все это выглядит как огромный HashTable. Такие БД еще называют key-value storage или document oriented database.</p>
<h2>Сжатие данных</h2>
<p>Очень распространенная штука это использование сжатия данных. Тут возможно не заслуга использования колоночности, а больше того как именно такие БД используют, но факт что это популярно и дает вполне неплохой эффект, при этом для того класса приложений где это нужно обычно лишь при незначительной потере в производительности.</p>
<h2>Большие объемы данных</h2>
<p>По вышеуказанным причинам получается что в такой структуре удобно хранить огромные объемы данных, а шардинг и реплиция обычно из коробки, как само собой разумеющееся. Возможно это и не следствие колоночноый архитектуры, а даже наоборот причина, но в общем будем иметь ввиду что &laquo;большие объемы&raquo; и &laquo;колоночное хранение&raquo; идут бок о бок. Конечно же тут сразу появляются различные возможности для параллельной обработки хранимых данных, например используя подход mapreduce и пр.</p>
<h2>Доступ</h2>
<p>Подобная БД обычно востребована при хранении и обработки больших объемов данных, поэтому в данном случае и язык запросов может быть весьма далек от стандартного SQL, и даже вовсе не иметь оного. И конечно никакой тебе реляционности, да и транзакции так себе поддерживаются. Доступ к данным будет через какойто специфичный API, что с другой стороны позволяет более тесную интеграцию приложения и хранимых данных.</p>
<p>Но получается что средства доступа по универсальности и скорости разработки/использования выглядят обычно хуже возможностей предоставляемых Oracle и компании.</p>
<h1>Сравнение с RDBMS</h1>
<h2>RDBMS:</h2>
<ul>
<li>соблюдается целостность данных (foreign keys, транзакционность)</li>
<li>четко структурированные данные</li>
<li>запросы по всей структуре БД, используя стандартизованный язык</li>
<li>результат запроса это небольшой (относительно БД) кусок данных</li>
<li>быстрое извлечение нужной структуры (в том числе быстрая реализация запроса)</li>
</ul>
<h2>Колоночные БД:</h2>
<ul>
<li>хранят большие объемы данных, упрощеный шардинг, репликация и пр.</li>
<li>данные гораздо менее структурированы</li>
<li>данные обрабатываются большим блоком (параллельно, massive parallel processing), или вообще сразу вся база</li>
<li>оптимальным будет индивидуальный подход к обработке, тесная интеграция с данными</li>
<li>худшая (ручная) поддержка целостности данных</li>
</ul>
<h2>Где стоит использовать</h2>
<p>Может хранить огромные объемы слабоструктурированных данных, спокойно смасштабируется на большой кластер и запросы будет обрабатывать параллельно по всему кластеру.</p>
<p>Здесь достаточно просто хранить большие блоки данных, документов (в документ-ориентированных БД) и/или сложных структур. Также довольно распространено хранилище данных вида &laquo;Ключ-Значение&raquo; (aka Properties Pattern, Хэш-таблица) с большими группами которых идет различная работа. Отлично подходит для задач, которые я привел в записи &laquo;<a href="http://artamonov.ru/2009/01/19/storage-for-data-mining/">Хранилище для обработки данных</a>&laquo;. Ну и также это хранилище логов и прочее в этом духе. Особенно хорошо если данные лишь дописываются, а не изменяются существующие.</p>
<p>Больший выигрыш будет если храним много, но в реальных операциях используется лишь часть колонок, или вовсе одна, помимо идентификатора конечно.</p>
<p>При таком хранении гораздо проще бежать вдоль столбца, выполняя нужные операции. Причем операции лучше независимые, или групповые, и когда они затрагивают большой блок хранимых данных. К примеру брать большими кусками и агрегировать результат &#8211; самое оно. Это такие задачи как обработать лог отдельных операций, и просуммировать результаты в течении каждого отдельного периода (что вообще запросто превратить в mapreduce обработку). В случае лога веб-серверов это может быть агрегация посещений по браузерам (т.е. используется отдельная колонка). Или иным образом разбивая данные независимо, и обрабатывая эти сгруппированные данные параллельно, например mapreduce&#8217;ом.</p>
<h2>Где не стоит использовать</h2>
<p>Не стоит использовать когда нам нужна именно классическая реляционная структура, и когда у нас данные (и связи) постоянно меняются. Под &laquo;меняются&raquo; я подразумеваю изменение и удаление существующих данных, смену связей между ними. Хотя если данные лишь дополняются, то уже стоит подумать.</p>
<p>Так же не подойдет если у нас много колонок, и мы оперируем в основном всей строкой, нет особого смысла менять тип БД. Хотя в большинстве случаев, как я уже упоминал, значения в нескольких колонкам, которые нам нужно обрабатывать одновременно, даже удобней объединить в общую структуру, к примеру в список имя/значений, или превратив в xml, yaml или json, по вкусу.</p>
<p>Также не пойдет вариант когда операции проводятся лишь небольшом объеме базы, здесь мы просто не получим никакого выигрыша (или точнее наступим на грабли колоночных БД), и больше вероятность что хранение по строкам будет гораздо удобнее.</p>
<p>Ну и конечно не подойдет когда нам нужны классические SQL запросы. Что-то &laquo;в стиле SQL&raquo; они часто имеют, но это уже на самом деле другой подход и по другому выполняется.</p>
<h1>Реализации</h1>
<p><strong><a href="http://hadoop.apache.org/hbase/">HBase</a></strong> &#8211; представляет собой часть Apache Hadoop, можно сказать классическая реализация Гуглового Bigtable, рассчитана в первую очередь на большие объемы данных, и на хранение этих данных в большом кластере. Типы данных ничем не ограниченны. Я именно именно на hbase ориентировался когда приводил приводил основные тонкости/отличия, но не ограничивался им.</p>
<p>Из возможностей: сразу учтено что каждая колонка может иметь несколько ячеек (получается что помимо того что в строке несколько строк, в колонке тоже несколько ячеек, этакое минидерево, для хранения списочных и связанных данных), может хранить любые бинарные данные, может хранить одновременно несколько версии (версионность из коробки), поддерживает фильтры Блума, rest интерфейс доступа (помимо java api) и пр.</p>
<p>Но, как минимум в данный момент, не имеет индексов, кроме как по ключу. Если честно, как и сам Hadoop эта база еще развивается, поэтому БД в данный момент достаточно сырая.</p>
<p>Прочие</p>
<dl>
<dt><a href="http://couchdb.apache.org/">CouchDB</a></dt>
<dd>реализация на Erlang. Не совсем колоночная, это документная БД (document oriented DB), но по сути внутри одна большая колонка, и все приемы соответствующие. БД, конечно, не привязана к определенной платформе (т.е. к Эрлангу). Запросы пишутся на Javascript(!) в виде mapreduce операций, доступ через REST. Благодаря отказоустойчивости самого Erlang&#8217;а &#8211; очень интересное решение</dd>
<dt><a href="http://hypertable.org/">Hipertable</a></dt>
<dd>реализация bigtable на С, изначально как основная альтернатива Hadoop HBase, именно так себя позиционировали. Причем хранение так же было организовано поверх Hadoop HDFS. Как там сейчас обстоит дело не знаю.</dd>
<dt><a href="http://code.google.com/p/the-cassandra-project/">The Cassandra Project</a></dt>
<dd>реализация от Facebook, тоже базируется на идеях Google BigTable и поэтому похожа на HBase.</dd>
<dt><a href="http://project-voldemort.com/">Project Voldermort</a></dt>
<dd>распределенный key-value storage, на java.</dd>
<dt><a href="http://www.kx.com/">Kdb+</a></dt>
<dd>коммерческая БД и язык обработки, заточенные под time-series data. Это всевозможные логи, биллинг, биржы и пр. Язык обработки имеет очень сильную базу для обработки массивов (БД в данном случае является отдельным огромным многомерным массивом) и особенно распределенных во времени. В результате многие узкоспециализированные задачи (всяческие кубы, временные данные) выполняются в разы быстрее. Как минус &#8211; БД и все вокруг нее являются излишне закрытыми от людей извне</dd>
<dt><a href="http://www.luciddb.org/">LucidDB</a></dt>
<dd>Open Source реляционная СУБД с основой на колоночной структуре. Расчитывается в первую очеред на аналитику, bi и пр.</dd>
<dt><a href="http://www.sybase.ru/products/sybase_iq">Sybase IQ</a></dt>
<dd>Еще одна реляционная колоночная СУБД, для нужд аналитики. В этот раз коммерческая</dd>
<dt>Amazon SimpleDB, Google BigTable, Yahoo Everest</dt>
<dd>закрытые внутренние реализации от монстров интернета.</dd>
</dl>
<h2>Ссылки</h2>
<ul>
<li><a href="http://cs-www.cs.yale.edu/homes/dna/papers/abadi-sigmod08.pdf">PDF &#8211; &laquo;Column-Stores vs. Row-Stores: How Different Are They Really?&raquo;</a></li>
<li><a href="http://www.databasecolumn.com/2008/12/debunking-yet-another-myth-col.html">Debunking Yet Another Myth: Column-Stores As A Storage-Layer Only Optimization</a> (и предыдущие в цикле статей)</li>
<li><a href="http://www.readwriteweb.com/archives/is_the_relational_database_doomed.php">Is the Relational Database Doomed?</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2009/02/17/column-oriented-databases/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>GridGain</title>
		<link>http://artamonov.ru/2009/01/29/gridgain/</link>
		<comments>http://artamonov.ru/2009/01/29/gridgain/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 11:58:29 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[gridgain]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[map reduce]]></category>
		<category><![CDATA[mapreduce]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=177</guid>
		<description><![CDATA[GridGain &#8211; платформа для реализации cloud вычислений. На мой взгляд очень серьезная платформа, вполне стабильная (если это имеет значение то версия, например, уже 2.1.0) имеет открытый код, на java, интегрируется с огромным количеством внешний систем. В отличие от пока академического Apache Hadoop здесь уже все более практично. А разобраться и запустить можно за пару часов, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.gridgain.com/">GridGain</a> &#8211; платформа для реализации cloud вычислений. На мой взгляд очень серьезная платформа, вполне стабильная (если это имеет значение то версия, например, уже 2.1.0) имеет открытый код, на java, интегрируется с огромным количеством внешний систем. В отличие от пока академического Apache Hadoop здесь уже все более практично. А разобраться и запустить можно за пару часов, в отличии от&#8230;</p>
<p>Самый известный, наверное, подход к cloud вычислениям это <a href="http://artamonov.ru/2008/09/16/mapreduce/">mapreduce</a>, и он прекрасно здесь организован. А так как этот mapreduce не всем понятен, да и не всегда нужен полностью, то здесь <u>помимо него</u> предлагается своя реализация java.lang.concurency.ExecutorService который разбрасывает переданные вычисления по кластеру.<br />
<span id="more-177"></span><br />
В отличии от того же <a href="http://hadoop.apache.org/">Hadoop</a> здесь не гнались за обязательной возможностью обрабатывать терабайты данных за один проход. GridGain удобней будет для длительных вычислений на объемах гораздо поменьше, по хорошему это то что можно передать между нодой в одном List&#8217;е, что, возможно, даже практичней. Я не хочу сказать что для больших объемов эта платформа не подойдет, просто при большом объеме данных (а не вычислений над ними) все упирается уже в хранилище данных, и они этим сознательно не занимались, но в случае когда это нужно &#8211; можно всегда использовать и внешнюю БД и даже Hadoop HDFS/HBase. </p>
<p>Для многих случаев это очень удобный вариант, отличная альтернатива hadoop&#8217;у, ну в самом деле не обязательно у нас что-то грандиозное, вполне может быть у нас пара тысяч независимых операций и cloud из нескольких серверов, и этот самый простой способ распараллелить все.  Если основной упор на вычисления, например параллельно обработать несколько тысяч url&#8217;ов, на каждый по 1-2 минуты, то GridGain предлагает очень удобное подспорье. И, кстати, очень просто организуется архитектура для случая когда есть несколько gui клиентов, на слабых компах, а все вычисления для них производятся в cloud.</p>
<p>Как я уже говорил платформа давно развивается (кстати нашими соотечественниками), хорошо документирована, внутренняя часть уже вполне стабильна, и к тому же хорошо развиты инструменты мониторинга, алгоритмы балансировки, восстановления после сбоя и пр. и пр. Для ознакомления стоит посмотреть скринкаст &laquo;<a href="http://www.gridgain.com/screencasts.html">Grid Application in 15 Minutes</a>&raquo; </p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2009/01/29/gridgain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Хранилище для обработки данных</title>
		<link>http://artamonov.ru/2009/01/19/storage-for-data-mining/</link>
		<comments>http://artamonov.ru/2009/01/19/storage-for-data-mining/#comments</comments>
		<pubDate>Mon, 19 Jan 2009 11:16:08 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[text mining]]></category>
		<category><![CDATA[архитектура]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=151</guid>
		<description><![CDATA[Допустим у нас стоит задача: нужно собирать неструктурированные html данные и извлекать из них структуру, или, точнее, информацию, т.е. система Text Mining/Information Extraction.
Вcе элементы этого процесса, конечно, должны где то хранится. И если конечную информацию можно структурировать, завести с десяток таблиц в БД, настроить связи и складывать туда, то входная информация по определению у нас [...]]]></description>
			<content:encoded><![CDATA[<p>Допустим у нас стоит задача: нужно собирать неструктурированные html данные и извлекать из них структуру, или, точнее, информацию, т.е. система Text Mining/Information Extraction.</p>
<p>Вcе элементы этого процесса, конечно, должны где то хранится. И если конечную информацию можно структурировать, завести с десяток таблиц в БД, настроить связи и складывать туда, то входная информация по определению у нас не структурирована, ну или, как минимум, слабо структурированная. Если делать сложную структуру то из-за специфики нашей задачи нам будет очень сложно отследить целостность данных.  К слову о сложности работы с такой структурированностью замечу что я попытался было нарисовать это подход, но не смог сделать чтобы это было внятно, без всего лишнего.</p>
<p>Поэтому нужно придумывать какое то простое и универсальное решения для этой задачи. Одна из них это структура когда у нас для всего выделена одна таблица, в первые колонки которой заливается начальная структура. Далее они обрабатываются нашей программой для структурирования, и результат складывается рядом, в следующие колонки. Причем если результат мы получаем не за один шаг, что чаще и бывает, то в таком случае мы последовательно выполняем все шаги, складывая новые данные правее от текущих.<br />
<span id="more-151"></span><br />
В итоге получаем примерно такие шаги:</p>
<ol>
<li>(первая колонка) список URL</li>
<li>выкачиваем документ по этому адресу, складываем в колонку 2</li>
<li>убираем весь мусор (стили, js, реклама и пр.) из html и кладем в колонку 3</li>
<li>вырезаем текстовые контент (убираем навигацию, и пр.), результат в колонку 4</li>
<li>делаем PDF, результат в колонку 5 </li>
</ol>
<div style="float: right; margin-left: 10px; font-style: italic; font-size: 10px;">
<img src="http://artamonov.ru/wp-content/uploads/2009/01/1to1struct.png" alt="1to1struct" title="1to1struct" width="212" height="158" /><br />
Рис 1. Таблица с несколькими колонками<br />
<img src="http://artamonov.ru/wp-content/uploads/2009/01/mtonstruct.png" alt="mtonstruct" title="mtonstruct" width="212" height="235" /><br />
Рис 2. Таблица с вертикальной обработкой
</div>
<p>Мы складываем в колонку справа если у нас идет обработка 1 к 1 (см. рис 1), если же у нас идет какая либо вертикальная агрегация (см. рис 2), то новые данные стоит записывать под текущим блоком, в той же колонке, что есть более универсальный подход. В случае СУБД у нас получается для первого варианта таблица с колонками <code>block_id</code>, <code>data_id</code>, <code>col_1...col_N</code>, для второго варианта <code>block_id</code>, <code>data_id</code>, <code>value</code>. Где </p>
<ul>
<li><code>block_id</code> это у нас идентификатор обрабатываемого блока,</li>
<li> <code>data_id</code> идентификатор элемента данных, которым мы оперируем,</li>
<li> и <code>col_1..col_n</code> или <code>value</code> это те данные которые нужно обработать.</li>
</ul>
<p>В случае файловой системы получается только второй вариант, идентификатором тут будет путь к файлу. Следуя этим подходам в <a href="http://hadoop.apache.org/">Apache Hadoop</a> есть HDFS для варианта хранения в файлах, и <a href="http://hadoop.apache.org/hbase/">HBase</a> для хранения в виде таблицы.</p>
<p>Наверное сразу возникает претензия что у нас всегда данные если не дублируются, то остается слишком много временных данных, старые на каждом этапе остаются, а новые (выведенные из предыдущих) складываются рядом. Зачем это? Затем что иначе нам нужно следить за транзакциями, усложнять процесс распараллеливания обработки. Гораздо проще складывать рядом, и когда придет время (например когда мы дойдем до конечного шага), можно будет выкинуть все лишнее. Если мы можем позволить себе это, то так получается гораздо удобнее. Дополнительные бонусы тут в том что на любом этапе мы можем переиграть обработку заново (как замена rollback&#8217;а) или сделать новую &laquo;ветку&raquo; обработки, выполнив другие функции. И, как минимум, всегда можем проследить историю операций.</p>
<p>Но еще более важно то что мы получаем независимые функции. Почти функции в том виде в котором они приняты в функциональном программировании. Т.е. у нас входные параметры и есть результат, и функция не должна больше ничего менять, не должна трогать входные данные, и не зависеть ни от каких данных кроме этих. Каждую из них может разрабатывать отдельный разработчик, не сильно заботясь об общей архитектуре приложения, и даже на совершенно разных языках можно писать, выбирая тот который больше подходит для конкретной задачи, которая к тому же имеет очень четкие границы.</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2009/01/19/storage-for-data-mining/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Map Reduce</title>
		<link>http://artamonov.ru/2008/09/16/mapreduce/</link>
		<comments>http://artamonov.ru/2008/09/16/mapreduce/#comments</comments>
		<pubDate>Tue, 16 Sep 2008 09:21:32 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[map reduce]]></category>
		<category><![CDATA[mapreduce]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=122</guid>
		<description><![CDATA[
Подход mapreduce сейчас, с ростом объемов вычислений, стал очень популярен, но все упоминания какие то туманные, надо разложить все по полочкам. Начну с того что напомню о такой штуке как «закон Амдала». Он описывает ограничение роста производительности вычислительной системы с увеличением количества вычислителей, т.е. как мы можем ускорить вычисление увеличивая количество компьютеров в кластере. В [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://artamonov.ru/wp-content/uploads/2008/09/combines-1-150x150.jpg" alt="map reduce harvesters" title="mapreduce" width="150" height="150" class="size-thumbnail wp-image-126" style="float: left; padding: 5px"/><br />
Подход mapreduce сейчас, с ростом объемов вычислений, стал очень популярен, но все упоминания какие то туманные, надо разложить все по полочкам. Начну с того что напомню о такой штуке как «<a href="http://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%90%D0%BC%D0%B4%D0%B0%D0%BB%D0%B0">закон Амдала</a>». Он описывает ограничение роста производительности вычислительной системы с увеличением количества вычислителей, т.е. как мы можем ускорить вычисление увеличивая количество компьютеров в кластере. В общем то тут все интуитивно понятно. <span id="more-122"></span> Математически он выражается в формуле:</p>
<div style="text-align:center; clear: both">
<img src="http://artamonov.ru/wp-content/uploads/2008/09/formula.png" alt="" title="formula" width="158" height="78" class="aligncenter size-full wp-image-123" />
</div>
<p>где:<br />
α — доля вычислений которые могут быть произведены только последовательно,<br />
p — размер кластера (ну или количество процессоров/вычислителей). </p>
<p>И чем меньше α тем ближе масштабируемость к линейной. При 10% последовательного кода, к примеру, выходит что больше чем 100 компьютеров использовать не имеет никакого смысла, никакого серьезного прироста не будет, хоть на 1000 запускай. И добиться этих 10% не всегда просто.</p>
<p>Понятно что для того чтобы мы могли ускорять программу добавляя процессоры она должна иметь минимум таких обязательно последовательных участков. Это, кстати, один из стопоров увеличения количества ядер, так как сейчас очень мало программ которые используют параллельное вычисление, α у большинства в районе единицы, и тут как не добавляй ядра, программа не заработает быстрее.</p>
<p>Так вот MapReduce это такой подход построения архитектуры при котором просто не получится написать не параллельное приложение, α будет близко к 0. Алгоритм разбивается на 2 слоя параллельных операций и, в итоге, очень хорошо масштабируется. Надо заметить что алгоритм в виде функции map+reduce может быть гораздо медленней чем он же в стандартном (имеющим последовательные участки) виде, но стандартный алгоритм будет иметь предел после которого добавляя процессоры мы не выигрываем в производительности, с map+reduce вариантом этот предел почти недостижим. Дополнительным плюсом здесь является независимость, и при сбое отдельного участка его можно вычислить заново, не перезапуская весь процесс.</p>
<p>Map в данном случае независимо обрабатывает входящие блоки данных. Но хоть сами входящие данные не зависят друг от друга, то результат обработки часто зависит от их связей между собой. Обработкой первоначально независимой информации занимается соответственно <code>Map</code>, он подготавливает блоки данных для обработки, обработкой итоговых, уже зависимых друг от друга, данных займется <code>Reduce</code>.</p>
<p>Один из классических примеров использования mapreduce &#8211; подсчитать распределение слов. В этом случае map обрабатывает входной текст, как независимые блоки. На выходе получаем пары «слово — кол-во употреблений» . В простейшем случае map не анализирует текст, а лишь разбивает по пробелам, в итоге из текста 5 раз содержащего слово «hello» на выходе будет не пара <code>«hello — 5»</code>, а 5 пар по <code>«hello — 1»</code>. Вот этот выхлоп уже связан друг с другом, и reduce обрабатывает эту связь. Ему на вход приходят блоки с одинаковым ключем пары, он в свою очередь суммирует цифровые значения этих пар. Поэтому обоих случаев наших <code>«hello — x»</code> он выдаст <code>«hello — 5»</code>. Основную работу тут выполняет reduce. Такой, не совсем простой, способ подсчета количества слов полезен когда объем анализируемого текста измеряется гигабайтами (и более). Map выдаст огромный файл отсортированных пар <code>«слово — количество»</code> Так как он отсортирован то пробегая по нему достаточно просто вызвать reduce для всех групп с одним ключом, и получить суммарное количество для каждого из слов. </p>
<p>Хочу заметить что mapreduce, конечно, не панацея, часто он совсем не оптимален, и для малых объемов вообще не имеет смысла, но это самое простое и универсальное решение для масштабируемых алгоритмов, хорошо подходящий для различных data mining решений.</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2008/09/16/mapreduce/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Что дает очистка данных</title>
		<link>http://artamonov.ru/2008/06/18/chto-daet-ochistka-dannyx/</link>
		<comments>http://artamonov.ru/2008/06/18/chto-daet-ochistka-dannyx/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 13:40:49 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Бизнес]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[cdi]]></category>
		<category><![CDATA[crm]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[mdm]]></category>
		<category><![CDATA[очистка данных]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=79</guid>
		<description><![CDATA[Расскажу немного о том зачем нужна очистка данных и CDI. Сейчас не буду углубляться в CDI, MDM,  это потом,  и будем считать что данные должны быть чистые, это вполне логично. Вопрос в другом, вот почистили мы наши клиентские базы, положили в некую CDI систему, а на что можно рассчитывать дальше? Т.е. как мы [...]]]></description>
			<content:encoded><![CDATA[<p>Расскажу немного о том зачем нужна очистка данных и <abbr title="Customer Data Integration">CDI</abbr>. Сейчас не буду углубляться в <abbr title="Customer Data Integration">CDI</abbr>, <abbr title="Master Data Management">MDM</abbr>,  это потом,  и будем считать что данные должны быть чистые, это вполне логично. Вопрос в другом, вот почистили мы наши клиентские базы, положили в некую CDI систему, а на что можно рассчитывать дальше? Т.е. как мы сможем их использовать, помимо того что теперь мы знаем что у нас не мусор в базе/CRM? Какие преимущества мы получим от очистки данных?</p>
<p>Ну, во-первых, благодаря стандартизации упрощается работа всех связанных систем, грязные данные тянули за собой слишком много костылей во внешних системах, что лишь увеличивало степень неопределенности. А вот после очистки данных уже можно найти тысячи положительных эффектов, все зависит от конкретной ситуации. От снижение количества искажений при анализе клиентской базы, до возможности проведения таких BI операций, о которых до этого и речи быть не могло за отсутствием нужных данных. В конце концов мы будем точно знать кто наши клиенты, а не предполагать основываясь на куче неверных данных.<br />
<span id="more-79"></span></p>
<h1>Основные блоки данных</h1>
<p>Приведу список основных элементов данных и то что можно получить на из основе.</p>
<h2>Адрес</h2>
<ol>
<li>Дает возможность сделать географическую привязку клиента, для:
<ol>
<li>Анализ эффективности деятельности филиалов, проанализировав объемы клиентов в различных зонах.</li>
<li>Анализ действия рекламной компании, сравнивая области с различным уровнем объема уличной рекламы по разным частям города.</li>
<li>Сегментация уровня дохода/социального положения клиентов по стоимости жилья. Как минимум можно составить характеристики по районам города, а по хорошему еще составить отдельный список элитного жилья, и наоборот.</li>
<li>Обнаружение аномалий в распределении. К примеру повышенный объем страховок в одном из регионов относительно других регионов, при прочих равных факторах, возможно говорит о наличии неучтенного повышенного риска для жителей данной области (т.е. жители чего то опасаются, лучше узнать чего именно, пока не поздно).</li>
<li>Определить где можно открыть новый филиал/банкомат/магазин и пр.</li>
</ol>
</li>
<li>Обнаружение связей:
<ol>
<li>соседи и друзья</li>
<li>семья</li>
<li>коллеги, при анализе рабочего адреса</li>
</ol>
</li>
<li>Дополнение недостающей информации (например индекс,который, как известно, никто не заполняет правильно), что может устранять неоднозначности адреса, ускорять доставку корреспонденции и пр.</li>
<li>Удаление из базы мусорных записей.</li>
</ol>
<h2>Имя</h2>
<ol>
<li>Определение пола. Нужно для:
<ol>
<li>Формировании исходящей корреспонденции. Может и мелочь, но меня лично раздражает эта запись в поздравительных письмах типа «уважаемый(ая)». Ты или определись с моим полом или не делай вид что письмо совсем уж персональное.</li>
<li>Сегментация по полу при исследованиях</li>
</ol>
</li>
<li>Уточнение семейных связей (используя совместно со значениями адреса и возраста)</li>
</ol>
<h2>Телефон</h2>
<ol>
<li>Дополнение недостающей информации (код города из адреса или наоборот)</li>
<li>Обнаружение связей (по домашнему и рабочему телефонам)</li>
<li>Определение сферы деятельности по рабочему телефону (используя справочники организаций)</li>
</ol>
<h2>Прочие поля</h2>
<p>Название компании в которой работает клиент дает установить связи, определить уровни доверия, платежеспособности, доходов и пр. и пр. Тут больше зависит от того какие имеются сторонние базы организаций. Кстати, название компании и должность одни из немногих полей которые чаще всего позволяют заполнить произвольным образом, и, как следствие, требуют тщательной очистки и насыщения, иначе не могут в полной мере использоваться при анализе клиентской базы.</p>
<h1>Связи между клиентами</h1>
<p>Зачем нам знать связи между клиентами? Допустим мы почистили данные и нашли связи между людьми, но для чего нам выяснение всяких связей и пр.? Бесспорно, это хорошо что мы выяснили зависимости, но как на этом заработать?<br />
Приведу пару примеров, навскидку:</p>
<ul>
<li>Анализ нового клиента. Т.е. известное «скажи мне кто твой друг и я скажу кто ты» в действии.
<ul>
<li>К примеру у нас появляется новый клиент, молодой человек или  девушка, по которому мы определили что он родственник нашего существующего vip клиента, и даже то что это сын или дочь. В таком случае нам лучше пометить и этого клиента как VIP, или ввести тип вроде VIP-related. Вполне возможно что если ему не понравится сервис, он может отговорит и своего отца пользоваться нашими услугами. Да, дети иногда имеют хорошее влияние на своих родителей, да еще и с учетом юношеского максимализма. В общем лучше подстраховаться сразу.</li>
<li>С другой стороны таким образом можно вычислить родственника (или соседа/друга) нежелательного клиента, или мошенника.</li>
<li>Ну конечно дополнительные критерии для скоринга.</li>
</ul>
</li>
<li>Следующий вариант это коллеги. Если в одной организации есть несколько лояльных клиентов, то такую организацию будет гораздо проще поставить на какое либо корпоративное обслуживание. Опять же будет возможность улучшить лояльность компании, которой делается соответствующее предложение, предложив перед этим какой то бонус найденным (но ничего не подозревающим) «инсайдерам». Но это уже в сторону вирусного маркетинга и пр., тут главное что нашли точку куда можно приложить силу.</li>
</ul>
<p>На самом деле тут можно придумать много очень хитрых вариантов использования, все зависит конкретно от тонкостей текущего бизнеса.</p>
<p>Да, и еще, тут еще интересный момент есть: для обнаружения связей между клиентами можно воспользоваться базами «Одноклассников» и «В Контакте». Если у нас не трудно достать базы не только всех гос. структур, но и вполне серьезных коммерческих организаций, банков и операторов сотовой связи, то база «Одноклассников» вообще не проблема, рано или поздно базы социальных сетей будут в продаже. Кстати, в случае БД социальных сетей типа «Одноклассников» все даже проще, так как доступ ко всем связям есть извне, через web, не надо прямого доступа к серверам. Я более чем уверен что уже есть софт который вытаскивает всю нужную информацию с этих сайтов и сохраняет ее в нужном виде. В конце концов вполне реально самостоятельно сделать парсинг подобных сайтов и последующее насыщение профайла, по мере надобности, так даже правильнее будет. Причем это будет вполне законно, в отличии от краденных баз.</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2008/06/18/chto-daet-ochistka-dannyx/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Выбор лучшего алгоритма хэширования строк</title>
		<link>http://artamonov.ru/2008/05/08/best-hashing-algorithm/</link>
		<comments>http://artamonov.ru/2008/05/08/best-hashing-algorithm/#comments</comments>
		<pubDate>Thu, 08 May 2008 13:35:47 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[DJB]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[int]]></category>
		<category><![CDATA[SDBM]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[алгоритм]]></category>
		<category><![CDATA[строки]]></category>
		<category><![CDATA[хэш]]></category>

		<guid isPermaLink="false">http://artamonov.ru/?p=73</guid>
		<description><![CDATA[
Неоднократно слышал о том что метод вычисления хэша, реализованный по умолчанию, для строк в Java не совсем хороший. Якобы много коллизий и пр. На замену ему можно найти в интернете несколько иных алгоритмов, но тоже непонятно какой лучший.
Поэтому проведем экперимент, сравним алгоритм по умолчанию, и пару считающихся лучшими алгоритмов. Выберем, так сказать, the best of [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://artamonov.ru/wp-content/uploads/2008/05/t1-150x150.png" alt="Качество хэшей, отклонение от оптимального" title="Отклонения хэшей" width="150" height="150" style="float:left; margin-right:10px;"/><br />
Неоднократно слышал о том что метод вычисления хэша, реализованный по умолчанию, для строк в Java не совсем хороший. Якобы много коллизий и пр. На замену ему можно найти в интернете несколько иных алгоритмов, но тоже непонятно какой лучший.</p>
<p>Поэтому проведем экперимент, сравним алгоритм по умолчанию, и пару считающихся лучшими алгоритмов. Выберем, так сказать, the best of the best среди хэширования <img src='http://artamonov.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Конкретно для меня, это равная вероятность состояний отдельных бит, в 32х битном целом. Т.е. чем ближе вероятность появления &laquo;1&#8243; в каждой из позиций к вероятности 1/2 тем лучше.<br />
<span id="more-73"></span><br />
И так, помимо алгоритма по умолчанию решил попробовать SDBM:</p>
<pre class="code_java"><code>public int hash(String val) {
    int hash = 0;
    for (char c: val.toCharArray()) {
	hash = c + (hash << 6) + (hash << 16) - hash;
    }
    return hash;
}
</code></pre>
<p>и DJB2:</p>
<pre class="code_java"><code>public int hash(String val) {
    int hash = 0;
    for (char c: val.toCharArray()) {
	hash = ((hash << 5) + hash) + c;
    }
    return hash;
}
</code></pre>
<p>и подсчитал отклонение от середины для случайно сгенеренных слов (как коротких так и длинных), на английском, русском, смешанном, смешанном+случайный регистр.</p>
<p>И вот график среднего отклонения, по этим четырем тестам:<br />
<img src="http://artamonov.ru/wp-content/uploads/2008/05/t1.png" alt="Качество хэшей, отклонение от оптимального" title="Отклонения хэшей" class="aligncenter size-medium wp-image-74" /><br />
По оси X - номер бита, по Y отклонение от равномерного, среднее для 4х тестов.<br />
Видно что алгоритм по умолчанию, что DJB2 нормально работают лишь для первых 15 бит, дальше отклонения все больше и больше (на практике понижается вероятность заполнения бита по мере удаления от начала) В Java же int является 32х битным, поэтому в таком случае лучше использовать SDBM, который гораздо меньше отклоняется.</p>
<p>Да, кстати, для чисто русского текста результаты всегда получше чем для чисто английского и даже их смеси.</p>
<p>Количество коллизий я не замерял, но судя по <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/142054">некоторым тестам</a> sdbm здесь тоже себя хорошо ведет.</p>
<p>PS: это для моих потребностей важна именно равномерность, не буду утверждать что для всех остальных случаев SDBM алгоритм лучше/быстрее/пр., но вероятно что именно так.</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2008/05/08/best-hashing-algorithm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Обработка данных, подход &#171;MapReduce&#187;</title>
		<link>http://artamonov.ru/2008/02/21/obrabotka-dannyx-podxod-mapreduce/</link>
		<comments>http://artamonov.ru/2008/02/21/obrabotka-dannyx-podxod-mapreduce/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 11:07:03 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Базы данных]]></category>
		<category><![CDATA[Новые технологии]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[cloud computing]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gridgain]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[map reduce]]></category>
		<category><![CDATA[split aggregate]]></category>
		<category><![CDATA[кластеризация]]></category>
		<category><![CDATA[обработка данных]]></category>

		<guid isPermaLink="false">http://artamonov.ru/2008/02/21/obrabotka-dannyx-podxod-mapreduce/</guid>
		<description><![CDATA[В 2004 году Google рассказал о модели обработки данных которую они использую. Основана она на том что данные обрабатывает пара простых функций Map и Reduce. Первая их которых выделяет множество пар Ключ/Значений из входящих данных (тоже являющихся парами Ключ/Значение), а вторая производит объединение/группировку этих пар, и, опять же, выдает наружу таки пары, чаще всего в [...]]]></description>
			<content:encoded><![CDATA[<p>В 2004 году Google рассказал о модели обработки данных которую <a href="http://labs.google.com/papers/mapreduce.html">они использую</a>. Основана она на том что данные обрабатывает пара простых функций <code>Map</code> и <code>Reduce</code>. Первая их которых выделяет множество пар Ключ/Значений из входящих данных (тоже являющихся парами Ключ/Значение), а вторая производит объединение/группировку этих пар, и, опять же, выдает наружу таки пары, чаще всего в меньшем количестве чем пришло на вход. Дополнительным элементом является распределенная файловая система GoogleFS, благодаря которой обрабатываемый файл, и вся промежуточная информация, становится легко доступной с любого компьютера в кластере.</p>
<p>Т.к. вся архитектура обработки состоит из небольших функций, то обработку можно легко распараллелить на кластере. К тому же облегчает разбивка на отдельные куски и восстановление после сбоя. Используя распределенную ФС мы разбиваем данные на небольшие кусочки, с каждым из которых и работает отдельный элемент кластера. </p>
<p>Так же эту идею можно встретить под названием Split/Aggregate. Т.е. суть в том что входные данные (неважно какого размера) разбиваются на отдельные элементы (этап split), к примеру построчно, каждая строка как отдельное значение для обработки. Эти блоки строк раcпределяются по кластеру для обработки, где для каждой строки вызывается функция обработки (map). Результат выполнения опять объединяется (reduce/aggregate) в выходной файл. Если нужно, то данные сохраняются отсортироваными в определенном порядке, к примеру по внешнему ключу.<br />
<span id="more-60"></span></p>
<h1>Область применения</h1>
<p>Сам подход очень хорошо подходит для длительной обработки больших объемов данных, причем когда нам не требуется определенная последовательность процесса или получение результата по мере поступления новых данных. Т.е. если у нас в наличии пару гигабайт данных для обработки и нам нужен конечный результат обработки, то это отличный вариант, но если у нас тот же гигабайт постоянно поступает небольшими кусочками, и мы должны их тут же отправлять на обработку, ожидая результат как можно скорее, то удобней иной подход, нежели чем MapReduce и Hadoop в частности.</p>
<p>Например это очень подходит когда нам нужно обработать стопку csv файлов. Ну или один, но большой. В каждой строке несколько колонок с данными, на основе этого получаем результат, тоже в csv. Так вот обработку такого файла легко распаралелить на нескольких машинах, построчно, или блоками, скажем по 100 строк, равномерно раскидать по серверам, обработать, а потом результирующие строки склеить в выходной файл. Если надо можно еще отсортировать чтобы было в том же порядке что и во входящих данных. Все это требует гораздо меньше ресурсов чем сама обработка данных. </p>
<p>Есть мнение что при обработке данные не стоит перегонять в текстовые файлы, пусть все хранится в БД, и читать оттуда поблочно, тут же складывая полученные результаты. В этом тоже есть свои плюсы и минусы, тут каждый решает сам, в зависимости от задач. Распределенная ФС, кстати, очень хорошо заменяет БД как центральное хранилище данных, а привести в структурный вид, удобный для БД можно уже и отдельным этапом (например отдельной задачей mapreduce). Хотя загрузку и средствами БД можно легко и быстро сделать.</p>
<h1>Пример алгоритма</h1>
<p>Приведу один простой пример, может понятней будет.</p>
<dl>
<dt>mapNumbers(&laquo;1, 4 and 3&#8243;)</dt>
<dd>Пусть он выделит все цифры в тексте, например регэкспом \d+, не суть важно. В нашем случае выдаст пары {num:1, num:4, num:3}, где num  &#8211; имя ключа, а 1,4 и 3 &#8211; его значения</dd>
<dt>reduceSum(num[])</dt>
<dd>На вход придет список пар с одинаковым ключем, в нашем случае ключ num. Пусть метод выполняет суммирование всех цифр для переданного списка пар. Т.е. в нашем случае ему на вход придут те три пары num:#, и он произведет суммирование 1 + 4 + 3, выдав 8</dd>
</dl>
<p>На самом деле функции иногда в сотни раз сложнее, но суть та же.</p>
<h1>Реализации MapReduce кластера под java</h1>
<h2>Apache Hadoop</h2>
<p><a href="http://hadoop.apache.org/">Apache Hadoop</a> &#8211; одна из основных реализаций системы для такой обработки. Поддерживает как MapReduce так и распределенную файловую систему (HDFS). Подпроектом еще идет как минимум реализация BigTable. map/reduce могут быть написаны не обязательно на Java, вполне подойдет все что может запускаться под этой ОС. Кстати, базовой ОС является Unix, хотя как я понимаю под Windows тоже работает, через cygwin.</p>
<p>Недавно Yahoo! <a href="http://developer.yahoo.com/blogs/hadoop/2008/02/yahoo-worlds-largest-production-hadoop.html">сообщил</a> что они успешно используют Hadoop для обработки объемов порядка 300 терабайт на кластере из 10 000 серверов. Из чего можно сделать вывод что для повседневных задач по обработки текущих данных Hadoop хватит с лихвой.</p>
<h2>GridGain</h2>
<p><a href="http://www.gridgain.com">GridGain</a> скорее рассчитан(но не ограничивается этим) не на обработку терабайтов данных, а разбиение на кучу задач, не важно каких. Больше подходит название SplitAggregate. Т.е. мы задаем объем задач, GridGain раскидывает это по кластеру, и далее передает нам результат. И здесь уже хоть сразу все через БД делай, хоть используй поверх распределенной ФС (от того же Hadoop даже), не суть важно. Авторы к примеру предлагают так юнит тесты запускать, т.е. разбиваем по методам на кластер, и все они параллельно тестируются. Надо это попробовать, если окажется десяток лишних компов под рукой <img src='http://artamonov.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>А еще эти товарищи очень не любят писать лишний код сами, а предпочитают интегрировать готовые, зарекомендовавшие себя решения. Что я считаю очень правильно, зачем лишний раз изобретать велосипед? Так вот, я к тому что система получается очень гибкая, красиво написанная, настраиваемая в спринге и интегрируется с кучей прочих около grid решений. </p>
<h1>Cloud Computing</h1>
<p>В свете последнего расцвета cloud computing, сервисов типа Amazon S3 и EC2 все это становится довольно интересным. Сейчас можно не ждать несколько часов для обработки, когда можно запустить все это на кластере из сотен серверов, получить результат через несколько минут заплатив за аренду этого кластера совсем небольшую сумму.</p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2008/02/21/obrabotka-dannyx-podxod-mapreduce/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Пример очистки данных</title>
		<link>http://artamonov.ru/2006/07/12/primer-ochistki-dannyih/</link>
		<comments>http://artamonov.ru/2006/07/12/primer-ochistki-dannyih/#comments</comments>
		<pubDate>Wed, 12 Jul 2006 06:18:01 +0000</pubDate>
		<dc:creator>splix</dc:creator>
				<category><![CDATA[Мои проекты]]></category>
		<category><![CDATA[Обработка данных]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[data mining]]></category>
		<category><![CDATA[text mining]]></category>
		<category><![CDATA[алгоритм]]></category>
		<category><![CDATA[бренды]]></category>

		<guid isPermaLink="false">http://www.artamonov.ru/2006/07/12/primer-ochistki-dannyih/</guid>
		<description><![CDATA[Я практически ничего не писал о том, чем именно я сейчас занимаюсь, но это у меня часто спрашивают, и мало кому понятно, что такое &#171;Очистка данных&#187;. Постараюсь это объяснить.
Очистка данных нужна, к примеру, организации, которая анкетирует своих покупателей на предмет того, что и где они покупали. Это может быть по почте, через сайт, еще как-то, [...]]]></description>
			<content:encoded><![CDATA[<p>Я практически ничего не писал о том, чем именно я сейчас занимаюсь, но это у меня часто спрашивают, и мало кому понятно, что такое &laquo;Очистка данных&raquo;. Постараюсь это объяснить.<br />
Очистка данных нужна, к примеру, организации, которая анкетирует своих покупателей на предмет того, что и где они покупали. Это может быть по почте, через сайт, еще как-то, источник не важен, но факт что данные могут придти различные.</p>
<p>В общем, расскажу на примере одной недавней задачки.<span id="more-43"></span></p>
<p>Вот возьмем такую задачу: в анкете есть поле, заполняемое названием магазина, а организации, к примеру, надо делать отчет по покупкам в определенных магазинах. Ну хотя этот отчет можно на основе других данных сделать. Да на самом деле неважно, зачем эти данные могу понадобиться, они точно требуются, и в нашем случае важно то, что они должны быть обрабатываемы и понятны.</p>
<p>Начинаем разбирать&#8230; Фантазия людей безгранична: вот возьмем к примеру <em>Евросеть</em>, как название только не напишут, могут как <em>&laquo;ЕВРОСЕТЬ ЦЕНТР&raquo;</em>, или <em>&laquo;ЕВРОСЕТЬ (ООО ЦЕНТР ХАБАРОВСК)&raquo;</em>. Ну с этим все более понятно, есть вхождение слова Евросеть и значит нашли магазин.</p>
<p>Следующий вариант это написание типа <em>&laquo;Evroset&raquo;</em>. Сразу не найдем, тут нам надо сделать обратную транслитерацию. А есть, кстати, тот же <em>DIXIS</em>, для которого получается надо делать обратную операцию. </p>
<p>С учетом транслитерации и самих ошибок начинаются проблемы, потому люди пишут и как <em>&laquo;Evroset&raquo;</em>, и как <em>&laquo;Euroset&raquo;</em>, как &laquo;<em>euroset.ru&raquo;</em>, да и в общем-то тоже самое для русского. К тому же бывают опечатки, или просто незнания правильного написания. <em>&laquo;Техносила&raquo;</em> может быть написана как <em>&laquo;TECHNOSILA&raquo;</em>, или как <em>&laquo;TEHNO SILA&raquo;</em> (буковки C вообще нет), и т.д. А как вам <em>&laquo;ЦИФРАГАД&raquo;</em>(видимо не угодил он покупателю) и &laquo;ЦИФР0ГРАД&raquo; (Ноль вместо О, не иначе как кулхаксор писал), или <em>&laquo;ЦЫФРАГРАТ&raquo;</em> (ага, афтар жжет)?<br />
Вывод такой: искать по вхождению не имеет смысла. Перебирать все варианты возможных ошибок, фантазий и пр. для каждого магазина просто нереально. Итого остается вариант искать по близости написания. Т.е. строка сравнивается по написанию со всеми магазинами, и берется тот, который наиболее похож. Естественно нужно еще найти какой-то минимальный порог, меньший 100% совпадения, но очень высокий, чтобы <em>&laquo;ТЕХНОМИКС&raquo;</em> не совпадал с <em>&laquo;ТЕХНОМИР&raquo;</em>.</p>
<p>Сравнивать полную строку нет смысла, потому что чисто символьная разница между &laquo;СВЯЗНОЙ В ОКЕЕ НА МАРШАЛА ЖУКОВА&raquo;, &laquo;СЕТЬ МАГАЗИНОВ САТЕЛЛИТ&raquo; и пр. далека от написания самого названия магазина. Из первой фразы надо сразу убирать адрес, но это просто, мы убираем все окончания начинающиеся на &laquo;на&raquo;, &laquo;у&raquo;, &laquo;ул&raquo;, &laquo;в&raquo;, &laquo;пр&raquo;. Второй случай содержит часто употребимые слова, их можно выделить даже мельком пробежав все названия, хотя лучше с этим справился простенький скрипт. Но, так как даже после этого, во фразе все равно может остаться невыловленный нами мусор, надо сравнивать слова по отдельности, а не всю фразу. </p>
<p>Думаете стало находить? А фиг то там! Потому что если мы начнем таким образом сравнивать &laquo;EURO SET&raquo; и &laquo;BETA LINK&raquo;, или, что еще хуже, &laquo;ЗАОБЕТА ЛИНК СПБ&raquo;, то они станут непохожи, ведь из слова &laquo;BETA LINK&raquo;, что &laquo;бета&raquo; что &laquo;линк&raquo; лишь наполовину похожи на <em>&laquo;беталинк&raquo;</em>&#8230; Поэтому надо сравнивать слова не только по одному, но и группами близлежащих, и к тому же не учитывая пробелы&#8230;</p>
<p>А еще надо учитывать чтобы из-за этой похожести &laquo;ДОМ.ТЕХНИКА&raquo; не совпал с &laquo;ДОМОТЕХНИКА&raquo; <img src='http://artamonov.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Тут, на самом деле, начинается новая проблема. И если дальше копать, то выясняем что магазинов с элементами &laquo;техно/техника/техникс&raquo;, &laquo;мир&raquo;, &laquo;центр&raquo;, &laquo;видео&raquo; и пр. просто немеряно <img src='http://artamonov.ru/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  А ведь чем длиннее строка тем меньшую непохожесть вносит всего одна опечатка. Поэтому подобные элементы нужно сразу учитывать, чтобы не вносили погрешности. Но, опять же, тут надо учитывать что есть <em>&laquo;М-ВИДЕО&raquo;</em>, который почти полностью состоит из одного из этих самых частоупотребимых элементов. Т.е. в данном случае нельзя отбрасывать эту часть, как мы делали с простым мусором (который упомянул выше, как например &laquo;СЕТЬ МАГАЗИНОВ&raquo;). Эти элементы надо сравнивать как обязательную и неотемлимую часть. И в тоже время требовать, чтобы ничего лишнего не было, т.е. &laquo;МИР ВИДЕО И АУДИО&raquo; это уже должно подпадать под мусор.</p>
<p>Да, и еще, насчет этих частоупотребымих элементов и мусора. Есть не только магазины, который в офлайне, но и интернет-магазины. А уж они то любят занять распространенное слово. И если на сайте telephone.ru продается достаточно товаров чтобы быть заметным, то нужно уметь его выделять. Вы думаете что его пишут как название сайта? Фиг то там! Он и сам себя именует как телефон.ру, и поэтому его пишут например как: &laquo;РОСТОВ.ТЕЛЕФОН.РУ&raquo; и так далее с учетом всех возможных опечаток. И выделяя его, нам ни в коем случае нельзя ошибиться и выделить &laquo;СОТОВЫЕ ТЕЛЕФОНЫ&raquo;. Хотя в действительности для подобных сайтов не требует внесения каких-то особо уникальных вещей в алгоритм, но иметь ввиду это надо.</p>
<p>Ладно, это мы чуток разобрались с общеизвестными брендами, написание которых, чаще все же уникально. А ведь есть некоторые &laquo;псевдобренды&raquo;, или не знаю как назвать. В общем, суть в том, что многим нашим предпринимателям лень думать над уникальным названием, и очень многие берут себе название типа &laquo;МИР&raquo;, &laquo;МИР ТЕХНИКИ&raquo;, &laquo;БЫТОВАЯ ТЕХНИКА&raquo;, &laquo;ЭЛЕКТРОНИКА&raquo;. И этих название просто куча в анкетах, и хотя клиент прекрасно понимает, что как таковой сети магазинов с таким именем нет в природе, но учитывать надо, из-за того, что слишком часто упоминается. И ведь приходится <img src='http://artamonov.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  И, с учетом всего вышенаписанного, &laquo;БЫТОВАЯ ТЕХНИКА&raquo; должна отличатся от &laquo;МИР БЫТОВОЙ ТЕХНИКИ&raquo;, от &laquo;ВИДЕО И БЫТОВАЯ ТЕХНИКА&raquo;, но совпадать с &laquo;БЫТОВАЯ ТЕХНИКА 4&#8243;, &laquo;БЫТОВАЯ ТЕХНИКА МАГАЗИН №12 ЧП СОКОЛОВ С.И.&raquo;, а &laquo;МИР&raquo; не должен совпасть с &laquo;АПЕЛЬСИНОВЫЙ МИР&raquo;, &laquo;МИР ТЕХНИКИ&raquo;, но совпадать с &laquo;МИР В ГИПЕРМАРКЕТЕ СЕМЬЯ&raquo; ну и т.д. Т.е. мусор если и может присутствовать, то только указывающий на месторасположение или тип.</p>
<p>Вот примерно такими вещами я сейчас и занимаюсь, если кому не лень тот может попробовать реализовать такой алгоритм, он не такой уж и сложный <img src='http://artamonov.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Я привел на примере магазинов цифровой техники, но примерно также делается и для многих других вещей: для брендов, названий товаров, автомобилей и пр. что имеет конечный описанный объем названий. А вот когда требуется просто выделить что-то из фразы, к примеру адрес, то тут все гораздо хитрей.<br />
А еще подумайте как вообще можно написать адрес, или телефон, и как же определить настоящие это данные или нет, и поверьте, фантазия людей похоже действительно не имеет границ.<br />
А ведь мало написать выделение данных, нужно чтобы алгоритм сразу отбрасывал, как мусор, данные о человеке типа &laquo;Мери Попинс, ул. Ленина 1 кв. 1, тел. 123-12-34&#8243; <img src='http://artamonov.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Если интересно, то еще немного можно почитать на OSP.RU: <a href="http://old.osp.ru/pcworld/2006/05/056.htm">Фываяч и Микки Маус</a> и <a href="http://old.osp.ru/pcworld/2006/06/046.htm">Пылесосы в ассортименте</a></p>
]]></content:encoded>
			<wfw:commentRss>http://artamonov.ru/2006/07/12/primer-ochistki-dannyih/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
	</channel>
</rss>
