Rozproszona Kontrola Współbieżności

Pracuję nad tym od kilku dni i znalazłem kilka rozwiązań, ale żaden z nich nie jest niewiarygodnie prosty ani lekki. Problem jest w zasadzie taki: mamy klaster 10 maszyn, z których każda działa z tym samym oprogramowaniem na wielowątkowej platformie ESB. Mogę dość łatwo rozwiązywać problemy współbieżności między wątkami na tej samej maszynie, ale co z współbieżnością na tych samych danych na różnych maszynach?

Zasadniczo oprogramowanie otrzymuje prośby o feed dane Klienta z jednej firmy do drugiej za pośrednictwem usług internetowych. Jednak klient może lub nie musi jeszcze istnieć w innym systemie. Jeśli nie, tworzymy go za pomocą metody web service. Więc to wymaga pewnego rodzaju testu, ale potrzebuję jakiegoś semafora, aby zablokować inne maszyny przed spowodowaniem warunków wyścigowych. Miałem wcześniej sytuacje, w których zdalny klient został stworzony dwa razy dla jednego klienta lokalnego, co nie jest naprawdę pożądane.

Rozwiązania, z którymi się bawiłem koncepcyjnie są:

  1. Korzystanie z naszego odpornego na błędy współdzielonego systemu plików do tworzenia plików "blokujących", które będą sprawdzane przez każdą maszynę w zależności od klienta

  2. Używając specjalnej tabeli w naszej bazie danych i blokując całą tabelę, aby wykonać "test-and-set" dla rekordu blokady.

  3. Korzystanie z Terracotta, oprogramowania serwera open source, które pomaga w skalowaniu, ale wykorzystuje model hub-and-spoke.

  4. Używanie EHCache do synchronicznego replikacja moich zamków w pamięci."

Nie wyobrażam sobie, że jestem jedyną osobą, która kiedykolwiek miała taki problem. Jak to rozwiązałeś? Ugotowałeś coś w domu lub masz ulubiony produkt innych firm?

Author: Anony-Mousse, 2008-09-18

13 answers

Warto rozważyć użycie Hazelcast rozproszonych zamków. Super lite i łatwe.

java.util.concurrent.locks.Lock lock = Hazelcast.getLock ("mymonitor");
lock.lock ();
try {
// do your stuff
}finally {
   lock.unlock();
}

Hazelcast-Distributed Queue, Map, Set, List, Lock

 34
Author: ROMANIA_engineer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-23 12:11:49

Używamy terakoty, więc chciałbym za tym zagłosować.

Śledziłem Hazelcast i wygląda to na kolejną obiecującą technologię, ale nie mogę na nią głosować, ponieważ nie korzystałem z niej, a wiedząc, że używa systemu opartego na P2P, naprawdę nie ufałbym mu w przypadku dużych potrzeb skalowania.

Ale słyszałem też o Zookeeper, który wyszedł z Yahoo i porusza się pod parasolem Hadoop. Jeśli szukasz przygód, wypróbuj nową technologię, która naprawdę ma wiele obietnica, ponieważ jest bardzo chuda i wredna, koncentrując się na koordynacji. Podoba mi się ta wizja i obietnica, choć może być jeszcze zbyt Zielona.

 13
Author: fern,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 03:17:08

Terracotta jest bliższa modelowi "warstwowemu" - wszystkie aplikacje klienckie rozmawiają z tablicą serwerów Terracotta(a co ważniejsze ze względu na skalę nie rozmawiają ze sobą). Tablica serwerów Terracotta może być grupowana zarówno pod kątem skali ,jak i dostępności (lustrzana, dla dostępności i paski, dla skali).

W każdym przypadku, jak zapewne wiesz, Terracotta daje możliwość wyrażania współbieżności w całym klastrze w taki sam sposób, jak w pojedynczym JVM za pomocą POJO synchronized / wait/notify or by using any of the java.util.współbieżne prymitywy, takie jak ReentrantReadWriteLock, CyclicBarrier, AtomicLong, FutureTask i tak dalej.

Istnieje wiele prostych przepisów demonstrujących użycie tych prymitywów w Terakotowej książce kucharskiej .

