11-12 lipca w Sankt Petersburgu odbędzie się konferencja , poświęcona rozwojowi systemów równoległych i rozproszonych. Zaletą Hydry jest to, że łączy znakomitych naukowców (których zazwyczaj można spotkać tylko na zagranicznych konferencjach naukowych) i znanych praktyków inżynierii w jeden obszerny program na przecięciu nauki i praktyki.
Hydra to jedna z najważniejszych naszych konferencji w ostatnich latach. Towarzyszyły jej poważne przygotowania, dobór prelegentów i tematów wystąpień. W zeszłym tygodniu ukazało się z dyrektorem firmy JUG.ru Group, Aleksejem Fedorowem ().
My ) o trzech kluczowych uczestnikach, twórcach teorii systemów rozproszonych — Leslie Lamport, Maurice Herlihy i Michael Scott. Nadszedł czas, aby dokładniej omówić cały program!

Motywacja
Jeśli zajmujesz się programowaniem, w jakimś stopniu masz do czynienia z wielowątkowością i obliczeniami rozproszonymi. Specjaliści w odpowiednich dziedzinach pracują z nimi bezpośrednio, jednak rozproszenie jest wszędzie wokół nas: w każdym wielordzeniowym komputerze lub rozproszonym serwisie znajdzie się coś, co równolegle wykonuje obliczenia.
Istnieje wiele konferencji, które przedstawiają różne aspekty programowania aplikacyjnego. Z drugiej strony mamy specjalne szkoły naukowe, które w formie wykładów odkrywają ogromne ilości złożonej teorii. Na przykład równolegle z Hydrą w Petersburgu odbywa się . Na konferencji Hydra staraliśmy się zgromadzić zarówno surową praktykę, jak i naukę oraz wszystko, co znajduje się na ich przecięciu.
Pomyślcie o tym: żyjemy w niezwykłych czasach, kiedy można na żywo spotkać założycieli dziedziny nauki i inżynierii, którą się zajmujemy. Fizyk nie spotka ani Newtona, ani Einsteina — pociąg odjechał. Ale obok nas nadal żyją ci, którzy stworzyli podstawy teorii systemów rozproszonych, wymyślili popularne języki programowania, po raz pierwszy zrealizowali to wszystko w działających prototypach. Ci ludzie nie porzucili swojej pracy w połowie drogi, obecnie zajmują się aktualnymi problemami w znanych na całym świecie uniwersytetach i firmach, i są największymi źródłami wiedzy i doświadczenia współcześnie.
Z drugiej strony, możliwość spotkania się z nimi często pozostaje czysto teoretyczna: niewielu z nas może na bieżąco monitorować publiczne wydarzenia na uniwersytecie w Rochester, aby potem polecieć do USA, a następnie wrócić na wykład do Michaela Scotta. Uczestniczenie we wszystkich wydarzeniach Hydra kosztowałoby małą fortunę, nie wspominając o niezliczonym czasie poświęconym na to (choć brzmi to jak interesujący quest).
Z drugiej strony, mamy wielu topowych inżynierów, którzy obecnie pracują nad aktualnymi problemami systemów rozproszonych, i na pewno mają wiele do opowiedzenia. Ale problem polega na tym, że ich czas jest cenny. korzystaTak, jeśli jesteś pracownikiem Microsoftu, Google’a lub JetBrains, szanse na spotkanie jednego z znanych prelegentów na wewnętrznym wydarzeniu drastycznie rosną, ale ogólnie — to nie zdarza się codziennie.
W ten sposób konferencja Hydra pełni ważną rolę, której większość z nas nie może zrealizować samodzielnie — w jednym miejscu i w tym samym czasie gromadzi ludzi, których pomysły lub rozmowy mogą zmienić twoje życie. Przyznaję, że nie wszyscy potrzebują systemów rozproszonych czy skomplikowanych fundamentalnych rzeczy. Można przez całe życie programować CRUD-y w PHP i być całkiem szczęśliwym. Ale kto ich potrzebuje — to twoja szansa.
Od pierwszej zapowiedzi konferencji Hydra na Habra minęło już sporo czasu. W tym okresie wykonano ogromną pracę — i oto, mamy listę prawie wszystkich wykładów. Żadnych wątłych jednowątkowych algorytmów, tylko czysty rozproszony hardcore! Zakończmy ogólne słowa i zobaczmy, co teraz mamy w rękach.
Wykłady główne
Wykłady główne otwierają i zamykają dni konferencji. Zwykle sens otwierającego wykładu głównego polega na nadaniu ogólnego ducha i kierunku konferencji. Zamykający wykład główny podsumowuje wydarzenia i wyjaśnia, jak żyć z wiedzą i umiejętnościami zdobytymi w trakcie konferencji. Początek i koniec: to, co zostaje w pamięci najlepiej, a także ma podwyższone znaczenie.
Cliff Click —
Cliff to legenda świata Java. Pod koniec lat 90-tych dla pracy doktorskiej napisał pracę zatytułowaną , która po pewnym czasie stała się podstawą dla HotSpot JVM Server Compiler. Dwa lata później pracował już w Sun Microsystems nad JVM, pokazując światu, że JIT ma rację bytu. Cała ta historia o tym, że Java jest jednym z najszybszych nowoczesnych runtime’ów z najinteligentniejszymi i najszybszymi optymalizacjami wywodzi się właśnie od Cliffa Clicka. Na samym początku uważano, że jeśli coś jest dostępne dla kompilatora statycznego — to nie ma sensu próbować kompilacji JIT. Dzięki pracom Cliffa i jego zespołu, wszystkie nowe języki zaczęły być tworzone z założeniem domyślnej kompilacji JIT. Niewątpliwie, była to praca nie dla jednej osoby, ale Cliff odegrał w niej bardzo ważną rolę.
W otwierającym keynote, Cliff opowie o swoim innym przedsięwzięciu — , platformie in-memory do rozproszonego i skalowalnego uczenia maszynowego w zastosowaniach przemysłowych. A dokładniej — o rozproszonym magazynie par „klucz-wartość” wewnątrz niej. To bardzo szybki magazyn z mnóstwem interesujących właściwości (dokładna lista znajduje się w ), które umożliwiają stosowanie podobnych rozwiązań w matematyce przetwarzania strumieni dużych danych.
Kolejny wykład, w którym wystąpi Cliff — . Inna część jego biografii to dziesięć lat , gdzie zaktualizował i poprawił wiele aspektów sprzętu i stosu technologii Azul: kompilatory JIT, runtime, model wątków, obsługę błędów, pracę ze stosem, przerwania sprzętowe, ładowanie klas i tak dalej — no, rozumiecie.
Najciekawsza część zaczęła się, gdy stworzyli sprzęt dla dużych biznesów — superkomputer do uruchamiania Javy. To było dość innowacyjne rozwiązanie, dostosowane specjalnie do Javy, która ma szczególne wymagania — bariery pamięci do odczytu dla zminimalizowania pauz w zbieraniu śmieci, tablice z kontrolą granic, wirtualne wywołania… Jedną z najlepszych technologii była sprzętowa pamięć transakcyjna. Całe L1 każdego z 864 rdzeni mogło brać udział w transakcyjnych zapisach, co jest szczególnie istotne przy pracy z blokadami w Javie (bloki synchronized mogą działać równolegle, dopóki nie wystąpi rzeczywisty konflikt pamięci). Jednak piękna idea zderzyła się z surową rzeczywistością — i w tym wykładzie Cliff opowie, dlaczego HTM i STM niezbyt nadają się do praktycznych potrzeb obliczeń wielowątkowych.
Michael Scott —
— profesor informatyki na Uniwersytecie w Rochester, z którym los go związał , a na macierzystym Uniwersytecie Wisconsin–Madison był dziekanem przez pięć lat. Zajmuje się badaniami w dziedzinie programowania równoległego i rozproszonego oraz projektowania języków, a także naucza swoich studentów.
Cały świat zna Michaela dzięki podręcznikowi , którego ostatnie wydanie ukazało się stosunkowo niedawno — w 2015 roku. Jego praca otrzymał jako jedna z najbardziej rozpoznawalnych w dziedzinie obliczeń rozproszonych i w internetowej bibliotece Uniwersytetu w Rochester. Można go również znać jako autora słynnego algorytmu Michael-Scotta z .
Jeśli chodzi o świat Javy, to tutaj sytuacja jest szczególna: wraz z Doug Lea opracował te nieblokujące algorytmy i synchronizowane kolejki, na których opierają się biblioteki Javy. O tym właśnie będzie keynote „Struktury danych o podwójnej funkcji” — wprowadzenie tych struktur w Java SE 6 pozwoliło na dziesięciokrotne zwiększenie wydajności java.util.concurrent.ThreadPoolExecutor. Jeśli już teraz jesteście ciekawi, czym są te „struktury danych o podwójnej funkcji”, to istnieje .
Maurice Herlihy —
— laureat dwóch nagród Dijkstra. Pierwsza — za pracę nad (Uniwersytet Brown), a druga, bardziej współczesna — (Uniwersytet Virginia Tech). Nagrodę Dijkstra przyznaje się za prace, których znaczenie i wpływ były zauważalne przez co najmniej dziesięć lat, i oczywiście Maurice jest jednym z najbardziej znanych specjalistów w tej dziedzinie. Obecnie jest profesorem na Uniwersytecie Brown i ma na koncie wiele osiągnięć, które mogłyby zająć cały akapit.
Na tym kończącym keynote Maurice omówi teorię i praktykę blockchainowych systemów rozproszonych z perspektywy klasyki obliczeń rozproszonych oraz jak to upraszcza wiele powiązanych problemów. To wystąpienie będzie ściśle związane z tematyką konferencji — zupełnie nie o szumie górniczym, a raczej o tym, jak nasze zasoby wiedzy można zdumiewająco efektywnie i stosownie wykorzystywać do różnych zadań.
W lipcu 2017 roku Maurice już przyjechał do Rosji na szkołę SPTDC, uczestniczył w meet-upie JUG.ru, a nagranie można zobaczyć na YouTube:

