\documentclass[margin=0px]{article} \usepackage{listings} \usepackage[utf8]{inputenc} \usepackage{graphicx} \usepackage{float} \usepackage[a4paper, margin=0.7in]{geometry} \usepackage{amsthm} \usepackage{amssymb} \usepackage{fancyhdr} \usepackage{setspace} \onehalfspacing \renewcommand{\figurename}{ábra} \newenvironment{tetel}[1]{\paragraph{#1}}{} \pagestyle{fancy} \lhead{\it{PTI BSc Záróvizsga tételek}} \rhead{19. Osztott rendszerek és konkurens programozás} \title{\textbf{{\Large ELTE IK - Programtervező Informatikus BSc} \vspace{0.2cm} \\ {\huge Záróvizsga tételek}} \vspace{0.3cm} \\ 19. Osztott rendszerek és konkurens programozás} \author{} \date{} \begin{document} \maketitle TODO: Csak a "C" van kidolgozva a "2018"-as nem! \begin{tetel}{Osztott rendszerek és konkurens programozás} \begin{itemize} \item[] \textbf{A, C}: Folyamat fogalma, elosztott rendszerek tulajdonságai és felépítése, elnevezési rendszerek, kommunikáció, szinkronizáció, konzisztencia. \item[] \textbf{B}: Feladatok specifikációja biztonsági és haladási feltételekkel, absztrakt párhuzamos program tulajdonságai, megoldás fogalma, nevezetes feladatok megoldása párhuzamos és elosztott programokkal. \item[] \textbf{2018}: Szálkezelés. Ütemezés, kontextusváltás. Race condition. Szinkronizáció. Blokkoló műveletek. Memória (stack és heap) használata a szálakban. A konkurens programozás nyelvi eszközei. Szinkronizációhoz és kommunikációhoz használható adatszerkezetek. \end{itemize} \end{tetel} \section{Folyamatok, szálak} \noindent \textbf{Szál}: A szál (thread) a processzor egyfajta szoftveres megfelelője, minimális kontextussal. Ha a szálat megállítjuk, a kontextus elmenthető és továbbfuttatáshoz visszatölthető.\\ \noindent \textbf{Folyamat}: A folyamat (process vagy task) egy vagy több szálat összefogó nagyobb egység. Egy folyamat szálai közös memóriaterületen (címtartományon) dolgoznak, azonban különböző folyamatok nem látják egymás memóriaterületét.\\ \noindent \textbf{Kontextusváltás}: A másik folyamatnak/szálnak történő vezérlésátadás, így egy processzor több szálat/ folyamatot is végre tud hajtani.\\ \noindent \textbf{Szál vs. folyamat}: A szálak közötti váltáshoz nem kell igénybe venni az oprendszer szolgáltatásait, míg a folyamatok közötti váltásnál ahhoz, hogy a régi és új folyamat memóriaterülete elkülönüljön a memóriavezérlő (MMU) tartalmának jó részét át kell írni, amihez csak a kernel szintnek van joga. A folyamatok létrehozása, törlése és a kontextusváltás közöttük sokkal költségesebb a szálakénál. \section{Elosztott rendszerek tulajdonságai és felépítése} \noindent \textbf{Elosztott rendszer fogalma}: Az elosztott rendszer önálló számítógépek olyan összessége, amely kezelői számára egyetlen koherens rendszernek tűnik. \subsection{Az elosztott rendszer céljai, tulajdonságai} Az elosztott rendszer céljai a következők: \begin{itemize} \item Távoli erőforrások elérhetővé tétele \item Átlátszóság (transparency) \item Nyitottság (openness) \item Skálázhatóság \end{itemize} \subsubsection{Átlátszóság} Az átlátszóság nem más, mint az erőforrásokkal kapcsolatos különböző információk elrejtése a felhasználó elől. Az alapján, hogy mit rejtünk el, többféle fajtája létezik: \begin{figure}[H] \centering \includegraphics[width=0.8\linewidth]{img/atlatszosag} \caption{Az átlátszóság különböző típusai.} \label{fig:atlatszosag} \end{figure} \subsubsection{Nyitottság} A rendszer képes más nyitott rendszerek számára szolgáltatásokat nyújtani, és azok szolgáltatásait igénybe venni: \begin{itemize} \item A rendszerek jól definiált interfészekkel rendelkeznek. \item Az alkalmazások hordozhatóságát (portability) minél inkább támogatják. \item Könnyen elérhető a rendszerek együttműködése. \end{itemize} \noindent A nyitott elosztott rendszer legyen könnyen alkalmazható heterogén környezetben, azaz különböző hardvereken, platformokon, programozási nyelveken.\\ \noindent \textbf{Implementálása}: \begin{itemize} \item Fontos, hogy a rendszer könnyen cserélhető elemekből álljon. \item Belső interfészek használata, nem egyetlen monolitikus rendszer. \item A rendszernek minél jobban paraméterezhetőnek kell lennie. \item Egyetlen komponens megváltoztatása/cseréje lehetőleg minél kevésbé hasson a rendszer más részeire. \end{itemize} \subsubsection{Skálázhatóság} Többféle jelentése van, 3 fontos dimenzió: \begin{enumerate} \item méret szerinti skálázhatóság: a felhasználók és/vagy folyamatok száma \item földrajzi skálázhatóság: a csúcsok közötti legnagyobb távolság \item adminisztrációs skálázhatóság: az adminisztrációs tartományok száma \end{enumerate} Ezek közül a legtöbb rendszer a méret szerinti skálázhatóságot kezeli, ennek egy lehetséges megvalósítási módja erősebb szerverek használata. A másik kettőt nehezebb kezelni.\\ \noindent Technikák a skálázhatóság megvalósítására: \begin{itemize} \item A kommunikációs késleltetés elfedése azzal, hogy a válaszra várás közben más tevékenységet végzünk. Ehhez aszinkron kommunikáció szükséges. \item Elosztás: az adatokat és számításokat több számítógép tárolja/végzi (pl. amit lehet, a klienssel számoltatunk ki, elosztott elnevezési rendszerek használata, stb.) \item Replikáció/cache-elés: Több számítógép tárolja egy adat másolatait \end{itemize} A skálázhatóságnak ára van. Több másolat fenntartása inkonzisztenciához vezethet (ha módosítjuk az egyiket, az eltérhet a többitől). Ez globális szinkronizációval kikerülhető (minden egyes változtatás után az összes másolatot frissítjük), viszont a globális szinkronizáció rosszul skálázódik. Emiatt sok esetben fel kell hagynunk a globális szinkronizációval, ez viszont bizonyos mértékű inkonzisztenciát eredményez. Rendszerfüggő, hogy ez milyen mértékben megengedett. A cél az, hogy az inkonzisztencia mértéke a megengedett szint alatt maradjon. \subsection{Elosztott rendszerek típusai} \noindent \textbf{Főbb típusok}: \begin{itemize} \item Elosztott számítási rendszerek: \item Elosztott információs rendszerek \item Elosztott átható rendszerek \end{itemize} \subsubsection{Elosztott számítási rendszerek} Célja számítások végzése nagy teljesítménnyel.\\ \noindent \textbf{Cluster (fürt)}: Lokális hálózatra kapcsolt számítógépek összessége. Homogén rendszer (ugyanaz az oprendszer, hardveresen hasonlóak), központosított vezérléssel (általában egy gépre).\\ \noindent \textbf{Grid (rács)} Nagyméretű hálózatokra is kiterjedhet, akár több szervezeti egységen is átívelhet. Heterogén architektúra jellemzi.\\ \noindent \textbf{Cloud(felhő)}: Többrétegű architektúra: hardver, infrastruktúra, platform, alkalmazás. \subsubsection{Elosztott információs rendszerek} Az elsődleges cél általában adatok kezelése, illetve más információs rendszerek elérése. Például tranzakciókezelő rendszerek. A tranzakció adatok összességén (pl. egy adatbázison, adatbázis objektumon, stb.) végzett művelet (lehetnek részműveletei). A tranzakciókkal szemben az alábbi követelményeket szokás támasztani (ACID): \begin{itemize} \item Oszthatatlan, elemi (atomicity): Vagy a teljes tranzakció végbemegy minden részműveletével, vagy az adattárház egyáltalán nem változik. \item Konzisztens (consistency): Az adattárra akkor mondjuk, hogy érvényes, ha bizonyos, az adott adattárra megfogalmazott feltételek teljesülnek. Egy tranzakció konzisztens, ha érvényes állapotot állít elő a tranzakció végén. \item Elkülöníthető, sorosítható (isolation): Egyszerre zajló tranzakciók olyan eredményt adnak, mintha egymás után hajtódtak volna végre. \item Tartósság (durability): Végrehajtás után az eredményt tartós adattárolóra mentjük, így az összeomlás esetén visszaállítható. \end{itemize} \subsection{Elosztott rendszerek felépítése} Alapötlet: A rendszer elemeit szervezzük logikai szerepük szerint különböző komponensekbe, és ezeket osszuk el a rendszer gépein.\\ \subsubsection{Központosított architektúrák} \noindent \textbf{Kliens-szerver modell}: Egyes folyamatok (szerverek) szolgáltatásokat ajánlanak, míg más folyamatok (kliensek) ezeket a szolgáltatásokat szeretnék használni. A kliens kérést küld a szervernek, amire a szerver válaszol, így veszi igénybe a szolgáltatást. A kliens és szerver folyamatok különböző gépeken lehetnek. \subsubsection{Többrétegű architektúrák} Az elosztott információs rendszerek gyakran három logikai rétegre (layer vagy tier) vannak tagolva: \begin{itemize} \item Megjelenítés: az alkalmazás felhasználói felületét alkotó komponensekből áll. \item Üzleti logika: az alkalmazás működését írja le konkrét adatok nélkül \item Perzisztencia: az adatok tartós tárolása \end{itemize} \subsubsection{Decentralizált architektúrák} \noindent \textbf{Peer-to-peer (P2P)}: A csúcsok (peer-ek) között többnyire nincsenek kitüntetett szerepűek.\\ \noindent \textbf{Overlay hálózat}: A gráfban szomszédos csúcsok fizikailag lehetnek távol egymástól, a rendszer elfedi, hogy a köztük lévő kommunikáció több gépen keresztül zajlik. A legtöbb P2P rendszer overlay hálózatra épül.\\ \noindent \textbf{P2P rendszerek fajtái}: \begin{itemize} \item Strukturált P2P: A csúcsok által kiadott gráfszerkezet rögzített. A csúcsokat valamilyen struktúra szerint overlay hálózatba szervezzük és a csúcsoktól az azonosítójuk alapján lehet szolgáltatásokat igénybe venni. Pl.: elosztott hasítótábla (DHT). \item Struktúrálatlan P2P: Az ilyen rendszerek igyekeznek véletlen gráfstruktúrát fenntartani. Mindegyik csúcsnak csak részleges nézete van a gráfról. Minden $P$ csúcs időnként véletlenszerűen kiválaszt egy $Q$ szomszédot. $P$ és $Q$ információt cserélnek és elküldik egymásnak az általuk ismert csúcsokat. \item Hibrid P2P: néhány csúcsnak speciális szerepe van \end{itemize} \noindent \textbf{Superpeer}: Olyan csúcs, aminek külön feladata van, pl. kereséshez index fenntartása, a hálózat állapotának felügyelete, csúcsok közötti kapcsolatok létrehozása. \section{Elnevezési rendszerek} Az elosztott rendszerek entitásai a kapcsolódási pontjaikon (access point) keresztül érhetőek el. Ezeket távolról a címük azonosítja, amely megnevezi az adott pontot. Célszerű lehet az entitást a kapcsolódási pontjaitól függetlenül is elnevezni. Az ilyen nevek helyfüggetlenek (location independent).\\ \noindent \textbf{Egyszerű név}: Nincs szerkezete, tartalmaz véletlen szöveg. Csak összehasonlításra használható.\\ \noindent \textbf{Azonosító}: Egy név azonosító, ha egy-egy kapcsolatban áll a megnevezett entitással, és ez a hozzárendelés maradandó, azaz a név később nem hivatkozhat más egyedre. \subsection{Strukturálatlan nevek} \subsubsection{Egyszerű megoldások} \noindent \textbf{Broadcasting}: Kihirdetjük az azonosítót a hálózaton. Az egyed visszaküldi jelenlegi címét. Hátrányai: \begin{itemize} \item Lokális hálózatokon túl nem skálázódik. \item A hálózaton minden gépnek figyelnie kell a beérkező kérésre. \end{itemize} \noindent \textbf{Továbbítómutató}: Amikor az egyed elköltözik, egy mutató marad utána az új helyére. \begin{itemize} \item A kliens elől el van fedve, hogy a szoftver továbbítómutató-láncot old fel. \item A megtalált címet vissza lehet küldeni a klienshez, így a további feloldások gyorsabban mennek. \item Földrajzi skálázási problémák: \begin{itemize} \item A hosszú láncok nem hibatűrőek. \item A feloldás hosszú időbe telik. \item Külön mechanizmus szükséges a láncok rövidítésére. \end{itemize} \end{itemize} \subsubsection{Otthon alapú megoldások} \noindent \textbf{Egyrétegű rendszer}: Az egyedhez tartozik egy otthon, ez tartja számon az egyed jelenlegi címét. Az egyed otthoni címe (home address - HA) be van jegyezve egy névszolgáltatásba. Az otthon számon tartja a jelenlegi címet (foreign address - FA). A kliens az otthonhoz kapcsolódik, onnan kapja meg a címet.\\ \noindent \textbf{Kétrétegű rendszer}: Az egyes környékeken feljegyezzük, hogy mely egyedek tartózkodnak a közelben. A névfeloldás először ezt a jegyzéket vizsgálja meg és ha az egyed nincs a környéken, akkor kell az otthonhoz fordulni. \subsubsection{Elosztott hasítótábla} Elosztott hasítótáblát (DHT) készítünk, ebben csúcsok tárolnak egyedeket. Az $N$ csúcs gyűrű overlay szerkezetbe van szervezve. Minden csúcshoz hozzárendelünk egy $m$ bites azonosítót, és mindegyik entitáshoz egy $m$ bites kulcsot ($N \leq 2^{m}$). A $k$ kulcsú egyed felelőse az az $id$ azonosítójú csúcs, amelyre $k \leq id$, és nincs köztük másik csúcs. Ezt a csúcsot a kulcs rákövetkezőjének is szokás nevezni: $succ(k)$. Mindegyik $p$ csúcs egy $FT_{p}$ finger table-t tárol $m$ bejegyzéssel: $FT_{p}[i] = succ (p+2^{i-1})$. Bináris (jellegű) keresést szeretnénk elérni, ezért minden lépés felezi a keresési tartományt. A $k$ kulcsú egyed kikereséséhez (ha nem a jelenlegi csúcs tartalmazza) a kérést továbbítjuk ahhoz a $j$ indexű csúcshoz, melyre $FT_{p}[j] \leq k < FT_{p}[j+1]$, illetve, ha $p\frac{n}{2}$. Feltesszük, hogy egy esetleges összeomlás után a koordinátor felépül, de a kiadott engedélyeket elfelejti. \subsubsection{Elosztott kölcsönös kizárás} Többszörözött az erőforrás. Amikor a kliens hozzá szeretne férni az erőforráshoz, kérést küld a koordinátornak időbélyeggel ellátva. Választ (hozzáférési engedélyt) akkor kap, ha: \begin{itemize} \item A koordinátor nem igényli az erőforrást, vagy \item a koordinátor is igényli az erőforrást, de kisebb az időbélyege. \item Különben a koordinátor átmenetileg nem válaszol. \end{itemize} \begin{figure}[H] \centering \includegraphics[width=0.6\linewidth]{img/kolcskizar_elosztott} \caption{Példa elosztott kölcsönös kizárásra.} \label{fig:kolcskizar_elosztott} \end{figure} \subsubsection{Kölcsönös kizárás token ring-gel} A folyamatokat egy logikai gyűrűbe szervezzük. Egy tokent küldünk körbe. Amelyik folyamat birtokolja a tokent, az férhet hozzá az erőforráshoz. \subsection{Vezetőválasztás} Sok algoritmusnak szüksége van arra, hogy kijelöljön egy folyamatot, amely a további lépéseket koordinálja. \subsubsection{Zsarnok-algoritmus} A folyamatoknak sorszámot adunk, melyek közül a legnagyobb sorszámút szeretnénk vezetőnek választani.\\ \noindent A zsarnok-algoritmus lépései: \begin{enumerate} \item A vezetőválasztás kezdeményezése. Bármelyik folyamat kezdeményezheti. Mindegyik olyan folyamatnak, amelyről nem tudja, hogy kisebb lenne az övénél a sorszáma, elküld egy üzenetet. \item Ha a nagyobb sorszámú folyamat üzenetet kap egy kisebb sorszámútól, akkor visszaküld neki egy olyan üzenetet, amivel kiveszi a kisebb sorszámút a választásból. \item Amelyik folyamat nem kap letiltó üzenet egy bizonyos időn belül, akkor ő lesz a vezető. Erről értesíti a többi folyamatot egy-egy üzenettel. \end{enumerate} \begin{figure}[H] \centering \includegraphics[width=0.6\linewidth]{img/zsarnok} \caption{Példa a zsarnok-algoritmus működésére.} \label{fig:zsarnok} \end{figure} \subsubsection{Vezetőválasztás gyűrűben} Logikai gyűrűnk van, a folyamatoknak vannak sorszámai. A legnagyobb sorszámú folyamatot szeretnénk vezetőnek választani. Bármelyik folyamat kezdeményezhet vezetőválasztást: elindít egy üzenetet a gyűrűn körbe, amelyre mindenki ráírja a a sorszámát. Ha egy folyamat összeomlott, az kimarad az üzenetküldésből. Amikor az üzenet visszajut a kezdeményezőhöz, minden aktív folyamat sorszáma szerepel rajta. Ezek közül a legnagyobb sorszámú lesz a vezető. Ezt egy másik üzenet körbeküldése tudatja mindenkivel. Ha több folyamat kezdeményez egyszerre választást, az nem probléma, ugyanaz az eredmény adódik. Ha az üzenetek elvesznének, akkor újra lehet kezdeni a választást. \subsubsection{Superpeer-választás} A superpeer-eket úgy szeretnénk megválasztani, hogy teljesüljön rájuk: \begin{itemize} \item A többi csúcs alacsony késleltetéssel éri el őket. \item Egyenletesen vannak elosztva a hálózaton. \item A csúcsok megadott hányadát választjuk superpeer-nek. \item Egy superpeer korlátozott számú peer-t szolgál ki. \end{itemize} \noindent \textbf{Megvalósítás DHT esetén}: Ha $m$-bites azonosítókat használunk, és $S$ superpeer-re van szükség, akkor a $k= \lceil \log_{2} S \rceil$ felső bitet foglaljuk le a superpeer-ek számára. Így N csúcs esetén kb. $2^{k-m}N$ superpeer lesz. A $p$ kulcshoz tartozó superpeer a $p$ AND $\underbrace{11...11}_{k}\underbrace{00..00}_{m-k}$ kulcs felelőse lesz. \section{Konzisztencia} \noindent \textbf{Konfliktusos műveletek}: A replikátumok konzisztensen tartásához biztosítani kell, hogy az egymással konfliktusba kerülhető műveletek minden replikátumon egyforma sorrendben futnak le. Írás-olvasás és írás-írás konfliktusok fordulhatnak elő.\\ \noindent \textbf{Konzisztenciamodell}: A konzisztenciamodell megszabja, milyen módokon használhatják a folyamatok az adatbázist. Ha a feltételek teljesülnek, az adattárat érvényesnek tekintjük.\\ \noindent \textbf{Konzisztencia mértéke}: A konzisztencia többféle módon is sérülhet: eltérhet a replikátumok számértéke, frissessége, meg nem történt frissítési műveletek száma.\\ \noindent \textbf{Conit}: Az olyan adategység, amelyre közös feltételrendszer vonatkozik, a conit (consistency unit). \subsection{Soros konzisztencia} A feltételeket nem számértékekre, hanem írások/olvasások tényére alapozzuk. Jelölések: \begin{itemize} \item W(x) : x változót írta a folyamat \item R(x) : x változót olvasta a folyamat \end{itemize} Soros konzisztencia esetén azt várjuk el, hogy a végrehajtás eredménye olyan legyen, mintha az összes folyamat összes művelete egy meghatározott sorrendben történt volna meg, megőrizve bármely adott folyamat saját műveletinek sorrendjét. \begin{figure}[H] \centering \includegraphics[width=0.7\linewidth]{img/konz_soros} \caption{Példa: az (a) teljesíti, (b) nem a soros konzisztencia követelményeit.} \label{fig:konz_soros} \end{figure} \subsection{Okozati konzisztencia} A potenciálisan okozati összefüggésben álló műveleteket kell mindegyik folyamatnak azonos sorrendben látnia. A konkurens írásokat a különböző folyamatok különböző sorrendben láthatják. \begin{figure}[H] \centering \includegraphics[width=0.4\linewidth]{img/konz_okozati} \caption{Példa: a (b) teljesíti, (a) nem az okozati konzisztencia követelményeit.} \label{fig:konz_okozati} \end{figure} \subsection{Kliensközpontú konzisztencia} Azt helyezzük most előtérbe, hogy a szervereken tárolt adatok hogyan látszanak egy adott kliens számára. A kliens mozog: különböző szerverekhez csatlakozik, és írási/olvasási műveleteket hajt végre. Az $A$ szerver után a $B$ szerverhez csatlakozva különböző problémák léphetnek fel: \begin{itemize} \item Az $A$-ra feltöltött frissítések lehet, hogy nem jutottak még el $B$-hez. \item $B$-n lehet, hogy újabb adatok találhatóak, mint $A$-n. \item A $B$-re feltöltött frissítések ütközhetnek az $A$-ra feltöltöttekkel. \end{itemize} A cél az, hogy a kliens azokat az adatokat, amiket az $A$ szerveren kezelt, ugyanolyan állapotban lássa $B$-n is. Ekkor az adatbázis konzisztensnek látszik a kliens számára.\\ \subsubsection{Monoton olvasás} Ha egyszer a kliens kiolvasott egy értéket $x$-ből, minden ezután következő olvasás ezt adja, vagy ennél frissebb értéket. Például levelezőkliens esetén minden korábban letöltött levelünknek meg kell lennie az új szerveren is. \subsubsection{Monoton írás} A kliens akkor írhatja $x$-et, ha kliens korábbi írásai $x$-re már befejeződtek. Például verziókezelésnél minden korábbi verziónak meg kell lennie a szerveren, ha új verziót akarunk feltölteni. \subsubsection{Olvasd az írásodat} Ha kliens olvassa $x$-et, a saját legutolsó írásának eredményét kapja, vagy frissebbet. Például a kliens a honlapját szerkeszti, majd megnézi az eredményt. Ahelyett, hogy a böngésző gyorsítótárából egy régebbi változat kerülne elő, a legfrissebbet szeretné látni. \subsubsection{Írás olvasás után} Ha a kliens kiolvasott egy értéket $x$-ből, minden ezután kiadott frissítési művelete $x$-nek legalább ennyire friss értékét módosítja. Például egy fórumon a kliens csak olyan hozzászólásra tud válaszolni, amit már látott. \subsection{Tartalom replikálása} Különböző jellegű folyamatok tárolhatják a másolatokat: \begin{itemize} \item Tartós másolat: eredetszerver (origin server) \item Szerver által kezdeményezett másolat: replikátum kihelyezése egy szerverre, amikor az igényli az adatot \item Kliens által kezdeményezett másolat: kliensoldali gyorsítótár \end{itemize} \subsubsection{Frissítés terjesztése} Megváltozott tartalmat több különféle módon lehet kliens-szerver architektúrában átadni: \begin{itemize} \item Kizárólag a frissítésről szóló értesítés/érvénytelenítés elterjesztése. \item Passzív replikáció: adatok átvitele egyik másolatról a másikra \item Aktív replikáció: frissítési művelet átvitele \end{itemize} A frissítést kezdeményezheti a szerver (küldésalapú frissítés), ekkor a szerver a kliens kérése nélkül elküldi a frissítést a kliensnek, vagy kezdeményezheti a kliens, aki kérvényezi a frissítést a szervertől (rendelésalapú frissítés).\\ \noindent \textbf{Haszonbérlet (lease)}: A szerver ígéretet tesz a kliensnek, hogy átküldi a frissítést, amíg a haszonbérlet aktív. \end{document}