Jako przykład podam przykład ReentrantReadWriteLock (zauważ, że nie ma wersji "Terakotowej" blokady - wystarczy użyć zwykłego Java ReentrantReadWriteLock)

import java.util.concurrent.locks.*;

public class Main
{
    public static final Main instance = new Main();
    private int counter = 0;
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(true);

    public void read()
    {
        while (true) {
            rwl.readLock().lock();
                try {
                System.out.println("Counter is " + counter);
            } finally {
                rwl.readLock().unlock();
            }
            try { Thread.currentThread().sleep(1000); } catch (InterruptedException ie) {  }
        }
    }

    public void write()
    {
        while (true) {
            rwl.writeLock().lock();
            try {
               counter++;
               System.out.println("Incrementing counter.  Counter is " + counter);
            } finally {
                 rwl.writeLock().unlock();
            }
            try { Thread.currentThread().sleep(3000); } catch (InterruptedException ie) {  }
        }
    }

    public static void main(String[] args)
    {
        if (args.length > 0)  {
            // args --> Writer
            instance.write();
        } else {
            // no args --> Reader
            instance.read();
        }
    }
}
 4
Author: Taylor Gautier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 21:03:51

Zalecam użycie Redisson . Implementuje ponad 30 rozproszonych struktur danych i usług, w tym java.util.Lock. Przykład użycia:

Config config = new Config();
config.addAddress("some.server.com:8291");
Redisson redisson = Redisson.create(config);

Lock lock = redisson.getLock("anyLock");
lock.lock();
try {
    ...
} finally {
   lock.unlock();
}

redisson.shutdown();
 3
Author: Nikita Koksharov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-19 18:56:00

Miałem zamiar doradzić, jak używać memcached jako bardzo szybkiej, rozproszonej pamięci RAM do przechowywania dzienników; ale wygląda na to, że EHCache jest podobnym projektem, ale bardziej zorientowanym na Javę.

Jedno i drugie jest do zrobienia, o ile na pewno używasz atomic updates(memcached je obsługuje, Nie wiem o EHCache). To zdecydowanie najbardziej skalowalne rozwiązanie.

Jako pokrewny datapoint, Google używa "Chubby", szybkiej, opartej na PAMIĘCI RAM pamięci rozproszonej jako źródła wielu systemów, wśród nich BigTable.

 2
Author: Javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-17 03:36:17

Wykonałem wiele pracy z Koherencją, co pozwoliło na kilka podejść do implementacji rozproszonej blokady. Naiwne podejście polegało na żądaniu zablokowania tego samego obiektu logicznego we wszystkich uczestniczących węzłach. W sensie spójności było to blokowanie klucza na replikowanym buforze. To podejście nie skaluje się tak dobrze, ponieważ ruch sieciowy zwiększa się liniowo wraz z dodaniem węzłów. Inteligentniejszym sposobem było użycie rozproszonej pamięci podręcznej, gdzie każdy węzeł w klastrze jest naturalnie odpowiedzialny za część przestrzeń klucza, więc blokowanie klucza w takiej pamięci podręcznej zawsze wiązało się z komunikacją z co najwyżej jednym węzłem. W oparciu o tę ideę można stworzyć własne podejście, albo jeszcze lepiej uzyskać spójność. To naprawdę jest zestaw narzędzi skalowalności Twoich marzeń.

Dodam, że każdy w połowie przyzwoity mechanizm blokowania oparty na wielu węzłach sieci musiałby być odpowiednio wyrafinowany, aby działać poprawnie w przypadku jakiejkolwiek awarii sieci.

 1
Author: Craig Day,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 13:42:39

Nie wiem, czy Rozumiem cały kontekst, ale wygląda na to, że masz jedną bazę danych popierającą to? Dlaczego nie skorzystać z blokowania bazy danych: jeśli tworzenie klienta jest pojedynczym INSERTEM, to samo polecenie może służyć jako blokada, ponieważ baza danych odrzuci drugi INSERT, który naruszyłby jedno z Twoich ograniczeń (np. fakt, że nazwa klienta jest unikalna).