Główna agenda
Poniżej znajduje się krótki przegląd prezentacji, które weszły w skład programu. Część prezentacji została opisana szczegółowo, część — krócej. Długie opisy otrzymały głównie referaty w języku angielskim, które wymagają odniesień do prac naukowych, terminów na Wikipedii itd. Pełną listę można . Lista na stronie będzie aktualizowana i uzupełniana.
Leslie Lamport —
Leslie Lamport jest autorem fundamentalnych prac w zakresie obliczeń rozproszonych. rozszyfrowuje się jako „Lamport TeX”. To on po raz pierwszy, jeszcze w 1979 roku, wprowadził pojęcie , a jego artykuł otrzymał nagrodę Dijkstra.
To najbardziej nietypowa część programu, ponieważ to nawet nie jest wykład, a sesja pytań i odpowiedzi. Kiedy znaczna część widowni jest już zaznajomiona (lub może się zapoznać) z wszelkimi pracami opartymi na „teorii Lamporta”, jego własnymi artykułami i prezentacjami, najważniejsze jest, aby wykorzystać cały dostępny czas na bezpośrednią komunikację.
Pomysł jest prosty — oglądacie na YouTube dwa wykłady: i i przygotowujecie przynajmniej jedno pytanie, a Leslie odpowiada.
Pierwsze z tych dwóch wideo już . Jeśli nie macie godziny na obejrzenie filmu, można szybko przeczytać to w formie tekstu.
Na marginesie: na YouTube jest znacznie więcej wideo z Leslie Lamportem. Na przykład, jest świetny . Off-line wersja całego tego kursu dostępna jest na , a na YouTube zostało to udostępnione dla łatwiejszego oglądania na urządzeniach mobilnych.
Martin Kleppmann —
Martin Kleppmann jest badaczem na Uniwersytecie w Cambridge, pracującym nad CRDT i formalną weryfikacją algorytmów. Książka Martina , opublikowana w 2017 roku, okazała się bardzo udana i trafiła do bestsellerów w dziedzinie przechowywania i przetwarzania danych. Kevin Scott, CTO w Microsoft, : „Ta książka powinna być obowiązkowa dla inżynierów-programistów. To rzadki zasób, który łączy teorię z praktyką, pomagając programistom projektować i wdrażać infrastrukturę oraz systemy przetwarzania danych w bardziej inteligentny sposób“. Coś podobnego mówił także twórca Kafki i CTO Confluent, Jay Kreps.
Zanim zajął się badaniami akademickimi, Martin pracował w branży i był współzałożycielem dwóch udanych startupów:
- Rapportive, poświęconego wyświetlaniu profilu społecznego kontaktów z Twojej poczty elektronicznej, który LinkedIn kupił w 2012 roku;
- Go Test It, usługi automatycznego sprawdzania stron internetowych w różnych przeglądarkach, którą RedGate kupił w 2009 roku.
Ogólnie, Martin, choć mniej znany niż nasi prelegenci główni, już przyczynił się do rozwoju obliczeń rozproszonych oraz branży.
W tym wystąpieniu Martin będzie mówił na temat, który jest bliższy jego badaniom akademickim. W Google Docs i podobnym oprogramowaniu do wspólnej edycji dokumentów, „wspólna edycja“ oznacza zadanie replikacji: każdy użytkownik ma swoją własną replikę wspólnego dokumentu, którą następnie modyfikuje, a wszystkie zmiany są przesyłane po sieci do pozostałych uczestników. Zmiany dokumentów offline prowadzą do tymczasowej niespójności dokumentu względem pozostałych uczestników, a ponowna synchronizacja wymaga rozwiązywania konfliktów. Właśnie do tego służą (CRDT), w zasadzie dość nowa rzecz, której istota została sformułowana dopiero w 2011 roku. W tym wykładzie omawiane jest, co się wydarzyło od tego czasu w świecie CRDT, jakie są najnowsze osiągnięcia, omawiany jest sposób tworzenia aplikacji z podejściem local-first oraz wykorzystanie otwartoźródłowej biblioteki w szczególności.
W przyszłym tygodniu opublikujemy na Habra duży wywiad z Martinem, będzie ciekawie.
Pedro Ramalhete —
Pedro pracuje w Cisco i od około dziesięciu lat rozwija równoległe algorytmy, w tym mechanizmy synchronizacji, struktury danych bezblokujących i bezczekających oraz wszystko, co można sobie wyobrazić w tym temacie. Jego obecne zainteresowania naukowe i inżynieryjne koncentrują się na Uniwersalnych Konstrukcjach, Pamięci Transakcyjnej Oprogramowania, Pamięci Utrwalonej i podobnych technologiach, które umożliwiają tworzenie poprawnych, skalowalnych i odpornych na awarie aplikacji. Jest także autorem szeroko znanego w wąskich kręgach bloga .
Większość aplikacji wielowątkowych opiera się obecnie na równoległych strukturach danych, zaczynając od użycia kolejek komunikatów między aktorami, a kończąc na zindeksowanych strukturach danych w przechowalniach key-value. W Java JDK działają one z powodzeniem od wielu lat, a w C++ powoli również są dodawane.
Najprostszym sposobem na zaimplementowanie równoległej struktury danych jest sekwencyjna (jednowątkowa) realizacja, w której metody są chronione mutexami. Jest to dostępne dla każdego juniora, ale wiąże się z oczywistymi problemami ze skalowalnością i wydajnością. Jednocześnie struktury danych bezblokujące i bezczekające nie tylko lepiej radzą sobie z błędami, ale także mają bardziej korzystny profil wydajności — jednak ich opracowanie wymaga głębokiej wiedzy eksperckiej i dostosowania do konkretnego sposobu zastosowania. Jedna zła linia kodu wystarczy, aby wszystko się zepsuło.
Jak sprawić, by nawet nieekspert mógł projektować i wdrażać takie struktury danych? Wiadomo, że każdy sekwencyjny algorytm można uczynić bezpiecznym dla wątków za pomocą albo , albo pamięci transakcyjnej. Oba mogą obniżyć próg wejścia w rozwiązanie tego problemu. Jednak obie te metody zazwyczaj prowadzą do nieefektywnej realizacji. Pedro opowie o tym, jak udało im się uczynić te konstrukcje bardziej efektywnymi i jak można je wykorzystać w swoich algorytmach.
Heidi Howard —
Heidi Howard, podobnie jak Martin, jest badaczką systemów rozproszonych na Uniwersytecie Cambridge. Jej specjalizacja to spójność, odporność na awarie, wydajność i rozproszony konsensus. Jest najbardziej znana z uogólnienia algorytmu Paxos, znanego jako .
Przypomnijmy, że — rodzina protokołów służących do osiągania konsensusu w sieci niepewnych obliczeń, której fundamenty opierają się na pracach Lesliego Lamporta. Tak więc, niektórzy z naszych prelegentów pracują nad problemami, które pierwotnie zostały zaproponowane przez innych naszych prelegentów — i to jest wspaniałe.
Możliwość znalezienia konsensusu między kilkoma hostami — w kontekście adresacji, wyboru lidera, blokowania lub koordynacji — jest fundamentalnym pytaniem współczesnych systemów rozproszonych. Paxos jest obecnie głównym sposobem rozwiązywania problemów związanych z osiąganiem konsensusu, a wokół niego prowadzone są liczne badania mające na celu rozszerzenie i optymalizację algorytmu do różnych praktycznych potrzeb.
W tym referacie przeglądniemy teoretyczne podstawy Paxos, osłabiając pierwotne wymagania i uogólniając algorytm. Zobaczymy, że Paxos w rzeczywistości jest tylko jednym z wielu podejść do osiągania konsensusu, a inne punkty w tym spektrum również mogą być bardzo użyteczne w budowaniu dobrych systemów rozproszonych.
Alex Petrov —
Alex jest specjalistą ds. baz danych i systemów przechowywania, a co najważniejsze dla nas — komitentem w . Obecnie współpracuje z O’Reilly nad książką Database Internals.
Dla systemów z (w terminologii rosyjskiej — „zbieżnością w końcu”), po awarii węzła lub podziale sieci, trzeba rozwiązać następującą dylemat: czy kontynuować realizację zapytań, poświęcając spójność, czy odmówić ich wykonania, poświęcając dostępność. W takim systemie większościowe głosowania, pokrywające się podzbiory węzłów, które gwarantują, że co najmniej jeden węzeł będzie posiadał najnowszą wartość, mogą stać się dobrym granicznym rozwiązaniem. Można przetrwać awarie i utratę połączenia z niektórymi węzłami, jednocześnie odpowiadając najświeższymi wartościami.
Jednak wszystko ma swoją cenę. Schemat replikacji quorum oznacza wyższe koszty przechowywania: trzeba przechowywać nadmiarowe dane na kilku węzłach jednocześnie, aby zapewnić wystarczającą liczbę dostępnych kopii w momencie wystąpienia problemu. Okazuje się, że nie trzeba przechowywać wszystkich danych na wszystkich replikach. Można zmniejszyć obciążenie pamięci masowej, przechowując dane tylko na części węzłów, a do scenariuszy obsługi awarii używać specjalnych węzłów (Transient Replica).
W trakcie prezentacji przyjrzymy się , schematowi replikacji używanemu w i , oraz implementacji tej koncepcji w Apache Cassandra pod nazwami .
Dmitrij Wujkow —
Dmitrij jest deweloperem w Google, pracującym nad dynamicznym testowaniem C/C++ i Go — Address/Memory/ThreadSanitizer, oraz nad podobnymi narzędziami dla jądra Linux. Współtworzył w Go skalowalny harmonogram gorutin, poller sieciowy oraz równoległy zbieracz śmieci. Jest ekspertem w dziedzinie wielowątkowości, autorem tuzina nowych algorytmów nieblokujących i właścicielem Intel.
Teraz trochę o samej prezentacji. W języku Go istnieje natywne wsparcie dla wielowątkowości w postaci gorutin (lekkich wątków) i kanałów (kolejek FIFO). Dzięki tym mechanizmom użytkownicy mogą łatwo i przyjemnie pisać nowoczesne aplikacje wielowątkowe, a to wygląda jak magia. Jak rozumiemy, żadnej magii tutaj nie ma. W tej prezentacji Dmitrij zagłębi się w szczegóły działania harmonogramu Go i pokaże sekrety realizacji tej „magii”. Na początku przedstawi przegląd podstawowych komponentów harmonogramu, wyjaśni, jak to działa. Następnie bliżej poznamy poszczególne aspekty, takie jak strategia parkowania/odparkowania i obsługa blokujących wywołań systemowych. Na koniec Dmitrij opowie trochę o możliwych ulepszeniach w harmonogramie.
Dmitrij Bugajczenko —
Dmitrij pracował w outsourcingu przez prawie 9 lat, nie tracąc kontaktu z uniwersytetem i środowiskiem naukowym. Analiza dużych danych w Odnoklassnikach stała się dla niego unikalną okazją do połączenia przygotowania teoretycznego i fundamentu naukowego z tworzeniem rzeczywistych, poszukiwanych produktów.
Zdalna analiza grafów była i nadal jest skomplikowanym zadaniem: gdy zachodzi potrzeba uzyskania informacji o powiązaniach sąsiedniego wierzchołka, dane często trzeba przekazywać między maszynami, co prowadzi do zwiększenia czasu wykonania i obciążenia infrastruktury sieciowej. W tym referacie zobaczymy, jak można uzyskać znaczące przyspieszenie przetwarzania, wykorzystując prawdopodobnościowe struktury danych lub fakty takie jak symetryczność grafu przyjaźni w sieci społecznościowej. Wszystko to ilustrowane jest przykładami kodu na Apache Spark.
Denis Ryscov —
Denis — programista , ekspert w dziedzinie weryfikacji modeli spójności, algorytmów konsensusu oraz w transakcjach rozproszonych. Obecnie pracuje w Microsoft, a wcześniej zajmował się systemami rozproszonymi w Amazon i Yandex.
W tym referacie zapoznamy się z protokołami transakcji rozproszonych, które powstały w ciągu ostatnich kilku lat, które można zrealizować po stronie klienta na dowolnym magazynie danych, który wspiera warunkowe aktualizacje (compare and set). Sedno sprawy tkwi w tym, że życie nie kończy się na dwuetapowym zatwierdzeniu, transakcje można dodawać ponad dowolne bazy danych — na poziomie aplikacji, ale różne protokoły (2PC, Percolator, RAMP) mają różne kompromisy i nie są całkowicie darmowe.
Aleksiej Zinowjew —
Aleksiej () — nasz długoletni prelegent i członek komitetów programowych na innych konferencjach. Praktykujący trener w firmie EPAM Systems, z Hadoop/Spark i innymi technologiami big data zaprzyjaźniony od 2012 roku.
W tym referacie Aleksiej opowie o problemach adaptacji klasycznych algorytmów uczenia maszynowego do realizacji w rozproszonym trybie opierając się na swoim doświadczeniu z Apache Spark ML, Apache Mahout, Apache Flink ML oraz doświadczeniu w tworzeniu Apache Ignite ML. Aleksiej opowie także o realizacji rozproszonych algorytmów ML w tych frameworkach.
Na koniec — dwa referaty od firmy Yandex dotyczące Yandex Database.
Władysław Kuźniecow —
Władysław to programista w Yandexie, pracujący w grupie platform rozproszonych. Yandex Database to poziomo skalowalna, geograficznie rozproszona, odporna na awarie baza danych, która wytrzymuje awarię dysków, serwerów, szaf i centrów danych bez naruszania spójności. Aby zapewnić odporność na awarie, stosuje się własny algorytm osiągania rozproszonego konsensusu oraz szereg rozwiązań technicznych, które są szczegółowo omówione w referacie. Referat może być interesujący zarówno dla programistów baz danych, jak i dla twórców aplikacji opartych na bazach danych.
Semen Checherynda —
Semen to programista w grupie platform rozproszonych w Yandexie, pracujący nad możliwością wieloęgnościowego korzystania z instalacji YDB.
Yandex Database jest przystosowana do zapytań OLTP i spełnia wymagania ACID dla systemów transakcyjnych. W referacie omówimy algorytm planowania transakcji, który leży u podstaw systemu transakcyjnego YDB. Przeanalizujemy, jakie byty biorą udział w transakcjach, kto ustala globalny porządek transakcji, jak osiąga się atomowość transakcji, niezawodność oraz wysoki poziom izolacji. Na przykładzie powszechnego zadania omówimy realizacje transakcji z zastosowaniem dwuetapowego zatwierdzania oraz deterministycznych transakcji. Przedyskutujemy ich różnice.
Co dalej?
Program konferencji jest w trakcie uzupełniania o nowe referaty. W szczególności oczekujemy referatu od Nikita Kowala () z JetBrains oraz Olega Anastasjeva () z firmy Odnoklassniki. Nikita zajmuje się algorytmami dla korutyn w zespole Kotlin, a Oleg rozwija architekturę i rozwiązania dla systemów o dużym obciążeniu w platformie Odnoklassniki. Ponadto jest jeszcze 1 warunkowo pusty slot, nad którym obecnie pracuje komitet programowy.
Konferencja Hydra odbędzie się 11-12 lipca w Sankt Petersburgu. Bilety można . Zwracamy uwagę na dostępność biletów Online — jeśli z jakiegoś powodu nie możesz dotrzeć osobiście do Petersburga w te dni.
Do zobaczenia na Hydrze!
Źródło: habr.com
