Java-решения для распределенных транзакций и/или данных, совместно используемых в кластере

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

  • Какие технологии (методы разработки программного обеспечения или конкретные технологии) вы бы предложили для решения этого типа проблем?
  • Какие методы вы используете для разработки уровня сохраняемости для масштабирования для многих читателей/писателей. Масштабируйте транзакции приложений и масштабируйте доступ к общим данным (лучший подход — исключить общие данные; какие методы можно применить для устранения общих данных).
  • Кажется, нужны разные подходы в зависимости от того, читаются ли ваши транзакции или пишутся тяжело, но я чувствую, что если вы можете оптимизировать тяжелое приложение для записи, которое также было бы эффективным для "чтения"

«Лучшее» решение позволит вам написать приложение Java для одного узла и, надеюсь, «скрыть» большую часть деталей доступа/блокировки общих данных.

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

  1. Явные блокировки (которые чрезвычайно подвержены ошибкам и медленно координируются между несколькими узлами в распределенная система)
  2. Программная транзакционная память (STM) АКА оптимистичный параллелизм, при котором транзакция откатывается во время фиксации, если она обнаруживает это общее состояние изменилось (и транзакцию можно повторить позже). Какой подход лучше масштабируется и каковы компромиссы в распределенной системе?

Я исследовал решения для масштабирования (и вообще приложения, которые дают пример того, как масштабироваться), такие как:

  1. Terracotta – обеспечивает "прозрачное" масштабирование за счет расширения модели памяти Java путем включения распределенной общей памяти с использованием механизма блокировки параллелизма Java (синхронизированного, ReentrantReadWriteLocks).
  2. Google App Engine Java – Позволяет вам писать приложения Java (или Python), которые будут распределяться между «облачными» серверами, где вы распределяете, какой сервер обрабатывает транзакцию, и используете BigTable для хранения ваших постоянных данных (не знаете, как вы транзакции, которые обращаются к общим данным или обрабатывают конфликты блокировки для эффективного масштабирования)
  3. Сервер Darkstar MMO. Darkstar – это игровой сервер Sun с открытым исходным кодом для MMO (многопользовательская онлайн-игра). данная транзакция будет выполняться только для определенной суммы и фиксации, и если это займет много времени, она откатится (вроде как программная транзакционная память). Они изучают поддержку установки многоузлового сервера для масштабирования.
  4. оптимистическая блокировка Hibernate — если вы используете Hibernate, вы можете использовать оптимистическую поддержку параллелизма для поддержки поведения типа программной транзакционной памяти
  5. Предполагается, что Apache CouchDB естественным образом "масштабируется" для многих БД чтения/записи в сетчатой ​​конфигурации. (есть ли хороший пример того, как вы управляете блокировкой данных или обеспечением изоляции транзакций?):
  6. JCache — масштабирование "чтения" тяжелых приложений путем кэширования результатов до обычных запросы, которые вы можете использовать в Google appengine для доступа к memcached и для кэширования других часто читаемых данных.

Terracotta кажется наиболее полным решением, поскольку вы можете «легко» модифицировать существующее серверное приложение для поддержки масштабирования (после определения объектов @Root и методов @AutoLockRead/Write). Проблема в том, чтобы действительно получить максимальную производительность от распределенного приложения, оптимизация для распределенных систем на самом деле не является задним числом, вы должны разработать ее, зная, что доступ к объекту потенциально может быть заблокирован сетевым вводом-выводом.

Для правильного масштабирования кажется, что это всегда сводится к разделению данных и транзакциям балансировки нагрузки таким образом, чтобы заданная «единица выполнения» (ядро процессора -> поток -> узел распределенного приложения -> главный узел БД)

Похоже, что для правильного масштабирования любого приложения с помощью кластеризации вам необходимо иметь возможность разделять ваши транзакции с точки зрения их чтения/записи доступа к данным. Какие решения придумали люди для распределения данных своих приложений (Oracle, Google BigTable, MySQL, хранилища данных) и вообще, как вы управляете секционированием данных (много мастеров записи, гораздо больше баз данных чтения и т. д.).

С точки зрения масштабирования уровня сохраняемости данных, какой тип конфигурации лучше всего масштабируется с точки зрения разделения ваших данных на множество читателей/многих писателей (обычно я бы разделял свои данные на основе заданного пользователя (или любого другого основного объекта, который обычно является вашим «корневой» объект объекта), принадлежащий одной главной БД)


person Community    schedule 23.10.2009    source источник
comment
Сложная система, которая работает, всегда оказывается развившейся из простой системы, которая работала. Обратное утверждение также кажется верным: сложная система, созданная с нуля, никогда не работает и ее нельзя заставить работать. Вы должны начать все сначала, начиная с работающей простой системы. — Джон Галл   -  person Bob Aman    schedule 24.10.2009


Ответы (6)


Думал, что нашел отличную платформу Java Clustering/Distributed, хотел снова открыть это -

Оформить заказ http://www.hazelcast.com

Я запускал тестовые программы, они очень крутые, легкие и простые в использовании. Он автоматически обнаруживает элементы кластера в одноранговой конфигурации. Возможности безграничны.

person Community    schedule 20.05.2010

Спасибо за прекрасное обобщение всех возможностей в одном месте.

Однако здесь отсутствует одна техника. Это MapReduce-Hadoop. Если проблему можно подогнать под парадигму MapReduce, то это, пожалуй, наиболее доступное решение. Мне также интересно, можно ли расширить шаблон Actor Framework (JetLang, Kilim и т. д.) на кластер.

person srini.venigalla    schedule 23.10.2009

person alphazero    schedule 23.10.2009

Не забывайте Mnesia от Erlang.