Jeśli operacja "wstawianie klienta" nie jest atomowa i jest zbiorem instrukcji, to Chciałbym wprowadzić (lub użyć) początkową wstawkę, która tworzy jakiś prosty podstawowy rekord identyfikujący klienta (z niezbędnymi ograniczeniami unikalności), a następnie zrobić wszystkie inne wstawki / aktualizacje w tej samej transakcji. Ponownie baza danych zadba o spójność i wszelkie współbieżne modyfikacje spowodują, że jedna z nich ulegnie awarii.

 1
Author: Boris Terzic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 13:50:31

Wykonałem prostą usługę RMI za pomocą dwóch metod: lock i release. obie metody przyjmują klucz (mój model danych używał uuid jako pk, więc był to również klucz blokujący).

RMI jest dobrym rozwiązaniem, ponieważ jest scentralizowany. nie możesz tego zrobić z EJBs(szczególnie w klastrze, ponieważ nie wiesz, na której maszynie wyląduje Twoje połączenie). plus, to proste.

U mnie zadziałało.

 0
Author: entzik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 13:33:44

Jeśli możesz skonfigurować równoważenie obciążenia tak, aby żądania dla jednego klienta zawsze były mapowane na ten sam serwer, możesz obsłużyć to poprzez lokalną synchronizację. Na przykład, weź identyfikator klienta mod 10, aby znaleźć, które z węzłów 10 użyć.

Nawet jeśli nie chcesz tego robić w ogólnym przypadku, twoje węzły mogą zastępować się nawzajem dla tego konkretnego typu żądania.

Zakładając, że Twoi użytkownicy są na tyle jednorodni (tj. jeśli masz ich mnóstwo) , że nie oczekujesz gorące miejsca, które pojawią się, gdy jeden węzeł zostanie przeciążony, to nadal powinno być dobrze skalowane.

 0
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-16 07:27:11

Możesz również rozważyć Cacheonix dla rozproszonych zamków. Cacheonix obsługuje blokady ReadWrite z eskalacją blokady od odczytu do zapisu w razie potrzeby:

ReadWriteLock rwLock = Cacheonix.getInstance().getCluster().getReadWriteLock();
Lock lock = rwLock.getWriteLock();
try {
  ...
} finally {
  lock.unlock();
}

Pełne ujawnienie: jestem programistą Cacheonix.

 0
Author: Slava Imeshev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-26 16:54:37

Ponieważ już łączysz się z bazą danych, przed dodaniem kolejnego elementu na podczerwień, spójrz na JdbcSemaphore , jest prosty w użyciu:

JdbcSemaphore semaphore = new JdbcSemaphore(ds, semName, maxReservations);
boolean acq = semaphore.acquire(acquire, 1, TimeUnit.MINUTES);
if (acq) {
 // do stuff
 semaphore.release();
} else {
  throw new TimeoutException();
}

Jest częścią biblioteki spf4j .

 0
Author: user2179737,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-23 01:01:11

Kiedyś używaliśmy do tego konkretnego "serwera blokującego" w sieci. Bleh.

Twój serwer bazy danych może mieć zasoby specjalnie do tego rodzaju rzeczy. MS-SQL Server posiada blokadę aplikacji używaną przez sp_getapplock/procedury sp_releaseapplock.

 -1
Author: Clinton Pierce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 13:28:14

Rozwijaliśmy open source, rozproszony Framework synchronizacji, obecnie DistributedReentrantLock i DistributedReentrantReadWrite blokada została zaimplementowana, ale nadal są w fazie testowania i refaktoryzacji. W naszej architekturze klucze blokujące są dzielone w wiadra i każdy węzeł jest rezonowalny dla określonej liczby wiadra. Tak więc dla pomyślnego żądania blokady istnieje tylko jedno żądanie sieciowe. Używamy również klasy AbstractQueuedSynchronizer jako local lock state, tak więc wszystkie nieudane żądania blokady są obsługiwane lokalnie, co drastycznie zmniejsza trafic sieci. Używamy JGroups (http://jgroups.org ) do komunikacji grupowej i Heski do serializacji.

Aby uzyskać więcej informacji, sprawdź http://code.google.com/p/vitrit/.

Prześlij mi swoją cenną opinię.

Kamran

 -5
Author: Kamran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-08 08:45:35