Статьи

Умные синглтоны на сетке


При работе в распределенной среде часто необходимо иметь согласованное локальное состояние для каждого узла сетки, которое повторно используется при выполнении различных заданий. Например, что, если нескольким заданиям для выполнения требуется пул соединений с базой данных — как они получают этот пул соединений, который будет инициализирован один раз, а затем повторно использован всеми заданиями, работающими на одном узле сетки? По сути, вы можете думать об этом как о одноэлементном сервисе для каждого узла сетки, но идея не ограничивается только сервисами, это может быть просто обычный Java-бин, содержащий некоторое состояние, которое будет совместно использоваться всеми заданиями, выполняющимися на одном узле сетки. ,

В
версиях
GridGain 2.x и более ранних версиях этот подход обрабатывался с помощью
аннотации
@GridUserResource для аннотирования полей в
GridTask или
Классы GridJob для указания одноэлементных бинов . Однако этот подход зависит от
GridDeploymentMode конфигурации , и для
ИЗОЛИРОВАННОЕ или
ЧАСТНОЕ режимов развертывания, ресурс может быть инициализирован несколько раз, один раз в
GridTask . Это заставляло пользователей использовать различные хаки в их логике и, как правило, было не очень удобно использовать.

Начиная с GridGain 3.0,
было представлено локальное хранилище
GridNodeLocal для каждого узла сетки. Имя было заимствовано из
класса
ThreadLocal в Java, потому что точно так же, как
ThreadLocal обеспечивает уникальное пространство для каждого потока в Java,
GridNodeLocalпредоставляет уникальное пространство для каждой сетки в GridGain.
GridNodeLocal реализует
интерфейс
java.util.concurrent.ConcurrentMap и абсолютно не блокируется. Фактически, он просто расширяет
реализацию
java.util.concurrent.ConcurrentHashMap и, следовательно, наследует все доступные там методы.

Вот пример того, как GridNodeLocal можно использовать для создания какого- то
отдельного пользовательского однотонного сервиса из простого задания GridGain:

final Grid grid = G.start(..);

// Execute runnable job on some remote grid node.
grid.run(BALANCE, new Runnable() {
  public void run() {
    GridNodeLocal<String, MySingleton> nodeLocal = grid.nodeLocal();

    // 1. Check if f someone already created our singleton service. 
    MySingleton service = nodeLocal.get("myservice");

    if (service == null) {
      // 2. Create new singleton service.
      MySingleton other = 
        nodeLocal.putIfAbsent("myservice", service = new MySingleton(..));

      if (other != null) 
        service = other;
    }

    // Perform operations with our singleton service.
    ...
  }
});

 

С http://gridgain.blogspot.com/2011/08/clever-singletons-on-grid.html