Mnesia дает вам такие вещи, как транзакции, к которым вы привыкли в обычной БД, но обеспечивает операции в реальном времени и отказоустойчивость. Кроме того, вы можете перенастроить вещи без простоев. Недостатком является то, что это резидентная база данных в памяти, поэтому вам нужно фрагментировать действительно большие таблицы. Максимальный размер таблицы 4Gb.

person Bob Aman    schedule 23.10.2009
comment
Этот ответ действительно предназначен для понимания с точки зрения техники. Вы можете использовать Mnesia из Java через сокет, но на самом деле вам это не нужно. Смысл в том, чтобы учиться на том, что делает Mnesia. - person Bob Aman; 24.10.2009

Хотя Oracle Coherence и многие другие предлагаемые решения хороши для обмена данными, вы упомянули только блокировку и STM как способы управления изменением состояния в распределенной среде; оба эти способа, как правило, довольно плохие для масштабирования управления состоянием. На другом сайте я недавно опубликовал следующее о том, как реализовать (например) счетчики последовательности:

Если вы смотрите на счетчик, то использование чего-то вроде Coherence EntryProcessor легко обеспечит поведение «один раз и только один раз» и высокую доступность для любого количества монотонно возрастающих последовательностей; вот вся реализация:

public class SequenceCounterProcessor
        extends AbstractProcessor
    {
    public Object process(InvocableMap.Entry entry)
        {
        long l = entry.isPresent() ? (Long) entry.getValue() + 1 : 0;
        entry.setValue(l);
        return l;
        }
    }

Ага. Вот и все. Автоматическая и бесшовная высокая доступность, эластичность динамического масштабирования, однократное поведение и т. д. Готово.

EntryProcessor — это тип распределенного замыкания, который мы представили в 2005 году.

Кроме того, в Java 8 (еще не выпущенной) проект Lambda представляет официальную поддержку закрытия в языке и стандартных библиотеках.

По сути, идея состоит в том, чтобы доставить замыкание к местоположению «владельца» данных в распределенной среде. Coherence динамически управляет владением данными с помощью динамического разделения, позволяя распределенной системе распределять нагрузку данных между различными работающими машинами и узлами. На самом деле, по умолчанию все это на 100 % автоматизировано, поэтому вы никогда не указываете, куда помещать данные или сколько данных куда направляется. Кроме того, существуют вторичные (и, возможно, третичные и т. д.) копии данных, управляемые на других узлах и других физических серверах, чтобы обеспечить высокую доступность в случае сбоя процесса или отказа сервера. Опять же, управление этими резервными копиями по умолчанию полностью автоматическое и полностью синхронное, а это означает, что система по умолчанию имеет 100% HA (т. е. без настройки).

Когда закрытие поступает к владельцу данных, оно выполняется в рабочей области транзакций, и, если операция завершается успешно, оно отправляется в резервную копию для безопасного хранения. Мутация данных (например, результат операции) становится видимой для остальной части системы только после успешного создания резервной копии.

Несколько оптимизаций к вышеизложенному включают добавление интерфейсов ExternalizableLite и PortableObject для оптимизированной сериализации и избегание сериализации упакованных длинных данных путем непосредственного перехода к форме данных, «готовой к сети»:

public Object process(InvocableMap.Entry entry)
    {
    try
        {
        BinaryEntry binentry = (BinaryEntry) entry;
        long l = entry.isPresent() ? binentry.getBinaryValue()
                .getBufferInput().readLong() + 1 : 0L;
        BinaryWriteBuffer buf = new BinaryWriteBuffer(8);
        buf.getBufferOutput().writeLong(l);
        binentry.updateBinaryValue(buf.toBinary());
        return l;
        }
    catch (IOException e)
        {
        throw new RuntimeException(e);
        }
    }

И поскольку он не имеет состояния, почему бы не подготовить экземпляр singleton?

public static final SequenceCounterProcessor INSTANCE =
        new SequenceCounterProcessor();

Использовать его из любой точки сети так же просто, как одну строку кода:

long l = (Long) sequences.invoke(x, SequenceCounterProcessor.INSTANCE);

Где «x» — любой объект или имя, идентифицирующее конкретный счетчик последовательности, который вы хотите использовать. Дополнительные сведения см. в базе знаний Coherence по адресу: http://coherence.oracle.com/.

Oracle Coherence — это распределенная система. Всякий раз, когда вы запускаете узел Coherence, он соединяется с другими уже запущенными узлами Coherence и динамически формирует эластичный кластер. Этот кластер размещает данные секционированным, высокодоступным (HA) и транзакционно согласованным образом, а также содержит операции (подобные той, что я показал выше), которые работают с этими данными «один и только один раз».

Кроме того, в дополнение к возможности вызывать любую из этих логик или получать доступ к любым данным прозрачно из любого узла Coherence, вы также можете вызывать любую из этих логик или получать доступ к любым из этих данных прозрачным образом из любого процесса в сети (при условии аутентификации). и авторизация, разумеется). Таким образом, этот код будет работать с любого узла кластера Coherence или с любого (Java/C/C++/C#/.NET) клиента:

Поясню: я работаю в Oracle. Мнения и взгляды, выраженные в этом сообщении, являются моими собственными и не обязательно отражают мнения или взгляды моего работодателя.

person Community    schedule 11.08.2013

Возможно, вам будут полезны эти слайды. Исходя из нашего опыта, я бы порекомендовал Oracle (Tangosol) Coherence и GigaSpaces как самые мощные платформы распределения данных и обработки. В зависимости от точного характера проблемы, один из них может сиять. Терракота тоже вполне применима для решения некоторых задач.

person Community    schedule 11.12.2009