Обновить
Комментарии 41
В случае, если запрашиваемый объект находится на том же узле, на котором выполнен запрос, то (время получения) = (время на десериализацию).
А поиск в Map за фиксированное время?

При использовании IMDG вы всегда получаете актуальные данные, т.к. при выполнении put отсылается уведомление всем узлам кластера о том, что объекты с такими-то ключами получили новое значение.
А CME словить нельзя?
Достать объект из Map по ключу — это O(1).
Простите, а что такое CME?
Concurrent Modification Exception. А то я себе не представляю синк в кластере.
Спасибо за вопрос, в следующей статье раскрою эту тему, а пока собираю вопросы, т.к. если написать всё сразу, то получится слишком большая статья, и никто её не будет читать, поэтому в вводной статье оставил только описание самой концепции.
А проблема concurrent modification в кластерах решается за счет механизма распределенных блокировок.
Подписался на ваш блог по RSS. Очень надеюсь, что это только первый пост из серии:)
Спасибо.
Да, я планирую написать еще как минимум 2 поста. Надеюсь уложиться до конца августа.
Пожалуйста, пишите продолжение с конкретными реализациями, очень интересно будет почитать.
Особенно интересны будут сравнительные тесты, например, с парой популярных NoSQL для highload нагрузки. Понимаю, что это очень большая работа, но всё-таки очень прошу привести хотя бы какие-то минимальные, но конкретные цифры для сравнения.
Заранее большое спасибо!
Да, это займет время, но оно того стоит.
У вас нет предложений по конкретным NoSQL для тестов? MongoDB, Redis, CouchDB, Membase?
Это только кэширующий кластер, но не NoSQL решение для постоянного хранения данных. Т.е. memcached хранит данные в памяти, следовательно если вы кладете кластер, то теряете все данные.
Понятно, что данные хранятся в базе, а memcache используется для кеширования. Imdg ведь тоже можно так же использовать?
да, можно и так его использовать. Кстати в JBoss Infinispan встроена поддержка интеграции с memcached
Интересно было бы почитать про сравнение с Riak.
В NoSQl базах для был всегда не понятен один вопрос, здесь тоже:
Если мне нужно получать данные не по ключу, а по диапазону (дат),
как это реализуемо?
Индексы.
В некоторых IMDG (например Oracle Coherence), индексы распределены по узлам кластера, т.е. на каждом узле лежит кусочек индекса, который относится к данным на этом узле. Затем каждый запрос выполняется отдельно на каждом узле кластера, а результаты стекаются на тот узел, который инициировал запрос, там они и формируют конечный ответ. В некотором роде это Map Reduce.

В некоторых гридах индексирование данных выполняется с использованием open source поисковых движков. Примером служит JBoss Infinispan, в котором используется Apache Lucene. Там индекс хранится в RAM Directory. Вопрос индексирования более подробно рассмотрю в следующей статье, так как в комментарий не поместится.
А разве Redis это не то? Они сейчас еще работаю над Redis Cluster, который обещают выпустить в конце лета.
1. Redis только готовятся выпустить свой кластер из коробки, тогда как Oracle купил компанию Tangosol (ради их продукта — Tangosol Coherence) аж в 2007 году. Т.е. надежность и отточенность этого продукта должна быть выше.

2. Кластер Redis — это только кластерное key-value хранилище, в то время как in-memory-data-grid подразумевает организацию распределенных вычислений на хранящихся данных, а также их обработку.

3. Redis не может быть кэшом 2 уровня (поправьте меня, если я не прав, ибо нет 100% уверенности) какого-нибудь ORM, а также не предназначен для того, чтоб стоять перед какой-нибудь реляционной БД и выполнять read-through/write-behind

