16

Obecnie tworzę aplikację do przechowywania tabel Azure. W tej aplikacji mam tabelę, która będzie miała stosunkowo niewiele insertów (kilka tysięcy dziennie), a klucz podstawowy tych jednostek będzie użyty w innej tabeli, która będzie miała miliardy wierszy.Auto-increment on Azure Table Storage

Dlatego szukam sposobu użycia automatycznie zwiększanej liczby całkowitej, zamiast GUID, jako klucza podstawowego w małej tabeli (ponieważ pozwoli to zaoszczędzić wiele pamięci i skalowalność wstawek nie jest tak naprawdę problemem).

Było kilka dyskusji na ten temat, np. na http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797.

Jednak, ponieważ problemy ze współbieżnością mogą być naprawdę trudne do debugowania i zauważenia, jestem trochę niekomfortowy z samodzielnym wdrażaniem tego. Moje pytanie brzmi zatem, czy istnieje dobrze sprawdzona impelemntation tego?

+0

Jeśli naprawdę się o to martwisz, to czy masz tabelę w SQL Azure, która generuje wartości tożsamości? – Andrew

+0

To całkiem dobra sugestia. Jednak zmusiłoby to mnie do skonfigurowania mojego serwera SQL, ponieważ usługi danych SQL Azure nie obsługują kolumn tożsamości: http://www.shanmcarthur.net/cloud-services/design-strategies- for-Azure-and-SDS . – Yrlec

Odpowiedz

4

nie wdrożyły tego jeszcze, ale pracuję nad tym ...

Można nasion kolejkę ze swoimi kolejnych identyfikatorów użyć, a następnie po prostu wybrać je z kolejki, gdy są potrzebne.

Musisz zachować tabelę zawierającą wartość największej liczby dodanej do kolejki. Jeśli wiesz, że nie będziesz używał ton liczby całkowitej, możesz mieć pracownika co jakiś czas obudzić się i upewnić się, że kolejka nadal zawiera w sobie liczby całkowite. Można również użyć kolejki int, którą pracownik może sprawdzić, aby mieć oko na użycie.

Można również zawiesić ten robotnik, więc jeśli kolejka była pusta, gdy twój kod potrzebował identyfikatora (przez przypadek), mógł przerwać drzemkę pracownika, aby utworzyć więcej kluczy jak najszybciej.

Jeśli wezwanie powiodło musisz drogę do (powiedz pracownikowi idziesz do pracy dla nich (Lock), a następnie wykonaj pracę robotników coraz następnego id i odblokować)

  1. zablokować
  2. uzyskać ostatniego klucza stworzonego z tabeli
  3. inkrementacji i zapisać
  4. unlock

następnie użyć nowej wartości.

+1

Ale w jaki sposób kolejka gwarantuje, że zduplikowane identyfikatory nie zostaną utworzone? Z tego, co mogę zrozumieć z http://download.microsoft.com/download/5/2/D/52D36345-BB08-4518-A024-0AA24D47BD12/Windows%20Azure%20Queue%20-%20Dec%202008.docx, wynika, że komunikat jest dodawany do kolejki ponownie, jeśli proces roboczy zakończy się niepowodzeniem podczas przetwarzania komunikatu kolejki. W związku z tym należy wykonać zadanie w roli robota idempotent. Jeśli ta sama wiadomość (to jest ten sam identyfikator) jest używana przez dwie różne role robocze, nie widzę sposobu, w jaki można to zrobić idempotent. – Yrlec

+2

Jeśli masz tylko 1 woker, który tworzy id, wtedy dupki zostaną umieszczone w kolejce. Podczas wyciągania identyfikatorów z kolejki, pobierz wiadomość, a następnie usuń wiadomość przed użyciem zawartości wiadomości (identyfikatora). To powinno zapewnić, że żadne identyfikatory nie będą używane więcej niż jeden raz. Wygląda na to, że w najgorszym przypadku możesz stracić klucz, ale twoja wyjątkowość powinna być dobra. –

+0

Drugie zdanie powyżej powinno brzmieć: "Jeśli masz tylko 1 woker, który tworzy identyfikator, dupki nie zostaną umieszczone w kolejce ..." –

3

Jeśli naprawdę chcesz uniknąć przewodników, czy rozważałeś użycie czegoś opartego na dacie/czasie, a następnie wykorzystując klucze partycji, aby zminimalizować ryzyko współbieżności.

Twój klucz partycji może pochodzić od użytkownika, roku, miesiąca, dnia, godziny itp., A kluczem wiersza może być reszta datetime w wystarczająco krótkim czasie, aby kontrolować współbieżność.

Oczywiście trzeba zadać sobie pytanie, za cenę daty na Azure, jeśli unikanie Guida jest naprawdę warte tego dodatkowego wysiłku (zakładając, że Guid po prostu zadziała).

4

Rozwiązanie znalazłem że zapobiega zduplikowane identyfikatory i pozwala autoIncrement to jest

  1. lock (lease) a blob i pozwól, które działają jako logiczną bramą.

  2. Następnie przeczytaj wartość.

  3. Napisz zwiększoną wartość

  4. Zwolnij dzierżawę

  5. użyć wartości w app/tabeli

Następnie, jeśli rola pracownika były do ​​awarii w trakcie tego procesu, a następnie W twoim sklepie byłby tylko brakujący identyfikator. IMHO, które jest lepsze niż duplikaty.

Oto code sample and more information na tym podejściu od Steve Marx

10

dla każdego, kto znajdzie się w poszukiwania, nie jest lepszym rozwiązaniem. Minimal time for table lock is 15 seconds - to okropne. Nie używaj go, jeśli chcesz stworzyć prawdziwie skalowalne rozwiązanie. Użyj Etag!

Utwórz jeden element w tabeli dla identyfikatora (możesz nawet nazwać go ID lub cokolwiek innego).

1) Przeczytaj.

2) Przyrost.

3) InsertOrUpdate Z podanymETag (z zapytania odczytu).

Jeśli ostatnia operacja (InsertOrUpdate) powiedzie się, to masz nowy, unikalny, automatycznie zwiększany identyfikator. Jeśli się nie powiedzie (wyjątek: HttpStatusCode == 412), oznacza to, że zmienił go inny klient. Powtórz ponownie 1,2 i 3. Zazwyczaj czas dla Read+InsertOrUpdate jest mniejszy niż 200 ms. Moje narzędzie testowe with source on github.

+0

Doskonały pomysł. – PilotBob

+0

co z używaniem EGT do zagwarantowania operacji atomowych, czytania i inkrementacji? Czy to opłacalny sposób na zrobienie tego? https://docs.microsoft.com/en-gb/azure/storage/storage-table-design-guide#entity-group-transactions –

Powiązane problemy