{"id":84114,"date":"2020-06-05T07:42:55","date_gmt":"2020-06-05T05:42:55","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/one-cloud-os-urovnya-data-czentra-v-odnoklassnikah"},"modified":"2020-06-05T07:42:55","modified_gmt":"2020-06-05T05:42:55","slug":"one-cloud-os-urovnya-data-czentra-v-odnoklassnikah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/one-cloud-os-urovnya-data-czentra-v-odnoklassnikah","title":{"rendered":"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/fa983acacec59ff2d4ed098f87223971.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Aloha, ludzie! Nazywam si\u0119 Oleg Anastasiew, pracuj\u0119 w Odnoklassnikach w zespole Platformy. Opr\u00f3cz mnie, w Odnoklassnikach pracuje wiele urz\u0105dze\u0144. Mamy cztery centra danych, w kt\u00f3rych znajduje si\u0119 oko\u0142o 500 stojak\u00f3w z ponad 8000 serwer\u00f3w. W pewnym momencie zrozumieli\u015bmy, \u017ce wdro\u017cenie nowego systemu zarz\u0105dzania pozwoli nam efektywniej wykorzysta\u0107 sprz\u0119t, u\u0142atwi\u0107 zarz\u0105dzanie dost\u0119pami, zautomatyzowa\u0107 (prze)dystrybucj\u0119 zasob\u00f3w obliczeniowych, przyspieszy\u0107 uruchamianie nowych us\u0142ug oraz reakcje na masowe awarie. <\/p>\n<p><\/p>\n<p>Co z tego wysz\u0142o? <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Opr\u00f3cz mnie i mn\u00f3stwa sprz\u0119tu s\u0105 te\u017c ludzie, kt\u00f3rzy pracuj\u0105 z tym sprz\u0119tem: in\u017cynierowie znajduj\u0105cy si\u0119 bezpo\u015brednio w centrach danych; sieciowcy, kt\u00f3rzy konfiguruja infrastruktur\u0119 sieciow\u0105; administratorzy, czyli SRE, kt\u00f3rzy zapewniaj\u0105 niezawodno\u015b\u0107 infrastruktury; oraz zespo\u0142y deweloper\u00f3w, z kt\u00f3rych ka\u017cdy odpowiada za cz\u0119\u015b\u0107 funkcji portalu. Oprogramowanie, kt\u00f3re tworz\u0105, dzia\u0142a mniej wi\u0119cej tak:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/592fd0acfa7322eb80fbb85601a92918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zapytania u\u017cytkownik\u00f3w trafiaj\u0105 zar\u00f3wno na frontend g\u0142\u00f3wnego portalu <noindex><a rel=\"nofollow\" href=\"http:\/\/www.ok.ru\/\">www.ok.ru<\/a><\/noindex>, jak i na inne, na przyk\u0142ad na fronty API muzyki. Aby przetworzy\u0107 logik\u0119 biznesow\u0105, wywo\u0142uj\u0105 serwer aplikacji, kt\u00f3ry przy przetwarzaniu zapytania uruchamia niezb\u0119dne specjalizowane mikroserwisy \u2014 one-graph (graf spo\u0142ecznych powi\u0105za\u0144), user-cache (cache profili u\u017cytkownik\u00f3w) itd.<\/p>\n<p><\/p>\n<p>Ka\u017cdy z tych serwis\u00f3w jest uruchamiany na wielu maszynach, a ka\u017cdy z nich ma odpowiedzialnych deweloper\u00f3w, kt\u00f3rzy odpowiadaj\u0105 za dzia\u0142anie modu\u0142\u00f3w, ich eksploatacj\u0119 i rozw\u00f3j techniczny. Wszystkie te serwisy dzia\u0142aj\u0105 na serwerach fizycznych, a do niedawna uruchamiali\u015bmy dok\u0142adnie jedno zadanie na jeden serwer, co oznacza, \u017ce by\u0142 on wyspecjalizowany na konkretn\u0105 funkcj\u0119.<\/p>\n<p><\/p>\n<p>Dlaczego tak? Taki spos\u00f3b mia\u0142 kilka zalet:<\/p>\n<p><\/p>\n<ul>\n<li>U\u0142atwia <strong>masowe zarz\u0105dzanie<\/strong>. Powiedzmy, \u017ce zadanie wymaga pewnych bibliotek, pewnych ustawie\u0144. Wtedy serwer przypisany jest do dok\u0142adnie jednej okre\u015blonej grupy, opisana jest polityka cfengine dla tej grupy (lub ju\u017c jest opisana), a ta konfiguracja centralnie i automatycznie rozk\u0142ada si\u0119 na wszystkie serwery tej grupy.<\/li>\n<li>U\u0142atwia <strong>diagnozowanie<\/strong>Za\u0142\u00f3\u017cmy, \u017ce obserwujesz zwi\u0119kszone obci\u0105\u017cenie procesora i zdajesz sobie spraw\u0119, \u017ce to obci\u0105\u017cenie mog\u0142a wygenerowa\u0107 tylko ta zadanie, kt\u00f3re dzia\u0142a na tym fizycznym procesorze. Poszukiwania winnego ko\u0144cz\u0105 si\u0119 bardzo szybko.<\/li>\n<li>U\u0142atwia <strong>monitoring<\/strong>Je\u015bli co\u015b jest nie tak z serwerem, monitor o tym informuje i dok\u0142adnie wiesz, kto jest winny.<\/li>\n<\/ul>\n<p><\/p>\n<p>Us\u0142uga sk\u0142adaj\u0105ca si\u0119 z kilku replik ma przypisane kilka serwer\u00f3w - po jednym na ka\u017cd\u0105. W\u00f3wczas zasoby obliczeniowe dla us\u0142ugi s\u0105 przydzielane bardzo prosto: ile serwis ma serwer\u00f3w, tyle mo\u017ce maksymalnie wykorzysta\u0107 zasob\u00f3w. \u201eProsto\u201d w tym przypadku nie oznacza, \u017ce to \u0142atwe do u\u017cycia, lecz \u017ce przydzia\u0142 zasob\u00f3w odbywa si\u0119 r\u0119cznie.<\/p>\n<p><\/p>\n<p>Takie podej\u015bcie pozwala\u0142o nam r\u00f3wnie\u017c tworzy\u0107 <strong>specjalistyczne konfiguracje sprz\u0119towe<\/strong> pod aplikacje dzia\u0142aj\u0105ce na tym serwerze. Je\u015bli aplikacja przechowuje du\u017ce ilo\u015bci danych, korzystamy z serwera 4U z obudow\u0105 na 38 dysk\u00f3w. Je\u015bli zadanie jest wy\u0142\u0105cznie obliczeniowe, mo\u017cemy kupi\u0107 ta\u0144szy serwer 1U. To jest wydajne pod wzgl\u0119dem zasob\u00f3w obliczeniowych. Takie podej\u015bcie pozwala nam tak\u017ce na cztery razy mniejsze wykorzystanie maszyn przy obci\u0105\u017ceniu por\u00f3wnywalnym z jedn\u0105 przyjazn\u0105 nam sieci\u0105 spo\u0142eczno\u015bciow\u0105. <\/p>\n<p><\/p>\n<p>Taka efektywno\u015b\u0107 wykorzystania zasob\u00f3w obliczeniowych powinna zapewni\u0107 r\u00f3wnie\u017c efektywno\u015b\u0107 ekonomiczn\u0105, je\u015bli przyj\u0105\u0107, \u017ce najdro\u017csze s\u0105 serwery. Przez d\u0142ugi czas najdro\u017csze by\u0142o w\u0142a\u015bnie sprz\u0119t, a my w\u0142o\u017cyli\u015bmy du\u017co wysi\u0142ku w obni\u017cenie koszt\u00f3w sprz\u0119tu, tworz\u0105c algorytmy zapewniaj\u0105ce odporno\u015b\u0107 na awarie w celu zmniejszenia wymaga\u0144 dotycz\u0105cych niezawodno\u015bci sprz\u0119tu. Dzi\u015b dotarli\u015bmy do etapu, w kt\u00f3rym cena serwera przesta\u0142a by\u0107 decyduj\u0105ca. Je\u015bli nie bra\u0107 pod uwag\u0119 najnowszych egzotyk, konkretna konfiguracja serwer\u00f3w w szafie nie ma znaczenia. Teraz mamy inny problem \u2014 cena zajmowanego miejsca przez serwer w centrum danych, t.j. miejsca w szafie.<\/p>\n<p><\/p>\n<p>Zdaj\u0105c sobie z tego spraw\u0119, postanowili\u015bmy obliczy\u0107, jak efektywnie wykorzystujemy szafy.<br \/>\nWzi\u0119li\u015bmy cen\u0119 najsilniejszego serwera w ekonomicznie uzasadniony spos\u00f3b, policzyli\u015bmy, ile takich serwer\u00f3w mo\u017cemy zmie\u015bci\u0107 w szafach, ile zada\u0144 uruchomiliby\u015bmy na nich, opieraj\u0105c si\u0119 na starej zasadzie \u201ejeden serwer = jedno zadanie\u201d i w jakim stopniu te zadania mog\u0142yby wykorzysta\u0107 sprz\u0119t. Policzyli\u015bmy \u2014 wzruszyli\u015bmy si\u0119. Okaza\u0142o si\u0119, \u017ce efektywno\u015b\u0107 wykorzystania szaf wynosi oko\u0142o 11%. Wniosek jest oczywisty: trzeba zwi\u0119kszy\u0107 efektywno\u015b\u0107 korzystania z centr\u00f3w danych. Wydawa\u0142oby si\u0119, \u017ce rozwi\u0105zanie jest oczywiste: na jednym serwerze nale\u017cy uruchamia\u0107 jednocze\u015bnie kilka zada\u0144. Ale tu zaczynaj\u0105 si\u0119 trudno\u015bci. <\/p>\n<p><\/p>\n<p>Masowa konfiguracja staje si\u0119 znacznie bardziej skomplikowana \u2014 teraz niemo\u017cliwe jest przypisanie jednego serwera do jakiej\u015b jednej grupy. W ko\u0144cu na tym samym serwerze mog\u0105 by\u0107 uruchomione jednocze\u015bnie r\u00f3\u017cne zadania r\u00f3\u017cnych zespo\u0142\u00f3w. Ponadto, konfiguracja mo\u017ce kolidowa\u0107 z r\u00f3\u017cnymi aplikacjami. Diagnoza r\u00f3wnie\u017c staje si\u0119 trudniejsza: je\u015bli widzisz zwi\u0119kszone zu\u017cycie procesor\u00f3w lub dysk\u00f3w na serwerze, nie wiesz, kt\u00f3re z zada\u0144 sprawia problemy.<\/p>\n<p><\/p>\n<p>Ale najwa\u017cniejsze jest to, \u017ce mi\u0119dzy zadaniami uruchomionymi na jednej maszynie nie ma izolacji. Oto, na przyk\u0142ad, wykres \u015bredniego czasu odpowiedzi zadania serwera przed i po tym, jak na tym samym serwerze uruchomiono jeszcze jedno, ca\u0142kowicie niezwi\u0105zane z pierwszym, aplikacj\u0119 obliczeniow\u0105 \u2014 czas odpowiedzi dla g\u0142\u00f3wnego zadania znacz\u0105co wzr\u00f3s\u0142.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/c7c07359ae572ca8c84a4c63559e4083.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Oczywiste jest, \u017ce trzeba uruchamia\u0107 zadania albo w kontenerach, albo w maszynach wirtualnych. Poniewa\u017c praktycznie wszystkie zadania uruchamiamy pod jedn\u0105 OS (Linux) lub s\u0105 do niej dostosowane, nie musimy wspiera\u0107 wielu r\u00f3\u017cnych system\u00f3w operacyjnych. W zwi\u0105zku z tym wirtualizacja nie jest potrzebna, a ze wzgl\u0119du na dodatkowe koszty b\u0119dzie mniej efektywna ni\u017c konteneryzacja.<\/p>\n<p><\/p>\n<p>Docker jest dobrym kandydatem do uruchamiania kontener\u00f3w na serwerach: obrazy system\u00f3w plik\u00f3w skutecznie rozwi\u0105zuj\u0105 problemy z konfliktuj\u0105cymi konfiguracjami. Mo\u017cliwo\u015b\u0107 tworzenia obraz\u00f3w z kilku warstw pozwala nam znacznie zmniejszy\u0107 obj\u0119to\u015b\u0107 danych potrzebnych do ich wdro\u017cenia w infrastrukturze, wydzielaj\u0105c wsp\u00f3lne cz\u0119\u015bci do osobnych warstw podstawowych. W\u00f3wczas podstawowe (i najbardziej obszerne) warstwy szybko zostan\u0105 zbuforowane w ca\u0142ej infrastrukturze, a do dostarczenia wielu r\u00f3\u017cnych typ\u00f3w aplikacji i wersji wystarczy przes\u0142a\u0107 jedynie niewielkie warstwy. <\/p>\n<p><\/p>\n<p>Dodatkowo, gotowy rejestr i tagowanie obraz\u00f3w w Dockerze oferuj\u0105 nam gotowe mechanizmy do wersjonowania i dostarczania kodu do produkcji.<\/p>\n<p><\/p>\n<p>Docker, podobnie jak ka\u017cda inna technologia tego typu, zapewnia nam pewien poziom izolacji kontener\u00f3w od razu. Na przyk\u0142ad, izolacja pami\u0119ci - ka\u017cdy kontener ma przydzielony limit wykorzystania pami\u0119ci maszyny, kt\u00f3rego nie mo\u017ce przekroczy\u0107. Mo\u017cna r\u00f3wnie\u017c izolowa\u0107 kontenery w zakresie u\u017cycia CPU. Dla nas standardowa izolacja okaza\u0142a si\u0119 niewystarczaj\u0105ca. Ale o tym poni\u017cej.<\/p>\n<p><\/p>\n<p>Bezpo\u015brednie uruchamianie kontener\u00f3w na serwerach to tylko cz\u0119\u015b\u0107 problemu. Drug\u0105 cz\u0119\u015bci\u0105 jest umieszczanie kontener\u00f3w na serwerach. Nale\u017cy zrozumie\u0107, kt\u00f3ry kontener mo\u017cna umie\u015bci\u0107 na kt\u00f3rym serwerze. To nie jest tak prosta sprawa, poniewa\u017c kontenery nale\u017cy rozmieszcza\u0107 na serwerach jak naj\u015bci\u015blej, nie obni\u017caj\u0105c jednocze\u015bnie ich wydajno\u015bci. Takie rozmieszczenie mo\u017ce by\u0107 trudne tak\u017ce z punktu widzenia odporno\u015bci na awarie. Cz\u0119sto chcemy umieszcza\u0107 repliki tego samego serwisu w r\u00f3\u017cnych szafach lub nawet w r\u00f3\u017cnych salach data center, aby w przypadku awarii szafy lub sali nie straci\u0107 jednocze\u015bnie wszystkich replik serwisu. <\/p>\n<p><\/p>\n<p>R\u0119czne rozmieszczanie kontener\u00f3w nie jest opcj\u0105, kiedy masz 8 tysi\u0119cy serwer\u00f3w i 8-16 tysi\u0119cy kontener\u00f3w. <\/p>\n<p><\/p>\n<p>Ponadto, chcieli\u015bmy da\u0107 programistom wi\u0119ksz\u0105 niezale\u017cno\u015b\u0107 w przydzielaniu zasob\u00f3w, aby mogli samodzielnie umieszcza\u0107 swoje serwisy w produkcji, bez pomocy administratora. Jednocze\u015bnie chcieli\u015bmy zachowa\u0107 kontrol\u0119, aby jaki\u015b drugorz\u0119dny serwis nie zu\u017cy\u0142 wszystkich zasob\u00f3w naszych data center. <\/p>\n<p><\/p>\n<p>Oczywiste jest, \u017ce potrzebna jest warstwa zarz\u0105dzaj\u0105ca, kt\u00f3ra zajmowa\u0142aby si\u0119 tym automatycznie.<\/p>\n<p><\/p>\n<p>Oto prosta i zrozumia\u0142a wizualizacja, kt\u00f3r\u0105 uwielbiaj\u0105 wszyscy architekci: trzy kwadraty. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/079df6e79874ef55b0d967fde3d5feca.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>one-cloud masters \u2014 odporna na b\u0142\u0119dy klaster, odpowiedzialny za orkiestracj\u0119 chmury. Programista przesy\u0142a do mastera manifest, kt\u00f3ry zawiera wszystkie niezb\u0119dne informacje do umieszczenia us\u0142ugi. Master na tej podstawie wydaje polecenia wybranym minionom (maszynom przeznaczonym do uruchamiania kontener\u00f3w). Na minionach znajduje si\u0119 nasz agent, kt\u00f3ry otrzymuje polecenie, wydaje ju\u017c swoje polecenia Docker, a Docker konfiguruje j\u0105dro systemu Linux do uruchomienia odpowiedniego kontenera. Opr\u00f3cz wykonania polece\u0144 agent nieprzerwanie informuje mastera o zmianach stanu zar\u00f3wno maszyny-miniona, jak i uruchomionych na niej kontener\u00f3w.<\/p>\n<p><\/p>\n<h2 id=\"raspredelenie-resursov\">Rozdzielanie zasob\u00f3w<\/h2>\n<p><\/p>\n<p>A teraz zajmijmy si\u0119 trudniejszym problemem dzielenia zasob\u00f3w dla wielu minion\u00f3w.<\/p>\n<p><\/p>\n<p>Zas\u00f3b obliczeniowy w one-cloud to:<\/p>\n<p><\/p>\n<ul>\n<li>Moc obliczeniowa procesora wykorzystywana przez konkretne zadanie. <\/li>\n<li>Ilo\u015b\u0107 pami\u0119ci dost\u0119pnej dla zadania. <\/li>\n<li>Ruch sieciowy. Ka\u017cdy z minion\u00f3w ma konkretny interfejs sieciowy z ograniczon\u0105 przepustowo\u015bci\u0105, wi\u0119c nie mo\u017cna przydziela\u0107 zada\u0144 bez uwzgl\u0119dnienia ilo\u015bci danych przesy\u0142anych przez sie\u0107. <\/li>\n<li>Dyski. Opr\u00f3cz, oczywi\u015bcie, miejsca na dane zadania, przydzielamy tak\u017ce typ dysku: HDD lub SSD. Dyski mog\u0105 obs\u0142u\u017cy\u0107 okre\u015blon\u0105 liczb\u0119 zapyta\u0144 na sekund\u0119 \u2014 IOPS. Dlatego dla zada\u0144 generuj\u0105cych wi\u0119cej IOPS, ni\u017c mo\u017ce obs\u0142u\u017cy\u0107 jeden dysk, przydzielamy r\u00f3wnie\u017c 'spindle' \u2014 czyli urz\u0105dzenia dyskowe, kt\u00f3re nale\u017cy zarezerwowa\u0107 wy\u0142\u0105cznie dla zadania.<\/li>\n<\/ul>\n<p><\/p>\n<p>Zatem dla jakiej\u015b us\u0142ugi, na przyk\u0142ad user-cache, mo\u017cemy zapisa\u0107 zu\u017cywane zasoby w ten spos\u00f3b: 400 rdzeni procesora, 2,5 TB pami\u0119ci, 50 Gbit\/s ruchu w obie strony, 6 TB miejsca na HDD, umieszczonego na 100 spindle'ach. Lub w bardziej znanej nam formie tak:<\/p>\n<p><\/p>\n<pre><code>alloc:\n    cpu: 400\n    mem: 2500\n    lan_in: 50g\n    lan_out: 50g\n    hdd:100x6T<\/code><\/pre>\n<p><\/p>\n<p>Zasoby us\u0142ugi user-cache zu\u017cywaj\u0105 tylko cz\u0119\u015b\u0107 wszystkich dost\u0119pnych zasob\u00f3w w infrastrukturze produkcyjnej. Dlatego chcemy, aby nagle, z powodu b\u0142\u0119du operatora lub nie, user-cache nie zu\u017cy\u0142 wi\u0119cej zasob\u00f3w, ni\u017c mu przydzielono. To znaczy, \u017ce musimy ograniczy\u0107 zasoby. Ale do czego mogliby\u015bmy przypisa\u0107 kwot\u0119?<\/p>\n<p><\/p>\n<p>Wr\u00f3\u0107my do naszego mocno uproszczonego schematu interakcji komponent\u00f3w i narysujmy go z wi\u0119ksz\u0105 ilo\u015bci\u0105 szczeg\u00f3\u0142\u00f3w \u2014 oto tak: <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/27e5bfbffadd3d4b9fdc6bf138d135ed.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Co rzuca si\u0119 w oczy:<\/p>\n<p><\/p>\n<ul>\n<li>Frontend webowy i muzyka korzystaj\u0105 z izolowanych klastr\u00f3w tego samego serwera aplikacji.<\/li>\n<li>Mo\u017cna wyr\u00f3\u017cni\u0107 logiczne warstwy, do kt\u00f3rych nale\u017c\u0105 te klastry: frontend, cache, warstwa przechowywania i zarz\u0105dzania danymi.<\/li>\n<li>Frontend jest heterogeniczny, to r\u00f3\u017cne funkcjonalne podsystemy. <\/li>\n<li>Cache r\u00f3wnie\u017c mo\u017cna rozmie\u015bci\u0107 w podsystemach, kt\u00f3rych dane przechowuj\u0105.<\/li>\n<\/ul>\n<p><\/p>\n<p>Jeszcze raz narysujmy obrazek:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/905dacc0aca859e65bd33ef751a557cf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O, widzimy hierarchi\u0119! A wi\u0119c mo\u017cna przydziela\u0107 zasoby wi\u0119kszym kawa\u0142kom: przypisa\u0107 odpowiedzialnego programist\u0119 do w\u0119z\u0142a tej hierarchii, odpowiadaj\u0105cego funkcjonalnemu podsystemowi (jak \"music\" na rysunku), a do tego samego poziomu hierarchii przypi\u0105\u0107 kwot\u0119. Taka hierarchia r\u00f3wnie\u017c pozwala nam elastyczniej organizowa\u0107 us\u0142ugi dla wygody zarz\u0105dzania. Na przyk\u0142ad, wszystkie web, poniewa\u017c to bardzo du\u017ca grupa serwer\u00f3w, dzielimy na kilka mniejszych grup, pokazanych na obrazku jako group1, group2.<\/p>\n<p><\/p>\n<p>Usuwaj\u0105c zb\u0119dne linie, mo\u017cemy zapisa\u0107 ka\u017cdy w\u0119ze\u0142 naszego rysunku w bardziej p\u0142askiej formie: <strong>group1.web.front<\/strong>, <strong>api.music.front<\/strong>, <strong>user-cache.cache<\/strong>.<\/p>\n<p><\/p>\n<p>W ten spos\u00f3b dochodzimy do poj\u0119cia \"hierarchicznej kolejki\". Ma ona swoj\u0105 nazw\u0119, jak \"group1.web.front\". Przypisywana jest jej kwota na zasoby i prawa u\u017cytkownik\u00f3w. Osobie z DevOps nadamy uprawnienia do wysy\u0142ania us\u0142ugi do kolejki, a taki pracownik mo\u017ce uruchamia\u0107 co\u015b w kolejce, a osobie z OpsDev \u2014 prawa administracyjne, i teraz mo\u017ce zarz\u0105dza\u0107 kolejk\u0105, przypisywa\u0107 tam ludzi, przyznawa\u0107 tym ludziom prawa itd. Us\u0142ugi uruchamiane w tej kolejce b\u0119d\u0105 realizowane w ramach kwoty kolejki. Je\u015bli obliczeniowa kwota kolejki jest niewystarczaj\u0105ca do jednoczesnego wykonania wszystkich us\u0142ug, b\u0119d\u0105 one wykonywane kolejno, tworz\u0105c w ten spos\u00f3b rzeczywi\u015bcie kolejk\u0119. <\/p>\n<p><\/p>\n<p>Rozwa\u017cmy us\u0142ugi bardziej szczeg\u00f3\u0142owo. Us\u0142uga ma pe\u0142n\u0105 nazw\u0119, kt\u00f3ra zawsze zawiera nazw\u0119 kolejki. Wtedy us\u0142uga frontu webowego b\u0119dzie mia\u0142a nazw\u0119 <strong>ok-web.group1.web.front<\/strong>. A us\u0142uga serwera aplikacji, do kt\u00f3rego si\u0119 odnosi, b\u0119dzie nosi\u0107 nazw\u0119 <strong>ok-app.group1.web.front<\/strong>. Ka\u017cda us\u0142uga ma manifest, kt\u00f3ry zawiera wszystkie niezb\u0119dne informacje do rozmieszczenia na okre\u015blonych maszynach: ile zasob\u00f3w wymaga to zadanie, jak\u0105 konfiguracj\u0119 potrzebuje, ile replik powinno by\u0107, w\u0142a\u015bciwo\u015bci do obs\u0142ugi awarii tej us\u0142ugi. Po rozmieszczeniu us\u0142ugi na maszynach pojawiaj\u0105 si\u0119 jej instancje. S\u0105 one r\u00f3wnie\u017c jednoznacznie nazwane \u2014 jako numer instancji oraz nazwa us\u0142ugi: <strong>1.ok-web.group1.web.front, 2.ok-web.group1.web.front, \u2026<\/strong><\/p>\n<p><\/p>\n<p>To bardzo wygodne: patrz\u0105c tylko na nazw\u0119 uruchomionego kontenera, mo\u017cemy od razu wiele wywnioskowa\u0107.<\/p>\n<p><\/p>\n<p>A teraz bli\u017cej zapoznajmy si\u0119 z tym, co te instancje w rzeczywisto\u015bci wykonuj\u0105: z zadaniami.<\/p>\n<p><\/p>\n<h2 id=\"klassy-izolyacii-zadach\">Klasy izolacji zada\u0144<\/h2>\n<p><\/p>\n<p>Wszystkie zadania w O\u041a (a zapewne wsz\u0119dzie) mo\u017cna podzieli\u0107 na grupy:<\/p>\n<p><\/p>\n<ul>\n<li><strong>Zadania o kr\u00f3tkim czasie op\u00f3\u017anienia \u2014 prod<\/strong>. Dla takich zada\u0144 i us\u0142ug bardzo wa\u017cne jest op\u00f3\u017anienie odpowiedzi (latency), jak szybko ka\u017cde z zapyta\u0144 zostanie przetworzone przez system. Przyk\u0142ady zada\u0144: fronty webowe, cache'e, serwery aplikacji, OLTP magazyny itp.<\/li>\n<li><strong>Zadania obliczeniowe \u2014 batch<\/strong>. Tutaj szybko\u015b\u0107 przetwarzania ka\u017cdego konkretnego zapytania nie jest istotna. Wa\u017cne jest, ile ca\u0142kowicie oblicze\u0144 w danym (du\u017cym) czasie to zadanie wykona (throughput). B\u0119d\u0105 to wszelkie zadania MapReduce, Hadoop, uczenie maszynowe, statystyka.<\/li>\n<li><strong>Zadania w tle \u2014 idle<\/strong>. Dla takich zada\u0144 ani latency, ani throughput nie s\u0105 zbyt wa\u017cne. Nale\u017c\u0105 do nich r\u00f3\u017cne testy, migracje, przeliczenia, konwersje danych z jednego formatu do drugiego. Z jednej strony s\u0105 podobne do obliczeniowych, z drugiej \u2014 nie ma dla nas a\u017c tak du\u017cego znaczenia, jak szybko si\u0119 zako\u0144cz\u0105. <\/li>\n<\/ul>\n<p><\/p>\n<p>Zobaczmy, jak takie zadania zu\u017cywaj\u0105 zasoby, na przyk\u0142ad procesora.<\/p>\n<p><\/p>\n<p><strong>Zadania o kr\u00f3tkim czasie op\u00f3\u017anienia.<\/strong> Takie zadanie b\u0119dzie mia\u0142o wz\u00f3r zu\u017cycia CPU podobny do tego:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/1ed82c0df76325eb30056ad9af86e86e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na przetwarzanie przychodzi zapytanie od u\u017cytkownika, zadanie zaczyna wykorzystywa\u0107 wszystkie dost\u0119pne rdzenie CPU, przetwarza, zwraca odpowied\u017a, czeka na nast\u0119pne zapytanie i zatrzymuje si\u0119. Pojawia si\u0119 nast\u0119pne zapytanie \u2014 zn\u00f3w wykorzystujemy wszystko, co by\u0142o, obliczamy, czekamy na nast\u0119pne.<\/p>\n<p><\/p>\n<p>Aby zapewni\u0107 minimalne op\u00f3\u017anienie dla takiego zadania, musimy wzi\u0105\u0107 maksymalne zasoby, kt\u00f3re zu\u017cywa i zarezerwowa\u0107 odpowiedni\u0105 liczb\u0119 rdzeni na minionie (maszynie, kt\u00f3ra b\u0119dzie wykonywa\u0107 zadanie). Wtedy wz\u00f3r rezerwacji dla naszego zadania b\u0119dzie wygl\u0105da\u0142 nast\u0119puj\u0105co:<\/p>\n<p><\/p>\n<pre><code>alloc: cpu = 4 (max)<\/code><\/pre>\n<p><\/p>\n<p>I je\u015bli mamy maszyn\u0119-minion z 16 rdzeniami, to mo\u017cemy na niej umie\u015bci\u0107 dok\u0142adnie cztery takie zadania. Zauwa\u017cmy, \u017ce \u015brednie zu\u017cycie procesora w takich zadaniach jest cz\u0119sto bardzo niskie \u2014 co jest oczywiste, poniewa\u017c znaczn\u0105 cz\u0119\u015b\u0107 czasu zadanie sp\u0119dza w oczekiwaniu na zapytanie i nic nie robi.<\/p>\n<p><\/p>\n<p><strong>Zadania obliczeniowe.<\/strong> B\u0119d\u0105 mia\u0142y nieco inny wz\u00f3r:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/35b37fa1d70a137287cafdbfe3bcfc2e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u015arednie zu\u017cycie zasob\u00f3w procesora w takich zadaniach jest do\u015b\u0107 wysokie. Cz\u0119sto chcemy, aby zadanie obliczeniowe by\u0142o wykonane w okre\u015blonym czasie, dlatego musimy zarezerwowa\u0107 minimaln\u0105 liczb\u0119 procesor\u00f3w, kt\u00f3re s\u0105 potrzebne, aby ca\u0142e obliczenie zako\u0144czy\u0142o si\u0119 w akceptowalnym czasie. Jego formu\u0142a rezerwacji b\u0119dzie wygl\u0105da\u0107 tak:<\/p>\n<p><\/p>\n<pre><code>alloc: cpu = [1,*<\/code><\/pre>\n<p><\/p>\n<p><em>\u201eProsz\u0119 umie\u015bci\u0107 na minionie, gdzie jest przynajmniej jeden wolny rdze\u0144, a potem ile si\u0119 da \u2014 wszystko we\u017amie\u201d.<\/em><\/p>\n<p><\/p>\n<p>Tutaj efektywno\u015b\u0107 wykorzystania jest ju\u017c znacznie lepsza ni\u017c w przypadku zada\u0144 o kr\u00f3tkim czasie oczekiwania. Ale zyski b\u0119d\u0105 znacznie wi\u0119ksze, je\u015bli po\u0142\u0105czymy oba typy zada\u0144 na jednej maszynie-minion i na bie\u017c\u0105co b\u0119dziemy rozdziela\u0107 jej zasoby. Kiedy zadanie o kr\u00f3tkim czasie oczekiwania potrzebuje procesora \u2014 otrzymuje go natychmiast, a gdy zasoby staj\u0105 si\u0119 zb\u0119dne \u2014 przechodz\u0105 do zadania obliczeniowego, tzn. mniej wi\u0119cej tak:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/875ad8d3f6a01e4fd0a89d0931e986c1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ale jak to zrobi\u0107?<\/p>\n<p><\/p>\n<p>Na pocz\u0105tku zajmijmy si\u0119 prod i jego alloc: cpu = 4. Musimy zarezerwowa\u0107 cztery rdzenie. W Docker run mo\u017cna to zrobi\u0107 na dwa sposoby: <\/p>\n<p><\/p>\n<ul>\n<li>Za pomoc\u0105 opcji <code>--cpuset=1-4<\/code>, tzn. przypisa\u0107 zadaniu cztery okre\u015blone rdzenie na maszynie.<\/li>\n<li>U\u017cy\u0107 <code>--cpuquota=400_000 --cpuperiod=100_000<\/code>, przypisa\u0107 kwot\u0119 czasu procesora, tzn. wskaza\u0107, \u017ce co 100 ms czasu rzeczywistego zadanie zu\u017cywa nie wi\u0119cej ni\u017c 400 ms czasu procesora. Otrzymujemy te same cztery rdzenie. <\/li>\n<\/ul>\n<p><\/p>\n<p>Ale kt\u00f3ry z tych sposob\u00f3w b\u0119dzie odpowiedni?<\/p>\n<p><\/p>\n<p>Cpuset wygl\u0105da do\u015b\u0107 atrakcyjnie. Zadanie ma cztery dedykowane rdzenie, co oznacza, \u017ce pami\u0119ci podr\u0119czne procesora b\u0119d\u0105 dzia\u0142a\u0142y maksymalnie efektywnie. Ma to r\u00f3wnie\u017c swoj\u0105 odwrotn\u0105 stron\u0119: musieliby\u015bmy zaj\u0105\u0107 si\u0119 rozk\u0142adem oblicze\u0144 na mniej obci\u0105\u017cone rdzenie maszyny zamiast na system operacyjny, co jest do\u015b\u0107 nietrywialnym zadaniem, szczeg\u00f3lnie je\u015bli spr\u00f3bujemy umie\u015bci\u0107 takie zadania wsadowe na takiej maszynie. Testy pokaza\u0142y, \u017ce lepiej sprawdza si\u0119 opcja z kwot\u0105: w ten spos\u00f3b system operacyjny ma wi\u0119cej swobody w wyborze rdzenia do wykonania zadania w danym momencie, a czas procesora jest rozdzielany bardziej efektywnie.<\/p>\n<p><\/p>\n<p>Zajmiemy si\u0119 tym, jak w dockerze zarezerwowa\u0107 minimaln\u0105 liczb\u0119 rdzeni. Kwota dla zada\u0144 wsadowych ju\u017c nie ma zastosowania, poniewa\u017c nie ma potrzeby ogranicza\u0107 maksimum, wystarczy tylko zapewni\u0107 minimum. Tutaj dobrze sprawdza si\u0119 opcja <code>docker run --cpushares<\/code>.<\/p>\n<p><\/p>\n<p>Uzgodnili\u015bmy, \u017ce je\u015bli zadanie wsadowe wymaga gwarancji minimum na jeden rdze\u0144, to wskazujemy <code>--cpushares=1024<\/code>, a je\u015bli minimum na dwa rdzenie, to wskazujemy <code>--cpushares=2048<\/code>. Udzia\u0142y CPU w \u017caden spos\u00f3b nie wp\u0142ywaj\u0105 na podzia\u0142 czasu procesora, dop\u00f3ki go nie brakuje. W ten spos\u00f3b, je\u015bli produkcja w danej chwili nie wykorzystuje wszystkich swoich czterech rdzeni \u2014 nic nie ogranicza zada\u0144 wsadowych, mog\u0105 one korzysta\u0107 z dodatkowego czasu procesora. W sytuacji niedoboru procesora, gdy produkcja wykorzysta\u0142a wszystkie swoje cztery rdzenie i napotka\u0142a kwot\u0119 \u2014 pozosta\u0142y czas procesora b\u0119dzie podzielony proporcjonalnie do cpushares, tzn. w sytuacji trzech wolnych rdzeni jedno otrzyma zadanie z 1024 cpushares, a pozosta\u0142e dwa \u2014 zadanie z 2048 cpushares.<\/p>\n<p><\/p>\n<p>Jednak u\u017cycie kwoty i udzia\u0142\u00f3w nie jest wystarczaj\u0105ce. Musimy zapewni\u0107, \u017ce zadanie z kr\u00f3tkim op\u00f3\u017anieniem ma priorytet przed zadaniem wsadowym w rozdzielaniu czasu procesora. Bez takiej priorytetyzacji zadanie wsadowe zajmie ca\u0142y czas procesora w momencie, gdy b\u0119dzie on potrzebny produkcji. W Docker run nie ma \u017cadnych opcji priorytetyzacji kontener\u00f3w, ale z pomoc\u0105 przychodz\u0105 polityki planowania procesora w Linuksie. Szczeg\u00f3\u0142owo mo\u017cna o tym poczyta\u0107 <noindex><a rel=\"nofollow\" href=\"http:\/\/man7.org\/linux\/man-pages\/man2\/sched_setscheduler.2.html\">tutaj<\/a><\/noindex>, a w ramach tego artyku\u0142u przejrzymy je kr\u00f3tko:<\/p>\n<p><\/p>\n<ul>\n<li><strong>SCHED_OTHER<\/strong><br \/>\nDomy\u015blnie otrzymuj\u0105 wszystkie zwyk\u0142e procesy u\u017cytkownika na maszynie Linuks.<\/li>\n<li><strong>SCHED_BATCH<\/strong><br \/>\nPrzeznaczone do zasobo\u017cernych proces\u00f3w. Przy przypisaniu zadania do procesora wprowadza si\u0119 tzw. kar\u0119 aktywacji: takie zadanie z mniejszym prawdopodobie\u0144stwem otrzyma zasoby procesora, je\u015bli w danym momencie korzysta z niego zadanie z SCHED_OTHER<\/li>\n<li><strong>SCHED_IDLE<\/strong><br \/>\nProces w tle o bardzo niskim priorytecie, nawet ni\u017cszym ni\u017c nice \u201319. U\u017cywamy naszej biblioteki z otwartym kodem <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/odnoklassniki\/one-nio\">one-nio<\/a><\/noindex>, aby ustawi\u0107 odpowiedni\u0105 polityk\u0119 podczas uruchamiania kontenera poprzez wywo\u0142anie<\/li>\n<\/ul>\n<p><\/p>\n<pre><code class=\"java\">one.nio.os.Proc.sched_setscheduler( pid, Proc.SCHED_IDLE )<\/code><\/pre>\n<p><\/p>\n<p>Ale nawet je\u015bli nie programujesz w Javie, to samo mo\u017cna zrobi\u0107 za pomoc\u0105 polecenia chrt:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">chrt -i 0 $pid<\/code><\/pre>\n<p><\/p>\n<p>Zestawmy wszystkie nasze poziomy izolacji w jedn\u0105 tabel\u0119 dla przejrzysto\u015bci:<\/p>\n<p><\/p>\n<p>Klasa izolacji<br \/>\nPrzyk\u0142ad alloc<br \/>\nOpcje Docker run<br \/>\nsched_setscheduler chrt*<\/p>\n<p>Prod<br \/>\ncpu = 4<br \/>\n<code>--cpuquota=400000<\/code> <code>--cpuperiod=100000<\/code><br \/>\nSCHED_OTHER<\/p>\n<p>Batch<br \/>\nCpu = [1, * )<br \/>\n<code>--cpushares=1024<\/code><br \/>\nSCHED_BATCH<\/p>\n<p>Idle<br \/>\nCpu= [2, *)<br \/>\n<code>--cpushares=2048<\/code><br \/>\nSCHED_IDLE<\/p>\n<p><\/p>\n<p>*Je\u017celi wykonujesz chrt wewn\u0105trz kontenera, mo\u017ce by\u0107 potrzebna capability sys_nice, poniewa\u017c domy\u015blnie Docker odbiera t\u0119 capability podczas uruchamiania kontenera.<\/p>\n<p><\/p>\n<p>Ale zadania zu\u017cywaj\u0105 nie tylko procesor, ale r\u00f3wnie\u017c ruch, kt\u00f3ry wp\u0142ywa na op\u00f3\u017anienie zadania sieciowego jeszcze bardziej ni\u017c niew\u0142a\u015bciwe przydzielenie zasob\u00f3w procesora. Dlatego naturalnie chcemy uzyska\u0107 dok\u0142adnie taki sam obraz dla ruchu. To znaczy, gdy zadanie prod wysy\u0142a jakie\u015b pakiety do sieci, kwotujemy maksymaln\u0105 pr\u0119dko\u015b\u0107 (formu\u0142a <em>alloc: lan=[*,500mbps)<\/em> ), z jak\u0105 prod mo\u017ce to robi\u0107. A dla batch zapewniamy tylko minimaln\u0105 przepustowo\u015b\u0107, ale nie ograniczamy maksymalnej (formu\u0142a <em>alloc: lan=[10Mbps,*)<\/em> ) Przy tym ruch prod powinien mie\u0107 priorytet przed zadaniami batch.<br \/>\nTutaj Docker nie ma \u017cadnych prymityw\u00f3w, kt\u00f3re mogliby\u015bmy wykorzysta\u0107. Ale z pomoc\u0105 przychodzi nam <noindex><a rel=\"nofollow\" href=\"http:\/\/lartc.org\/\">Linux Traffic Control<\/a><\/noindex>. Uda\u0142o nam si\u0119 osi\u0105gn\u0105\u0107 po\u017c\u0105dany rezultat za pomoc\u0105 dyscypliny <noindex><a rel=\"nofollow\" href=\"http:\/\/linux-ip.net\/articles\/hfsc.en\/\">Hierarchical Fair Service Curve<\/a><\/noindex>. Dzi\u0119ki niej wyodr\u0119bniamy dwie klasy ruchu: wysokopriorytetowy prod i niskopriorytetowy batch\/idle. W rezultacie konfiguracja dla ruchu wychodz\u0105cego jest nast\u0119puj\u0105ca:<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/gh\/5k\/kf\/gh5kkfwkhwv0ilmbdmdbo83dp6k.png\"><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/3f52a968118b6021bd0c920af17a00c0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p><\/p>\n<p>tut 1:0 \u2014 \u00abkorzeniowy qdisc\u00bb dyscypliny hsfc; 1:1 \u2014 podrz\u0119dna klasa hsfc z wsp\u00f3lnym limitem przepustowo\u015bci wynosz\u0105cym 8 Gbit\/s, pod kt\u00f3r\u0105 mieszcz\u0105 si\u0119 podklasy wszystkich kontener\u00f3w; 1:2 \u2014 podrz\u0119dna klasa hsfc wsp\u00f3lna dla wszystkich zada\u0144 batch i idle z \u00abdynamicznym\u00bb limitem, o kt\u00f3rym mowa poni\u017cej. Pozosta\u0142e podrz\u0119dne klasy hsfc to klasy przypisane dla aktualnie dzia\u0142aj\u0105cych kontener\u00f3w prod z limitami odpowiadaj\u0105cymi ich manifestom \u2014 450 i 400 Mbit\/s. Ka\u017cdej klasie hsfc przypisana jest kolejka qdisc fq lub fq_codel, w zale\u017cno\u015bci od wersji j\u0105dra linux, w celu unikni\u0119cia strat pakiet\u00f3w podczas wzrostu ruchu. <\/p>\n<p><\/p>\n<p>Zwykle dyscypliny tc s\u0142u\u017c\u0105 do priorytetyzacji tylko ruchu wychodz\u0105cego. Ale chcemy r\u00f3wnie\u017c priorytetyzowa\u0107 ruch przychodz\u0105cy \u2014 przecie\u017c jaka\u015b zadanie batch mo\u017ce swobodnie zaj\u0105\u0107 ca\u0142y przychodz\u0105cy kana\u0142, otrzymuj\u0105c na przyk\u0142ad du\u017c\u0105 paczk\u0119 danych wej\u015bciowych do map&amp;reduce. W tym celu u\u017cywamy modu\u0142u <noindex><a rel=\"nofollow\" href=\"https:\/\/serverfault.com\/questions\/350023\/tc-ingress-policing-and-ifb-mirroring\">ifb<\/a><\/noindex>, kt\u00f3ry tworzy wirtualny interfejs ifbX dla ka\u017cdego interfejsu sieciowego i przekierowuje ruch przychodz\u0105cy z interfejsu do wychodz\u0105cego na ifbX. Nast\u0119pnie dla ifbX dzia\u0142aj\u0105 te same dyscypliny kontroli ruchu wychodz\u0105cego, dla kt\u00f3rego konfiguracja hsfc b\u0119dzie bardzo podobna:<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/iz\/ao\/-k\/izao-kgthgu_ptgyq9cjb1il0wm.png\"><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/967da9c0637cc70ba195af781db18adf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p><\/p>\n<p>W trakcie eksperyment\u00f3w odkryli\u015bmy, \u017ce najlepsze wyniki hsfc uzyskuje si\u0119, gdy klasa 1:2 niepriorytetowego ruchu batch\/idle jest ograniczona na maszynach-minionach do pewnego wolnego pasma. W przeciwnym razie ruch niepriorytetowy zbyt mocno wp\u0142ywa na op\u00f3\u017anienie zada\u0144 prod. Obecna warto\u015b\u0107 wolnego pasma jest okre\u015blana przez miniond co sekund\u0119, mierz\u0105c \u015brednie zu\u017cycie ruchu przez wszystkie zadania prod danego miniona <img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/9d6f38110d3b1693afe222b01430b9bb.jpg\" style=\"display:block;margin: 0 auto;\" \/> i odejmuj\u0105c j\u0105 od przepustowo\u015bci interfejsu sieciowego <img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/d5608ec4c58e44b8571ab0b1d0cc7701.jpg\" style=\"display:block;margin: 0 auto;\" \/> z niewielkim zapasem, t.j.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/fb01347c2224bd5bbd82169861eeb7e4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pasma s\u0105 okre\u015blane niezale\u017cnie dla ruchu przychodz\u0105cego i wychodz\u0105cego. I zgodnie z nowymi warto\u015bciami miniond rekonfiguruje limit klasy niepriorytetowej 1:2.<\/p>\n<p><\/p>\n<p>W ten spos\u00f3b zrealizowali\u015bmy wszystkie trzy klasy izolacji: prod, batch i idle. Te klasy maj\u0105 du\u017cy wp\u0142yw na charakterystyki wykonania zada\u0144. Dlatego zdecydowali\u015bmy si\u0119 umie\u015bci\u0107 ten atrybut na szczycie hierarchii, aby przy spojrzeniu na nazw\u0119 hierarchicznej kolejki od razu by\u0142o jasne, z czym mamy do czynienia: <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/34dc89c461db711b19a0f4eccc50efce.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wszystkie nasze znane <strong>web<\/strong> i <strong>music<\/strong> fronty s\u0105 wtedy umieszczane w hierarchiach pod prod. Na przyk\u0142ad pod batch umie\u015b\u0107my us\u0142ug\u0119 <strong>music catalog<\/strong>, kt\u00f3ry okresowo tworzy katalog utwor\u00f3w z zestawu za\u0142adowanych plik\u00f3w mp3 w \u201eOdnoklassniki\u201d. Przyk\u0142adem us\u0142ugi o idle mo\u017ce by\u0107 <strong>transformator muzyki<\/strong>, normalizuj\u0105cy poziom g\u0142o\u015bno\u015bci muzyki.<\/p>\n<p><\/p>\n<p>Po usuni\u0119ciu zb\u0119dnych linii mo\u017cemy zapisa\u0107 nazwy naszych us\u0142ug w bardziej p\u0142askiej formie, dodaj\u0105c klas\u0119 izolacji zadania na ko\u0144cu pe\u0142nej nazwy us\u0142ugi: <strong>web.front.prod<\/strong>, <strong>catalog.music.batch<\/strong>, <strong>transformer.music.idle<\/strong>.<\/p>\n<p><\/p>\n<p>I teraz, patrz\u0105c na nazw\u0119 us\u0142ugi, rozumiemy nie tylko to, jak\u0105 funkcj\u0119 ona pe\u0142ni, ale tak\u017ce jej klas\u0119 izolacji, a zatem jej krytyczno\u015b\u0107 itd.<\/p>\n<p><\/p>\n<p>Wszystko jest \u015bwietnie, ale jest jedna gorzka prawda. Ca\u0142kowita izolacja zada\u0144 dzia\u0142aj\u0105cych na jednej maszynie jest niemo\u017cliwa.<\/p>\n<p><\/p>\n<p>Co uda\u0142o nam si\u0119 osi\u0105gn\u0105\u0107: je\u015bli zadanie batch intensywnie wykorzystuje <strong>tylko<\/strong> zasoby procesora, to wbudowany harmonogram CPU Linux bardzo dobrze radzi sobie ze swoim zadaniem, a wp\u0142yw na zadanie prod jest praktycznie \u017caden. Ale je\u015bli to zadanie batch zaczyna intensywnie pracowa\u0107 z pami\u0119ci\u0105, wp\u0142yw wsp\u00f3\u0142zale\u017cno\u015bci ju\u017c si\u0119 manifestuje. Dzieje si\u0119 tak, poniewa\u017c z pami\u0119ci \u201ewyp\u0142ukiwane\u201d s\u0105 cache procesora zadania prod \u2014 w rezultacie w cache ro\u015bnie liczba b\u0142\u0119d\u00f3w, a procesor przetwarza zadanie prod wolniej. Takie zadanie batch mo\u017ce zwi\u0119kszy\u0107 op\u00f3\u017anienia naszego typowego kontenera prod o 10%.<\/p>\n<p><\/p>\n<p>Izolacja ruchu jest jeszcze trudniejsza, poniewa\u017c nowoczesne karty sieciowe maj\u0105 wewn\u0119trzn\u0105 kolejk\u0119 pakiet\u00f3w. Je\u015bli pakiet od zadania batch trafi\u0142 tam jako pierwszy, to jako pierwszy zostanie przes\u0142any przez kabel, i nic tu nie mo\u017cna zrobi\u0107.<\/p>\n<p><\/p>\n<p>Ponadto uda\u0142o nam si\u0119 jak dot\u0105d rozwi\u0105za\u0107 tylko problem priorytetyzacji ruchu TCP: dla UDP podej\u015bcie z hsfc nie dzia\u0142a. I nawet w przypadku ruchu TCP, je\u015bli zadanie batch generuje du\u017co ruchu, daje to r\u00f3wnie\u017c oko\u0142o 10% wzrostu op\u00f3\u017anienia zadania prod.<\/p>\n<p><\/p>\n<h2 id=\"otkazoustoychivost\">Odporno\u015b\u0107 na awarie<\/h2>\n<p><\/p>\n<p>Jednym z cel\u00f3w przy tworzeniu one-cloud by\u0142o poprawienie odporno\u015bci na awarie Odnoklassnik\u00f3w. Dlatego chcia\u0142bym bardziej szczeg\u00f3\u0142owo om\u00f3wi\u0107 mo\u017cliwe scenariusze awarii i incydent\u00f3w. Zacznijmy od prostego scenariusza \u2014 awarii kontenera. <\/p>\n<p><\/p>\n<p>Kontener sam w sobie mo\u017ce zawie\u015b\u0107 na kilka sposob\u00f3w. Mo\u017ce to by\u0107 jaki\u015b eksperyment, b\u0142\u0105d lub problem w manife\u015bcie, przez kt\u00f3ry zadanie produkcyjne zaczyna zu\u017cywa\u0107 wi\u0119cej zasob\u00f3w, ni\u017c wskazano w manife\u015bcie. Mieli\u015bmy przypadek: programista zaimplementowa\u0142 jeden skomplikowany algorytm, wielokrotnie go przerabia\u0142, tak si\u0119 pogubi\u0142, \u017ce ostatecznie zadanie zaawansowane znacznie si\u0119 zap\u0119tli\u0142o. A poniewa\u017c zadanie produkcyjne ma wy\u017cszy priorytet ni\u017c wszystkie inne na tych samych minionach, zacz\u0119\u0142o konsumowa\u0107 wszystkie dost\u0119pne zasoby procesora. W tej sytuacji uratowa\u0142a izolacja, a konkretnie kwota czasu procesora. Je\u015bli zadaniu przydzielona jest kwota, nie zu\u017cyje wi\u0119cej. Dlatego inne zadania produkcyjne i wsadowe, kt\u00f3re pracowa\u0142y na tej samej maszynie, niczego nie zauwa\u017cy\u0142y. <\/p>\n<p><\/p>\n<p>Drugim mo\u017cliwym problemem jest awaria kontenera. I tutaj ratuj\u0105 nas polityki ponownego uruchomienia, wszyscy je znaj\u0105, Docker radzi sobie doskonale. Praktycznie wszystkie zadania produkcyjne maj\u0105 polityk\u0119 ponownego uruchomienia always. Czasami u\u017cywamy on_failure dla zada\u0144 wsadowych lub do debugowania kontener\u00f3w produkcyjnych.<\/p>\n<p><\/p>\n<p>Co mo\u017cna zrobi\u0107 w przypadku niedost\u0119pno\u015bci ca\u0142ego miniona?<\/p>\n<p><\/p>\n<p>Oczywi\u015bcie, uruchomi\u0107 kontener na innej maszynie. Najciekawsze jest to, co si\u0119 dzieje z adresem IP (adresami) przypisanymi do kontenera. <\/p>\n<p><\/p>\n<p>Mo\u017cemy przypisywa\u0107 kontenerom te same adresy IP, co maszynom-minionom, na kt\u00f3rych te kontenery s\u0105 uruchamiane. Wtedy, gdy kontener jest uruchamiany na innej maszynie, jego adres IP si\u0119 zmienia, a wszyscy klienci musz\u0105 zrozumie\u0107, \u017ce kontener si\u0119 przeni\u00f3s\u0142, teraz trzeba chodzi\u0107 pod inny adres, co wymaga odr\u0119bnej us\u0142ugi Service Discovery. <\/p>\n<p><\/p>\n<p>Service Discovery to wygodne rozwi\u0105zanie. Na rynku jest wiele rozwi\u0105za\u0144 o r\u00f3\u017cnych poziomach odporno\u015bci na awarie do organizacji rejestr\u00f3w us\u0142ug. Cz\u0119sto w takich rozwi\u0105zaniach realizowana jest logika load balancera, przechowywanie dodatkowej konfiguracji w postaci KV-store itp.<br \/>\nJednak\u017ce chcieliby\u015bmy obej\u015b\u0107 si\u0119 bez potrzeby wdra\u017cania oddzielnego rejestru, poniewa\u017c oznacza\u0142oby to wprowadzenie systemu krytycznego, kt\u00f3ry by\u0142by wykorzystywany przez wszystkie us\u0142ugi w produkcji. A wi\u0119c by\u0142by to potencjalny punkt awarii i trzeba by wybra\u0107 lub opracowa\u0107 bardzo odporne rozwi\u0105zanie, co, jak wiadomo, jest bardzo trudne, czasoch\u0142onne i kosztowne. <\/p>\n<p><\/p>\n<p>I jeszcze jedna powa\u017cna wada: aby nasza stara infrastruktura mog\u0142a dzia\u0142a\u0107 z now\u0105, nale\u017ca\u0142oby przepisa\u0107 absolutnie wszystkie zadania pod k\u0105tem u\u017cycia jakiego\u015b systemu odkrywania us\u0142ug. Pracy jest BARDZO du\u017co, a w niekt\u00f3rych miejscach staje si\u0119 to niemo\u017cliwe, gdy m\u00f3wimy o urz\u0105dzeniach niskopoziomowych dzia\u0142aj\u0105cych na poziomie j\u0105dra systemu operacyjnego lub bezpo\u015brednio z hardwarem. Realizacja tej funkcjonalno\u015bci za pomoc\u0105 ustalonych wzorc\u00f3w rozwi\u0105za\u0144, takich jak na przyk\u0142ad <noindex><a rel=\"nofollow\" href=\"https:\/\/linkerd.io\">side-car<\/a><\/noindex> oznacza\u0142aby w niekt\u00f3rych przypadkach dodatkowe obci\u0105\u017cenie, a w innych \u2014 komplikacj\u0119 eksploatacji i dodatkowe scenariusze awarii. Nie chcieli\u015bmy komplikowa\u0107, dlatego zdecydowali\u015bmy si\u0119 na uczynienie u\u017cycia Service Discovery opcjonalnym. <\/p>\n<p><\/p>\n<p>W one-cloud IP pod\u0105\u017ca za kontenerem, tzn. ka\u017cdy egzemplarz zadania ma sw\u00f3j w\u0142asny adres IP. Ten adres jest \u201estatyczny\u201d: przypisywany jest ka\u017cdemu egzemplarzowi w momencie pierwszego uruchomienia us\u0142ugi w chmurze. Je\u015bli w ci\u0105gu \u017cycia us\u0142ugi istnia\u0142o r\u00f3\u017cne liczby egzemplarzy \u2014 to na ko\u0144cu przypisanych b\u0119dzie tyle adres\u00f3w IP, ile maksymalnie by\u0142o egzemplarzy.<\/p>\n<p><\/p>\n<p>W p\u00f3\u017aniejszym czasie te adresy si\u0119 nie zmieniaj\u0105: przypisane s\u0105 raz i istniej\u0105 przez ca\u0142y okres \u017cycia us\u0142ugi w produkcji. Adresy IP pod\u0105\u017caj\u0105 za kontenerami w sieci. Je\u015bli kontener zostanie przeniesiony na inny minion, to adres r\u00f3wnie\u017c przejdzie za nim. <\/p>\n<p><\/p>\n<p>W ten spos\u00f3b, przyporz\u0105dkowanie nazwy us\u0142ugi do listy jej adres\u00f3w IP zmienia si\u0119 bardzo rzadko. Je\u015bli jeszcze raz spojrzymy na nazwy egzemplarzy us\u0142ugi, kt\u00f3re wspomnieli\u015bmy na pocz\u0105tku artyku\u0142u (<strong>1.ok-web.group1.web.front.prod, 2.ok-web.group1.web.front.prod, \u2026<\/strong>), zauwa\u017cymy, \u017ce przypominaj\u0105 one FQDN u\u017cywane w DNS. I rzeczywi\u015bcie, do wy\u015bwietlania nazw instancji us\u0142ug w ich adresach IP u\u017cywamy protoko\u0142u DNS. Przy czym ten DNS zwraca wszystkie zarezerwowane adresy IP wszystkich kontener\u00f3w \u2014 zar\u00f3wno dzia\u0142aj\u0105cych, jak i zatrzymanych (za\u0142\u00f3\u017cmy, \u017ce u\u017cywane s\u0105 trzy repliki, a mamy tam pi\u0119\u0107 zarezerwowanych adres\u00f3w \u2014 wszystkie pi\u0119\u0107 b\u0119dzie zwracanych). Klienci, otrzymuj\u0105c te informacje, spr\u00f3buj\u0105 nawi\u0105za\u0107 po\u0142\u0105czenie ze wszystkimi pi\u0119cioma replikami \u2014 i w ten spos\u00f3b okre\u015bl\u0105, kt\u00f3re dzia\u0142aj\u0105. Taki spos\u00f3b okre\u015blania dost\u0119pno\u015bci jest znacznie bardziej niezawodny, nie wymaga ani DNS, ani Service Discovery, co oznacza, \u017ce nie ma r\u00f3wnie\u017c trudnych do rozwi\u0105zania problem\u00f3w z aktualno\u015bci\u0105 informacji i odporno\u015bci\u0105 na awarie tych system\u00f3w. Co wi\u0119cej, w krytycznych us\u0142ugach, od kt\u00f3rych zale\u017cy dzia\u0142anie ca\u0142ego portalu, mo\u017cemy w og\u00f3le nie u\u017cywa\u0107 DNS, a po prostu wpisa\u0107 adresy IP w konfiguracji.<\/p>\n<p><\/p>\n<p>Realizacja takiego przenoszenia adres\u00f3w IP mi\u0119dzy kontenerami mo\u017ce by\u0107 nietrywialna \u2014 zatrzymamy si\u0119 na tym, jak to dzia\u0142a, na nast\u0119pnym przyk\u0142adzie:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/faf99c2609a57daa1bdc193cb0f4cb31.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Za\u0142\u00f3\u017cmy, \u017ce master one-cloud wydaje polecenie minionowi M1 uruchomienia <strong>1.ok-web.group1.web.front.prod<\/strong> z adresem 1.1.1.1. Na minionie dzia\u0142a <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Bird_Internet_routing_daemon\">BIRD<\/a><\/noindex>, kt\u00f3ry og\u0142asza ten adres w specjalnych serwerach <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Route_reflector\">route reflector<\/a><\/noindex>. Ostatnie maj\u0105 sesj\u0119 BGP z urz\u0105dzeniem sieciowym, do kt\u00f3rego transmitowany jest rout adresu 1.1.1.1 na M1. M1 przekierowuje pakiety do wewn\u0105trz kontenera ju\u017c za pomoc\u0105 system\u00f3w Linux. Serwer\u00f3w route reflector jest trzy, poniewa\u017c jest to bardzo krytyczna cz\u0119\u015b\u0107 infrastruktury one-cloud \u2014 bez nich sie\u0107 w one-cloud nie b\u0119dzie dzia\u0142a\u0107. Umieszczamy je w r\u00f3\u017cnych szafach, w miar\u0119 mo\u017cliwo\u015bci usytuowanych w r\u00f3\u017cnych salach data center, aby zmniejszy\u0107 prawdopodobie\u0144stwo jednoczesnej awarii wszystkich trzech.<\/p>\n<p><\/p>\n<p>Za\u0142\u00f3\u017cmy teraz, \u017ce po\u0142\u0105czenie mi\u0119dzy masterem one-cloud a minionem M1 zanik\u0142o. Master one-cloud b\u0119dzie teraz dzia\u0142a\u0142, zak\u0142adaj\u0105c, \u017ce M1 ca\u0142kowicie zawi\u00f3d\u0142. To znaczy, wyda polecenie minionowi M2 uruchomienia <strong>web.group1.web.front.prod<\/strong> z tym samym adresem 1.1.1.1. Teraz mamy dwa konfliktuj\u0105ce trasy w sieci dla 1.1.1.1: na M1 i na M2. Aby rozwi\u0105za\u0107 takie konflikty, u\u017cywamy Multi Exit Discriminator, kt\u00f3ry jest wskazywany w og\u0142oszeniu BGP. Jest to liczba, kt\u00f3ra wskazuje wag\u0119 og\u0142aszanego szlaku. Z konfliktuj\u0105cych wybrana zostanie trasa z mniejszym warto\u015bci\u0105 MED. Mistrz one-cloud obs\u0142uguje MED jako integraln\u0105 cz\u0119\u015b\u0107 adres\u00f3w IP kontener\u00f3w. Po raz pierwszy adres jest wystawiany z do\u015b\u0107 wysokim MED = 1 000 000. W sytuacji takiego awaryjnego przeniesienia kontenera mistrz zmniejsza MED, a M2 ju\u017c otrzyma polecenie og\u0142oszenia adresu 1.1.1.1 z MED = 999 999. Instancja dzia\u0142aj\u0105ca na M1 pozostanie przy tym bez po\u0142\u0105czenia, a jej dalszy los ma\u0142o nas interesuje do momentu przywr\u00f3cenia po\u0142\u0105czenia z mistrzem, kiedy to zostanie zatrzymana jako stary duplikat.<\/p>\n<p><\/p>\n<h2 id=\"avarii\">Awarie<\/h2>\n<p><\/p>\n<p>Wszystkie systemy zarz\u0105dzania centrami danych zawsze akceptowalnie radz\u0105 sobie z drobnymi awariami. Wypadni\u0119cie kontenera to normy praktycznie wsz\u0119dzie.<\/p>\n<p><\/p>\n<p>Przyjrzyjmy si\u0119, jak radzimy sobie z awari\u0105, na przyk\u0142ad awari\u0105 zasilania w jednym lub wi\u0119cej salach centrum danych.<\/p>\n<p><\/p>\n<p>Co oznacza awaria dla systemu zarz\u0105dzania centrum danych? Przede wszystkim to masowe jednoczesne awari\u0119 wielu maszyn, a system zarz\u0105dzania musi jednocze\u015bnie migrowa\u0107 bardzo wiele kontener\u00f3w. Ale je\u015bli awaria jest bardzo rozleg\u0142a, mo\u017ce si\u0119 zdarzy\u0107, \u017ce wszystkie zadania nie b\u0119d\u0105 mog\u0142y zosta\u0107 przeniesione na innych minion\u00f3w, poniewa\u017c pojemno\u015b\u0107 zasob\u00f3w centrum danych spada poni\u017cej 100% obci\u0105\u017cenia. <\/p>\n<p><\/p>\n<p>Cz\u0119sto awariom towarzyszy r\u00f3wnie\u017c awaria warstwy steruj\u0105cej. Mo\u017ce to si\u0119 zdarzy\u0107 z powodu uszkodzenia sprz\u0119tu, ale cz\u0119\u015bciej z powodu tego, \u017ce awarie nie s\u0105 testowane, a warstwa zarz\u0105dzaj\u0105ca sama upada pod zwi\u0119kszonym obci\u0105\u017ceniem. <\/p>\n<p><\/p>\n<p>Co mo\u017cna z tym wszystkim zrobi\u0107?<\/p>\n<p><\/p>\n<p>Masywne migracje oznaczaj\u0105, \u017ce w infrastrukturze pojawia si\u0119 wiele dzia\u0142a\u0144, migracji i lokacji. Ka\u017cda z migracji mo\u017ce zajmowa\u0107 jaki\u015b czas, potrzebny na dostarczenie i rozpakowanie obraz\u00f3w kontener\u00f3w do minion\u00f3w, uruchomienie i inicjalizacj\u0119 kontener\u00f3w itp. Dlatego wskazane jest, aby wa\u017cniejsze zadania uruchamia\u0107 przed mniej wa\u017cnymi.<\/p>\n<p><\/p>\n<p>Znowu przyjrzyjmy si\u0119 znanej nam hierarchii us\u0142ug i spr\u00f3bujmy ustali\u0107, jakie zadania chcemy uruchomi\u0107 w pierwszej kolejno\u015bci.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/2e827271adb8d3ff3d385e53553aaacf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Oczywi\u015bcie, to s\u0105 procesy, kt\u00f3re bezpo\u015brednio uczestnicz\u0105 w obs\u0142udze zapyta\u0144 u\u017cytkownik\u00f3w, tzn. prod. Wskazujemy to za pomoc\u0105 <strong>priorytetu umieszczania<\/strong> \u2014 liczby, kt\u00f3ra mo\u017ce by\u0107 przypisana do kolejki. Je\u015bli jaka\u015b kolejka ma wy\u017cszy priorytet, jej us\u0142ugi s\u0105 umieszczane w pierwszej kolejno\u015bci.<\/p>\n<p><\/p>\n<p>Na prod przypisujemy wy\u017csze priorytety, 0; na batch \u2014 nieco ni\u017csze, 100; na idle \u2014 jeszcze ni\u017csze, 200. Priorytety s\u0105 stosowane hierarchicznie. Wszystkie zadania ni\u017csze w hierarchii b\u0119d\u0105 mia\u0142y odpowiedni priorytet. Je\u015bli chcemy, aby w obr\u0119bie prod pami\u0119ci podr\u0119czne by\u0142y uruchamiane przed frontami, to przypisujemy priorytety na cache = 0 i na front podkolejki = 1. Je\u015bli jednak, na przyk\u0142ad, chcemy, aby z front\u00f3w najpierw uruchamia\u0142 si\u0119 g\u0142\u00f3wny portal, a front muzyczny ju\u017c potem, to temu ostatniemu mo\u017cemy przypisa\u0107 ni\u017cszy priorytet \u2014 10.<\/p>\n<p><\/p>\n<p>Nast\u0119pnym problemem jest brak zasob\u00f3w. Tak wi\u0119c, mieli\u015bmy awari\u0119 du\u017cej liczby sprz\u0119tu, ca\u0142ych sal data center, a uruchomili\u015bmy tyle us\u0142ug, \u017ce teraz dla wszystkich brakuje zasob\u00f3w. Musimy zdecydowa\u0107, kt\u00f3re zadania po\u015bwi\u0119ci\u0107, aby dzia\u0142a\u0142y podstawowe krytyczne us\u0142ugi. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/1b1ad3da16df6677dd0ba4b038cdd7d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>W przeciwie\u0144stwie do priorytetu umieszczania, nie mo\u017cemy po prostu po\u015bwi\u0119ci\u0107 wszystkich zada\u0144 batch, poniewa\u017c niekt\u00f3re z nich s\u0105 wa\u017cne dla dzia\u0142ania portalu. Dlatego wydzielili\u015bmy osobno <strong>priorytet wypierania<\/strong> zada\u0144. Przy umieszczaniu zadanie z wy\u017cszym priorytetem mo\u017ce wypchn\u0105\u0107, tzn. zatrzyma\u0107 zadanie z ni\u017cszym priorytetem, je\u015bli nie ma ju\u017c wolnych minion\u00f3w. Przy tym zadanie z niskim priorytetem prawdopodobnie pozostanie niewykonane, tzn. dla niej nie b\u0119dzie ju\u017c odpowiedniego miniona z wystarczaj\u0105c\u0105 ilo\u015bci\u0105 wolnych zasob\u00f3w.<\/p>\n<p><\/p>\n<p>W naszej hierarchii bardzo \u0142atwo jest wskaza\u0107 taki priorytet wypierania, aby zadania prod i batch wypiera\u0142y lub zatrzymywa\u0142y zadania idle, ale nie nawzajem, wskazuj\u0105c dla idle priorytet r\u00f3wny 200. Podobnie jak w przypadku priorytetu umieszczania, mo\u017cemy wykorzysta\u0107 nasz\u0105 hierarchi\u0119 do opisywania bardziej z\u0142o\u017conych regu\u0142. Na przyk\u0142ad, okre\u015blimy, \u017ce po\u015bwi\u0119camy funkcj\u0119 muzyki, je\u015bli zabraknie nam zasob\u00f3w dla g\u0142\u00f3wnego portalu webowego, ustawiaj\u0105c dla odpowiednich w\u0119z\u0142\u00f3w priorytet ni\u017cszy: 10.<\/p>\n<p><\/p>\n<h2 id=\"avarii-dc-celikom\">Awaria DC ca\u0142kowicie<\/h2>\n<p><\/p>\n<p>Dlaczego mo\u017ce zawie\u015b\u0107 ca\u0142e data center? \u017bywio\u0142. By\u0142 dobry post, jak <noindex><a rel=\"nofollow\" href=\"https:\/\/habrahabr.ru\/company\/dataline\/blog\/333578\/\">huragan wp\u0142yn\u0105\u0142 na dzia\u0142anie data center<\/a><\/noindex>Mo\u017cna uzna\u0107, \u017ce \u017cywio\u0142em s\u0105 bezdomni, kt\u00f3rzy w pewnym momencie spalili \u015bwiat\u0142ow\u00f3d w kanale, przez co ca\u0142y data center straci\u0142 kontakt z innymi lokalizacjami. Przyczyny awarii mog\u0105 le\u017ce\u0107 tak\u017ce w czynniku ludzkim: operator wydaje takie polecenie, \u017ce ca\u0142e data center pada. Takie sytuacje mog\u0105 wyst\u0105pi\u0107 z powodu du\u017cego b\u0142\u0119du. Og\u00f3lnie rzecz bior\u0105c, data center padaj\u0105 \u2014 to nie jest rzadko\u015b\u0107. U nas zdarza si\u0119 to co kilka miesi\u0119cy. <\/p>\n<p><\/p>\n<p>I oto co robimy, aby nikt #ok\u017cyj nie publikowa\u0142 w Twitterze.<\/p>\n<p><\/p>\n<p>Pierwsza strategia \u2014 izolacja. Ka\u017cdy instancja one-cloud jest izolowana i mo\u017ce zarz\u0105dza\u0107 maszynami tylko jednego data center. To znaczy, \u017ce utrata chmury z powodu b\u0142\u0119d\u00f3w lub niew\u0142a\u015bciwego polecenia operatora \u2014 to utrata tylko jednego data center. Jeste\u015bmy na to gotowi: mamy polityk\u0119 rezerwacji, w kt\u00f3rej kopie aplikacji i danych s\u0105 umieszczane we wszystkich data center. Korzystamy z baz danych odpornych na awarie i okresowo testujemy awarie.<br \/>\nPoniewa\u017c mamy dzi\u015b cztery data center, mamy tak\u017ce cztery oddzielne, ca\u0142kowicie izolowane instancje one-cloud.<\/p>\n<p><\/p>\n<p>Takie podej\u015bcie nie tylko chroni przed fizyczn\u0105 awari\u0105, ale tak\u017ce mo\u017ce chroni\u0107 przed b\u0142\u0119dami operatora.<\/p>\n<p><\/p>\n<p>A co jeszcze mo\u017cna zrobi\u0107 w zwi\u0105zku z czynnikiem ludzkim? Kiedy operator wydaje chmurze dziwne lub potencjalnie niebezpieczne polecenie, mo\u017ce zosta\u0107 nagle poproszony o rozwi\u0105zanie ma\u0142ego zadania, aby sprawdzi\u0107, jak dobrze si\u0119 zastanowi\u0142. Na przyk\u0142ad, je\u015bli to jakie\u015b masowe zatrzymanie wielu replik lub po prostu dziwne polecenie \u2014 zmniejszenie liczby replik lub zmiana nazwy obrazu, a nie tylko numeru wersji w nowym manife\u015bcie.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habrastorage.org\/webt\/vh\/vw\/0d\/vhvw0dzobo9sd4x7zih_cnfnlu8.png\"><img decoding=\"async\" alt=\"One-cloud \u2014 system operacyjny na poziomie centrum danych w Odnoklassnikach\" src=\"\/wp-content\/uploads\/2020\/06\/f7ee44a77e30612a3cd99a6f7aee3820.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p><\/p>\n<h2 id=\"itogi\">Podsumowanie<\/h2>\n<p><\/p>\n<p>Cechy wyr\u00f3\u017cniaj\u0105ce one-cloud: <\/p>\n<p><\/p>\n<ul>\n<li><strong>Hierarchiczny i przejrzysty schemat nazewnictwa us\u0142ug i kontener\u00f3w<\/strong>, kt\u00f3ry pozwala bardzo szybko zrozumie\u0107, co to za zadanie, do czego si\u0119 odnosi, jak dzia\u0142a i kto za nie odpowiada. <\/li>\n<li>Stosujemy nasz\u0105 <strong>technik\u0119 \u0142\u0105czenia zada\u0144 prod- i batch-<\/strong>na minionach, aby poprawi\u0107 efektywno\u015b\u0107 wsp\u00f3\u0142dzielenia maszyn. Zamiast cpuset u\u017cywamy kwot CPU, udzia\u0142\u00f3w, polityk planowania CPU i Linux QoS.<\/li>\n<li>Nie uda\u0142o si\u0119 ca\u0142kowicie izolowa\u0107 kontener\u00f3w dzia\u0142aj\u0105cych na jednej maszynie, ale ich wzajemny wp\u0142yw pozostaje na poziomie do 20%.<\/li>\n<li>Organizacja us\u0142ug w hierarchi\u0119 pomaga przy automatycznej likwidacji awarii za pomoc\u0105 <strong>priorytet\u00f3w usytuowania i wymuszania<\/strong>.<\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"chavo\">FAQ<\/h2>\n<p><\/p>\n<p>Dlaczego nie wybrali\u015bmy gotowego rozwi\u0105zania.<\/p>\n<p><\/p>\n<ul>\n<li>R\u00f3\u017cne klasy izolacji zada\u0144 wymagaj\u0105 r\u00f3\u017cnej logiki przy ich umieszczaniu na minionach. Je\u015bli zadania produkcyjne mo\u017cna umieszcza\u0107 za pomoc\u0105 prostego rezerwowania zasob\u00f3w, to zadania wsadowe i idle musz\u0105 by\u0107 umieszczane, \u015bledz\u0105c rzeczywiste wykorzystanie zasob\u00f3w na maszynach-minionach. <\/li>\n<li>Potrzeba uwzgl\u0119dnienia takich zasob\u00f3w wykorzystywanych przez zadania, jak: \n<ul>\n<li>przepustowo\u015b\u0107 sieci;<\/li>\n<li>typy i 'spindle' dysk\u00f3w.<\/li>\n<\/ul>\n<\/li>\n<li>Potrzeba wskazywania priorytet\u00f3w serwis\u00f3w przy likwidacji awarii, praw i kwot zespo\u0142\u00f3w na zasoby, co jest realizowane za pomoc\u0105 hierarchicznych kolejek w one-cloud.<\/li>\n<li>Potrzeba posiadania ludzkich nazw kontener\u00f3w, aby skr\u00f3ci\u0107 czas reakcji na awarie i incydenty.<\/li>\n<li>Niemo\u017cno\u015b\u0107 jednoczesnej og\u00f3lnolokalnej implementacji Service Discovery; potrzeba d\u0142ugiego wsp\u00f3\u0142istnienia z zadaniami umieszczonymi na fizycznych hostach \u2014 co rozwi\u0105zuje zastosowanie 'statycznych' adres\u00f3w IP, kt\u00f3re pod\u0105\u017caj\u0105 za kontenerami, a w konsekwencji wym\u00f3g unikalnej integracji z du\u017c\u0105 infrastruktur\u0105 sieciow\u0105.<\/li>\n<\/ul>\n<p><\/p>\n<p>Wszystkie te funkcje wymaga\u0142yby znacznych przer\u00f3bek istniej\u0105cych rozwi\u0105za\u0144 pod siebie, a po oszacowaniu ilo\u015bci pracy zrozumieli\u015bmy, \u017ce mo\u017cemy opracowa\u0107 nasze rozwi\u0105zanie z podobnym nak\u0142adem pracy. Jednak nasze rozwi\u0105zanie b\u0119dzie znacznie \u0142atwiejsze w eksploatacji i rozwoju \u2014 nie ma w nim niepotrzebnych abstrakcji, kt\u00f3re wspiera\u0142yby nam nieistotne funkcjonalno\u015bci. <\/p>\n<p><\/p>\n<p>Dzi\u0119kujemy tym, kt\u00f3rzy czytaj\u0105 te ostatnie zdania, za cierpliwo\u015b\u0107 i uwag\u0119!<\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/odnoklassniki\/blog\/346868\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0410\u043b\u043e\u0445\u0430, \u043f\u0438\u043f\u043b! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041e\u043b\u0435\u0433 \u0410\u043d\u0430\u0441\u0442\u0430\u0441\u044c\u0435\u0432, \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u041f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u0410 \u043a\u0440\u043e\u043c\u0435 \u043c\u0435\u043d\u044f, \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0443\u0447\u0430 \u0436\u0435\u043b\u0435\u0437\u0430. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0447\u0435\u0442\u044b\u0440\u0435 \u0426\u041e\u0414\u0430, \u0432 \u043d\u0438\u0445 \u043e\u043a\u043e\u043b\u043e 500 \u0441\u0442\u043e\u0435\u043a \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0441 8 \u0442\u044b\u0441\u044f\u0447\u0430\u043c\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432. \u0412 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043f\u043e\u043d\u044f\u043b\u0438, \u0447\u0442\u043e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0442\u0435\u0445\u043d\u0438\u043a\u0443, \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":84115,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-84114","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0410\u043b\u043e\u0445\u0430, \u043f\u0438\u043f\u043b!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/one-cloud-os-urovnya-data-czentra-v-odnoklassnikah\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47One-cloud \u2014 \u041e\u0421 \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430 \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0410\u043b\u043e\u0445\u0430, \u043f\u0438\u043f\u043b!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/one-cloud-os-urovnya-data-czentra-v-odnoklassnikah\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-06-05T05:42:55+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-06-05T05:42:55+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47One-cloud \u2014 System operacyjny na poziomie centrum danych w Odnoklassnikach | ProHoster","description":"Aloha, ludzie!","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/one-cloud-os-urovnya-data-czentra-v-odnoklassnikah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47One-cloud \u2014 \u041e\u0421 \u0443\u0440\u043e\u0432\u043d\u044f \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0430 \u0432 \u041e\u0434\u043d\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u0438\u043a\u0430\u0445 | ProHoster","og:description":"\u0410\u043b\u043e\u0445\u0430, \u043f\u0438\u043f\u043b!","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/one-cloud-os-urovnya-data-czentra-v-odnoklassnikah","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-06-05T05:42:55+00:00","article:modified_time":"2020-06-05T05:42:55+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"84114","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 15:04:42","updated":"2022-10-02 14:53:14","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/84114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=84114"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/84114\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/84115"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=84114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=84114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=84114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}