4. Судя по презентации на их сайте, данные можно спросить только на той ноде, на которой они расположены. Если вы спросили не там, где надо — вернется ошибка и номер ноды, у которой надо спросить. Также можно написать (или он уже есть, я из презентации этого не понял) smart client, который будет сначала спрашивать карту кластера с распределением ключей по нодам, а потом спрашивать данные на нужной ноде.
В то время как в гриде вам абсолютно наплевать, в каком месте кластера лежат данные, потому что по запросу их доставят на ту ноду, откуда поступил запрос.

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

6. Запрос к Redis составляется на их внутреннем языке запросов, потому что NoSQL — это отдельное приложение, доступ к которому осуществляется снаружи. IMDG — это часть вашего приложения. А так как кэши реализуют интерфейс Map, то и обращаться с ними вы можете как с обычными объектами вашего приложения. Соответственно, если вам надо не просто достать объект по ключу, а сделать какой-либо запрос, то вы пишете его на Java (подставьте сюда любой другой язык, который поддерживается конкретным IMDG решением), что позволяет получить из хранилища сразу объекты вашей доменной модели и без необходимости трансформации.

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

В общем я вижу сильные различия в тех подходах, которые выбрали разработчики Redis Cluster и концепцией IMDG.
хм, не совсем так, gigaspaces тоже необходимо указывать routing. Без него на partitioned схемах будут проблемы при чтении.
Некоторые вопросы:

1. Не совсем понял почему не подходит вариант с кешом, якобы данные там могут устареть, ведь по своей сути IMDG ничем от него не отличается, кроме того что добавился слой распределения по кластеру. К тому же даже IMDG не снимает проблему когда к db имеется несколько точек доступа, то есть не только наше приложение, но и кто-то для оптимизации полез ручками напрямую, данные в распределённый IMDG не попадут, так как о них он не узнает.

2. Сравнение с nosql считаю не совсем корректным, если уж и сравнивать, то с тем же кластером memcache.

2.1. NoSQL — это полноценные решения которые гарантируют, что если у вас во всех dc резко погас свет (а такое даже у амазона бывает), то данные не пропадут.
2.2. Имеются объёмы данных которые все в кеш запихивать нецелесообразно(есть горячие, а есть очень редко используемые, в итоге иногда и можно подождать пока они подтянуться) или невозможно (большие объёмы). А уж если действительно нужна скорость ставьте памяти побольше, в итоге что у IMDG всё будет в памяти, что у NoSQL всё в памяти и выдача моментом.

3. «NoSQL — это отдельное приложение, доступ к которому осуществляется снаружи. IMDG — это часть вашего приложения. » — различие не совсем понятно, что IMDG может работать в той же jvm, что и само приложение (лично имел опыт работы с ehcache + terracotta) ясно, но вот дальше как-то смазано. И IMDG в основе своём требует сервера для поддержания кеша в памяти, и NoSQL отдельных серверов для хранения данных, отличие сводится к разным реализациям backend для слоя данных, интерфейс у них будет одинаков get/put/delete.

4. Может я и ошибаюсь, но если у нас имеется db для хранения финансов, то использовать там прослойку в виде IMDG рискованно, только явные транзакции в db.

p.s. по поводу использовать nosql как промежуточный кеш для снижения нагрузки к db встречал только если это memcache в кластере, в противном случае полностью согласен, что распределённый кеш в памяти более предпочтителен. На практике использовал архитектуру: распределённый кеш на terracotta + вся запись в бд через очередь сообщений на изменение данных, после изменения данные сразу обновляются в кеше, но в базу попадают с задержкой.
Что я подразумеваю под «IMDG — это часть вашего приложения»:
Допустим, вы написали конфиг вашего кластера config.xml, после этого вы пишете класс наподобие такого
public class MyClass {
private Map<KeyType, ValueType> myCache;

public void startCluster() {

IMDGConfig config = new IMDGConfig("config.xml");
CacheManager manager = new CacheManager(config);
myCache = manager.getCache("someName");
}
}


