Apache синхронизация данных балансировки нагрузки между несколькими приложениями - PullRequest
3 голосов
/ 27 марта 2020

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

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

Эти два приложения имеют абсолютно одинаковую конфигурацию с точки зрения структуры абстракции базы данных, Spring Framework и др. c. Кроме того, эти два приложения работают на разных серверах Tomcat на разных физических серверах.

В чем может быть причина проблемы?

Редактировать

Hibernate настроен следующим образом:

enter image description here

Редактировать 2

Вот ehcache. xml

<cache name="org.hibernate.cache.internal.StandardQueryCache"
       maxElementsInMemory="10000"
       eternal="false"
       timeToLiveSeconds="86400"
       overflowToDisk="false"
       memoryStoreEvictionPolicy="LRU"/>

<defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToLiveSeconds="86400"
        overflowToDisk="false"
        memoryStoreEvictionPolicy="LRU"/>

Ответы [ 3 ]

2 голосов
/ 13 апреля 2020

Скорее всего, у вас проблемы с репликацией кэша, возможно, из-за отсутствия / неправильной конфигурации координации кэша.

Предположение

Вы включили кэш второго уровня и кэш запросов в Hibernate, который хорошо, конечно, и вы получили повышение производительности. Проблема заключается в том, что вы используете 2 узла, каждый из которых имеет свой собственный кэш, или они неправильно делают недействительными кэши.

Например, узел A выполняет запрос для всех объектов Z (т. Е. Список категорий продуктов: Z1 , Z2, ...) и кеширует результат. Позже, узел B добавляет новую сущность категории продуктов Zn. Узел A не будет использовать этот новый объект, пока его собственный кэш не станет недействительным; до тех пор он будет использовать кэшированный результирующий набор, который не включает Zn.

. Вы можете проверить это предположение, если проблема исчезнет, ​​когда вы отключите кэширование запросов (т. е. установите <property name="hibernate.cache.use_query_cache">false</property>).

Решения

Вариант A

Оптимизация аннулирования кэша. Это в значительной степени зависит от потребностей вашего бизнеса, но некоторые предложения будут следующими:

  • Уменьшайте TTL кэша для определенных запросов, пока не найдете подходящее место (промежуток времени, в течение которого вы можете допустить пропущенные / дополнительные значения). Для этого вы можете использовать регионы EhCache.
  • Отключить кэширование для всех объектов в целом

Пример:

Создать регион для короткого (то есть 5-минутного) запроса приводит к ehcache.xml:

<cache name = "short-lived"
maxElementsInMemory = "500"
eternal = "false"
timeToIdleSeconds = "600"
timeToLiveSeconds = "600"
overflowToDisk = "false"
/>

Для определенных c запросов, которые необходимо часто обновлять:

Query query = session.createQuery("FROM Z");
query.setCacheable(true);
query.setCacheRegion("short-lived");

Подробнее о topi c здесь .

Вариант B

Это решение real . Вы можете иметь кэш shared для всех узлов. Хотя это, безусловно, сложнее в настройке и настройке, это дает вам максимальную производительность Например, кэшированные запросы будут выполняться один раз для каждого кластера, а не один раз для каждого узла, как сейчас.

Взгляните на Terracotta .

0 голосов
/ 12 апреля 2020

Есть ли в вашем приложении ORM для связи с БД? Я предполагаю, что вот мой ответ: у каждого приложения есть собственный механизм кэширования через ORM (например, Hibernate). Если один из них изменяет данные, изменения будут отражены в его кеше, но другой ничего не знает об изменениях в БД. Вы можете сделать один из следующих вариантов:

  1. Отключить кэш ORM в приложении (быстрое решение)
  2. Обернуть БД другим приложением, действующим как слой модели + сервер кеша
  3. Создание системы обмена сообщениями для трансляции события изменения между экземплярами и обновления кэша в случае триггера (хотя это не очень хорошая идея)
0 голосов
/ 10 апреля 2020

Существуют различные типы причин возникновения этой проблемы.

1) Проверьте наличие прав доступа к базе данных. Также проверьте, может ли ваше приложение зафиксировать данные в базе данных. Вам необходимо отладить другой сценарий ios

  1. Вставить данные из cluster_1 и попытаться прочитать их из cluster_2
  2. Повторить шаг 1 в другом порядке
  3. Регистрация SQL В базе данных есть какие-либо различия при вставке данных (информация о владельце, версия объекта).

2) Вы можете создать кластер сервера Tomcat в ( Инструкции по кластеризации / репликации сеансов). )

...