Всё, больше никаких движений совершать не нужно. После этого вы сможете спокойно класть объекты в myCache. Здесь это поле имеет тип Map, т.к. кэш реализует этот интерфейс, но вы вполне можете использовать тип Cache для получения дополнительных возможностей, но с точки зрения использования этот кэш всё равно останется всего лишь полем класса.
Более того, если вы запустите этот код на двух jvm, то они автоматически соединятся в кластер.

Что касается get/put/delete, то возможности IMDG этим не ограничиваются.

4. IMDG поддерживает распределенные транзакции, и например в Deutsche Bank активно используется Oracle Coherence. Правда я там не работал, и не могу утверждать, что он там используется именно для проведения финансовых транзакций, но исключать этого не могу, т.к. все возможности для этого есть.

P.S. А вы не писали статью на тему своего опыта работы с terracota? Если писали, то поделитесь пожалуйста ссылочкой, мне было бы интересно, а если нет, то считайте это официальным реквестом:)
Прошу прощения, ответы на первые 2 вопроса куда-то подевались.

1. Если имеется несколько точек доступа к БД, то вы правы, но я рассматривал ситуацию, при которой есть только одно тяжелое приложение, которое хорошо нагружает БД, а IMDG стоит между базой и приложением. Тогда все запросы на чтение и запись идут не в БД, а в грид, поэтому там всегда содержатся актуальные данные. А грид уже в свою очередь может отправлять асинхронные запросы на запись в БД, либо накапливать объекты и потом записывать сразу пачкой и т.п. В этом случае нагрузка на базу минимальна, но и в базе и в кэше содержатся актуальные данные.

2. Не соглашусь с вами. IMDG — это скорее NoSQL + кластерный кэш + возможность обработки данных.

2.1. IMDG умеет писать в БД, файл или любое другое хранилище данных, таким образом тоже может обеспечивать долговременное хранение данных.

2.2. В посте я указывал, что возможны разные варианты загрузки данных в грид:
— с самого начала выкачать из постоянного хранилища (БД) необходимые данные
— ничего при старте не выкачивать (если память или время поджимают), а подтягивать данные во время выполнения запроса

Поэтому необязательно иметь количество памяти соответствующее объему данных.
по поводу удобства когда имеется интерфейс map я с вами спорить не буду, но следом возникают вопросы:

«IMDG умеет писать в БД, файл или любое другое хранилище данных, таким образом тоже может обеспечивать долговременное хранение данных.» — насколько я помню та же теракота умеет хранить данные только в памяти, и если с ehcache ещё возможно использовать отдельно с дампом на диск, то при переводе её в кластерный вариант остаётся возможность только держать в памяти, да и чем большинство плюсов по скорости сразу пропадают когда начинается вытеснение данных на диск.

«IMDG — это скорее NoSQL + кластерный кэш + возможность обработки данных.» — что вы подразумеваете под «возможность обработки данных», большинство nosql решений имеют встроенные средства для обработки данных, в основном на парадигме MR (mongodb — внутри, hbase,cassandra — легко подключаются к hadoop).

Чтобы внести ясность: я не говорю что IMDG ненужен или ещё что-то, на нём действительно можно строить распределённый кеш для RDBMS, быстрые очереди сообщений, согласен что использовать nosql для кеширования тоже совсем правильно, НО в некоторых местах лучше бы подошла nosql база данных, вместо связки реляционной db + кластерный кеш.

p.s. с теракотой работал год назад, в данный момент активно занимаюсь hadoop/hbase, так что уж если и писать, то по ним.
Про терракоту спорить не буду, вы лучше меня знаете, что она умеет. EhCache тоже не трогал руками, но если он также интегрирован в приложение, то ничего не мешает написать слушателя, который на каждый put будет выполнять сохранение данных куда-либо. Насчет падения скорости при дампе на диск — согласен, но туда можно сбрасывать данные, которые редко нужны либо просто в качестве бекапа на случай падения кластера.

Под обработкой данных я подразумеваю MR, который выполняется без десериализации данных, возможность переиндексирования данных при обновлении. Из коробки это есть (из известных мне) только в MongoDB, а в Redis, Membase, CouchDB поддержки MR нет, её надо прикручивать (возможно это и легко, спорить не буду).

Я тоже не говорю, что RDBMS + IMDG = SilverBullet :), и я согласен, что NoSQL решения богаты самыми востребованными функциями, но существуют ситуации, когда большие компании (а может и не очень большие) не могут отказаться от RDBMS в силу корпоративной архитектуры, где многие приложения являются потребителями (но не источниками) данных из БД.
Кстати IMDG может потреблять данные не только из БД, но и из веб-сервиса (что для NoSQL как мне кажется нелегко организовать).

Надеюсь, мы поняли друг друга в этом непростом вопросе, грозящем холиваром.
Когда мне ждать вашей статьи?:)
да, походу поняли =)
у каждой системы своя ниша и свой случай использования, знаю случаи когда решения в пределах одной системы сосуществуют не мешая друг другу (быстрый mq на самописной ситеме поверх Hazelcast и передача/хранения собщений пользователей в системе поверх hbase).

Про что конкретно вы хотите услышать?
Ту же теракоту давно не пинал, а про hbase и её возможности могу, только хотелось бы узнать что вам интересно.
Базовые возможности и поверхностно рассказать о том, как реализовано, чтоб можно было составить представление, также было бы интересно посмотреть, как к ней прикручивается Hadoop. Давно хочу его попробовать, но постоянно не хватает времени, которое я себе выделяю на самообучение.

На основе этого можно было бы попробовать присобачить его к какому-нибудь гриду (не для практики, а интереса ради) и сравнить скорость нативного MR с Hadoop.
Хотя если Hadoop работает только с HDFS, то сравнение будет не в его пользу
Если в одной из следующих статей будете сравнивать IMDG, включите туда, пожалуйста, Hazelcast.
Опыт с Hazelcast у меня пока только на уровне hello world, но я постараюсь изучить его глубже и включить в следующие статьи.
Во всех этих гридах меня более всего интересует вопрос: на сколько быстра синхронная репликация? Стоит ли овечка выделки? key-value легко шардятся, эффективны ли гриды на их фоне, если не брать во внимание другие недостатки?
Грид — это тоже key-value, и он также состоит из шард (партиций). Никакого лишнего трафика между нодами кластера нет, т.к. если вы добавляете объект в кэш, то он быстро летит на ту ноду, куда ему определит алгоритм хэширования, плюс к этому, в зависимости от конфигурации, могут быть созданы резервные копии, которые будут размещены на других нодах кластера, причем сделано это будет асинхронно, так что никакого оверхеда по времени это не вызывает.
Конечно можно использовать грид в режиме репликации данных (т.е. каждая нода хранит полную копию данных, об этом я напишу в следующем посте), но этот режим не является часто используемым.
Так, теперь я совсем запутался :) Поясните пожалуйста чем IMDG отличается от key-value хранилища, скажем от redis в кластере? Выше вы уже писали, но я ничерта не понял :)

>Кластер Redis — это только кластерное key-value хранилище, в то время как in-memory-data-grid подразумевает организацию распределенных вычислений на хранящихся данных, а также их обработку.

Можно вот тут по-подробней, что за распределенные вычисления?

>Redis не может быть кэшом 2 уровня (поправьте меня, если я не прав, ибо нет 100% уверенности) какого-нибудь ORM, а также не предназначен для того, чтоб стоять перед какой-нибудь реляционной БД и выполнять read-through/write-behind

Вот это просто особенность реализации.

И еще смущает вот что: в статье фигурирует слово «кэш», но «кэш» — штука, которая по определению не может гарантировать наличие какого-то значения. Или под кэшом имеется что-то другое?
1. Под распределенными вычислениями я подразумеваю MapReduce. Если разбирать на примере, то допустим у вас в кэше хранятся объекты, представляющие каких-то клиентов с их счетами, а вы хотите посчитать, сколько всего у них есть денег. Тогда вы на любом узле кластера отправляете запрос в кэш, этот запрос распространяется на все узлы, каждый узел подсчитывает свой результат и отправляет результат на тот узел, который инициировал запрос. А там результаты выполнения запросов с каждого узла складываются в один результат, который и возвращается.

2. Нет, это не особенность реализации. Это следствие того, что обращение к кэшам IMDG идет как к объектам вашего приложения (никаких удаленных вызовов вы не выполняете), т.е. вы кладете в IMDG ваши доменные объеты (Java-объекты, C#-объекты) без каких либо преобразований. Вы просто делаете cache.put(id, myJavaObject). Соответственно ORM, которые также оперируют с доменными объектами, могут использовать напрямую IMDG, и вам не придется хитро организовывать их взаимодействие. А если ORM будет брать данные не из БД, а из IMDG, то фактически IMDG будет являться кэшом этого ORM.

Также вы не сможете поставить Redis Cluster между вашим приложением и БД, потому что у него нет такого функционала (как я понял из презенации на их сайте). Если в Redis не оказалось требуемого объекта, то он вернет NULL, и вы не сможете сказать ему, чтоб он в этом случае сходил в БД, выполнил запрос, собрал из него доменный объект, выдал его вам и положил себе в хранилище.

3. Кэш — это key-value хранилище в памяти для объектов определенного типа. Т.е. когда вы конфигурируете и создаете кэш, то вы указываете какого типа будет ключ и какого типа будет значение, которое по этому ключу будет лежать.
А так как все операции записи будут идти в этот кэш (а дальше либо в БД, либо в веб-сервис, либо в файл, либо вам вообще не надо его сохранять вне памяти), то этот кэш всегда будет содержать только актуальные данные. Естественно, только в том случае, когда у вас нет приложений, которые работают в обход IMDG, потому что в этом случае данные в кэше и в БД могут различаться.
Спасибо, стало понятней. Все же странно, что фигурирует такое понятие, как кэш. Может конечно я один такой, но у меня в мозгу четка установка — кэш — это хранилище без гарантий на актуальность/сохранность данных.
понятие кэша просто предполагает хранение данных в памяти для быстрого доступа, при этом на актуальность данных это понятие никаких ограничений не накладывает.

Википедия со мной согласна:)
Поясните пожалуйста если IMDG это key-value решение то причем тут вообще реляционная db?
Реляционная БД тут при том, что IMDG может стоять перед этой БД. Если у вас есть серьезные причины, не позволяющие отказаться от реляционной базы, то вы можете просто выкачивать данные в IMDG и работать с ними там, при этом все изменения данных могут быть сохранены в БД для поддержания целостности данных.
Естественно, что модель данных для БД и для IMDG не будут совпадать, поэтому ваши Loader'ы будут обеспечивать преобразование данных из таблиц реляционной БД к вашей доменной модели.
Слышал, что используют такое решение: кластер мемкеш серверов с патчем, который отключает вытеснение данных, ttl и тому подобное. Такую систему можно считать IMDG?
Не думаю, что отсутствие вытеснения данных можно считать признаком IMDG. В IMDG как раз тоже можно настроить expiration, eviction, passivation и т.д.

И еще раз заострю внимание на том, что IMDG существует внутри вашего приложения, тогда как все остальные решения — это standalone кластеры с доступом снаружи через какой-либо API.

Да и возможности memcached по работе с persistence хранилищами не позволяют его считать IMDG
Плохо понятно про распределенные вычисления; ведь интерфейс к IMDG — это Map с точки зрения интерфейса это key/value о каких вычислениях речь?
Ну во-первых, кэш — это не только Map, он реализует и другие интерфейсы.

Во-вторых, в гриде можно создавать объекты (наподобие распределенной Callable и Executor), которые принимают кэш в качестве аргумента и выполняют над ним какие-либо действия.

Это может быть просто изменение данных, соответствующих какому-то условию, либо это может быть Map Reduce, который позволит вам на основе существующих данных получить некий результат
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.