% !TeX root = ../thesis.tex
%----------------------------------------------------------------------------
\chapter{Alkalmazás komponensek dinamikus ütemezése}
\label{chapter:dynamic_scheduling}
%----------------------------------------------------------------------------

Az előző fejezetekben ismertetett, átalakított alkalmazások jól ki tudják használni a peremhálózati informatikai infrastruktúra adta lehetőségeket. Mint azt a \aref{sec:peremhalozati_rendszerek}.\ szekcióban is ismertettem a peremhálózati rendszerek a hagyományos adatközpontokkal szemben számos különbséget képviselnek. Egyik ilyen különbség a telepítésük sűrűsége. Ez a tulajdonsága lehetővé teszi, hogy a megvalósított alkalmazás szempontjából bizonyos szolgáltatásokat a felhasználókhoz \enquote{közel} futtasson. Ennek a \enquote{közelségnek} önmagában számos előnye tud lenni, mint például a csökkentett hálózati késleltetés és terhelés. Tipikusan a peremhálózati infrastruktúrákra jellemző, hogy a felhő végtelennek tűnő számítási kapacitásához képest erősen limitált erőforrások állnak rendelkezésre.

Könnyen beláthatjuk ezekből adódóan, hogy fontos szerepe van annak a kérdésnek, hogy egyes szolgáltatásokat mikor és melyik peremhálózati rendszeren futtatunk, vagy hogy megéri-e kihelyezni őket a felhő által nyújtott futtatókörnyezetből. Egy rosszul megválasztott szolgáltatás elhelyezés könnyen lehet, hogy az előnyök teljes ellentétét idézi elő megnövekedett költségek mellett. Mivel a peremhálózati rendszerek sokkal nagyobb számban állnak rendelkezésre és a helyes elhelyezés is kockázatos feladat, ezért az elhelyezési feladatokat minden esetben \enquote{kézzel} megoldani jelentős kihívást tud jelenteni.

Megoldást jelenthet a problémára ha az egyes szolgáltatás komponenseket automatikusan tudjuk peremhálózati infrastruktúrába kihelyezni. Egy olyan ütemező algoritmusra van szükség, amely képes kiválasztani az ideális futtatási helyet a megfelelő komponenseknek és automatikusan áthelyezni (azaz ütemezni) oda. Így nincs szükség emberi beavatkozásra a megfelelő peremhálózati adatközpont kiválasztásához.

A dinamikus ütemezés több kérdést és problémát is felvet, hiszen nem egyértelmű, hogy melyik alkalmazás szempontjából mi számít ideális környezetnek. Illetve ha tudjuk, hogy mi számít ideális környezetnek, hogy tudjuk felmérni, hogy melyik környezet lehet ideális jelölt az alkalmazás futtatására.

Ebben a fejezetben megvizsgálom a dinamikus áthelyezés megvalósításának lehetőségét a korábban ismertetett alkalmazásokon, illetve egy egyszerű megoldást is tervezek, amely a probléma megoldását mutatja be.

\section{Alkalmas felhős keretrendszer kiválasztása}
\label{sec:cloud_framework}


\Aref{sec:frameworks}.\ szekcióban több keretrendszert is megvizsgáltam. Ezek közül a \textit{KubeFed}-et választottam.

A kiválasztásnál elsősorban azt vettem figyelembe, hogy milyen lehetőségeket adnak az egyes keretrendszerek a szolgáltatások dinamikus átütemezésére felhő és perem, illetve perem és perem adatközpontok között.

A \textit{KubeFed} mellett a \textit{Kubeedge} volt a másik keretrendszer, amely ideálisnak tűnt, ám mélyebb vizsgálatot követően elvetettem. Ennek oka a korábban is ismertetett hiányosságai kezdetleges állapota volt. 

Az \textit{EdgeX Foundry} és \textit{Porject EVE} használatát korán elvetettem. Tipikusan erős különbségeket feltételeznek a perem és a felhő adatközpontokkal szemben támasztott elvárásoktól. Emiatt olyan megoldásokat kínálnak, amelyek teljesen más igényeket próbálnak kielégíteni, mint amiket az én eredeti problémafelvetésem támaszt. Emiatt ezeknek a megoldásoknak a használata csak felesleges nehézségeket jelentene.

A megvizsgált \acrshort{paas} rendszereket azért nem szerettem volna használni, mert célom volt egy teljesen nyílt megoldás készítése, ami nyílt szoftverekre épül és nem függ egy konkrét megoldástól. Továbbá így előfizetésre se volt szükségem.

A \textit{KubeFed} saját ütemezőt nem implementál (mint ahogy egyik másik vizsgált megoldás sem). Viszont az általa megvalósított egységes vezérlő felületnek köszönhetően nagyon könnyen képesek vagyunk az egyes komponenseket adatközpontokra mozgatni, így könnyen tudunk olyan saját ütemezőt készíteni, ami megvalósítja a feladatot. Emiatt választottam ezt a keretrendszert.

\section{Szolgáltatás létesítés és mozgatás \textit{KubeFed} környezetben}

Konténerizált alkalmazás környezetben egy futó konténer mozgatása csak korlátozott értelemben lehetséges. Mivel az alkalmazás nem egy virtualizált hardveren, hanem magán a hoszt operációs rendszeren fut egy konténerizált környezetben, így nincs egyszerű arra, hogy egy alkalmazást a memória tartalmával együtt mozgassunk, úgy, hogy az egy másik hoszton ugyan úgy tudja folytatni a működését. 

Ezért az áthelyezés az adott konténer leállítását és egy másik hoszton (másik klaszterben) való elindítását jelenti. Ez állapotmentes szolgáltatásoknál nem jelent nagyobb problémát, hiszen nincs belső állapot amit meg kell őrizni a mozgatás során. Belső állapottal rendelkező alkalmazások esetén viszont ez komplex problémát is jelenthet akár. 

Állapotmentes szoftverek esetén lehetőségünk van arra, hogy a konténerek \enquote{mozgatása} alatti kieséseket minimalizálhatjuk azzal, hogy az új konténereket előbb indítjuk el, mint hogy a régit leállítanánk. Ez idő alatt lehetőség van a még futó kéréseket befejeznie a leállítandó alkalmazásnak, miközben az új kérések már az újonnan indított alkalmazáshoz érkeznek. Egy ilyen átterheléses áthelyezés időbeni lefutását mutatja be \aref{fig:workload_move}.\ ábra. Ideális esetben egy ilyen mozgatás teljes mértékben szolgáltatás kiesés nélkül megoldható.

\begin{figure}[h!]
	\centering
	\includegraphics[width=0.7\textwidth]{figures/workload_move}
	\caption{Állapotmentes alkalmazás mozgatása \enquote{A} hosztról \enquote{B} hosztra.}
	\label{fig:workload_move}
\end{figure}

Az átterheléses mozgatás belső állapottal rendelkező alkalmazások esetén nem könnyen oldható meg, hiszen a belső állapot szinkronizálása komoly feladat és többnyire nem is oldható meg az alkalmazás közreműködése nélkül.


Az alkalmazások leállítását és másik klaszterben való elindítását a \textit{KubeFed} teljes mértékben támogatja. Az összes federált \acrshort{api} objektum esetén lehetőséget ad arra, hogy kiválasszuk, hogy melyik klaszterben hozza létre. De még arra is lehetőséget nyújt, hogy bizonyos tulajdonságait az objektumoknak klaszterre szabva változtassuk meg. 

Ezeknek a konstrukcióknak a segítségével az ütemező szoftvernek csak egy \acrshort{api} hívást kell intéznie a \textit{Kubernetes} \acrshort{api}-hoz és ezzel meg tudja változtatni az ütemezést. A fentebb vázolt átterheléses mozgatást magától nem tudja megvalósítani a \textit{KubeFed}, de megfelelő \acrshort{api} hívásokkal ez is megoldható.

\section{Alkalmazás komponensek dinamikus ütemezésének vizsgálata}

Egy alkalmazás komponens dinamikus ütemezésének megvalósítása nagyon sok esetben támogatást igényel az alkalmazástól. Annak eldöntése, hogy mikor ütemezzük a komponenseket, hova és mit nyerünk az ütemezéssel mind-mind az alkalmazás saját tulajdonságaitól és belső működésétől függ. 

Emellett a konkrét ütemezés megvalósítása is erősen függ az alkalmazás tulajdonságaitól működésétől.

A következőkben a korábban bemutatott alkalmazásokat fogom megvizsgálni abból a szempontból, hogy ezeket a problémákat, hogy lehet megoldani. Illetve milyen támogatásra van szükség az alkalmazástól.

\subsection{Intelligens madárhang felismerés}

Ebben az alkalmazásban a peremhálózati adatközpontba egy előszűrést megvalósító komponens kerül. Ennek a komponensnek a feladata, hogy a sok \acrshort{iot} eszköz által feltöltött hangminták által generált hálózati terhelést csökkentse azzal, hogy intelligens felismerést futtatva csak a releváns hangmintákat küldi tovább.

Ez a komponens állapotmentes, két kérés teljesítésének eredménye egymástól teljesen független. Ennek köszönhetően könnyen skálázható több példányra, hogy képes legyen nagy mennyiségű klienst kiszolgálni. Mivel a peremhálózati adatközpontokban -- a felhőhöz képest -- általában korlátozottan állnak csak rendelkezésünkre erőforrások, ezért nem tudjuk tetszőlegesen skálázni a feldolgozó szolgáltatásunkat. 

Előfordulhat olyan helyzet, amikor a peremhálózat kifogy a számítási kapacitásból. Ilyen esetben is szeretnénk legalább annyi terhelést megtartani a használt peremhálózati adatközpontban, amennyit az teljesíteni képes a fennmaradó terhelést pedig szeretnénk átütemezni egy másik peremhálózati adatközpontba vagy végszükségben a felhőbe. Ezzel annyi sávszélesség kihasználtságot spórolni, amennyire csak képesek vagyunk.

\subsubsection{Ütemezési döntés meghozása}

Ebben az alkalmazásban azt szeretnénk megvalósítani, hogy ha egy adatközpontban fogytán van a számítási kapacitás, akkor más adatközpontokhoz tudjunk fordulni a feladataink végrehajtásával. Ebből következik, hogy szükségünk van arra, hogy mérjük egy adatközpont terheltségét. 

A futó előszűrő szoftver komponens teljesítőképességéről egy jó jellemző a várakozási sorának hossza. \Aref{sec:prefilter_service_implementation}.\ szekcióban ismertetettek szerint a szolgáltatás fenntart egy várakozási sort, ahol a feldolgozásra váró adatokat állítja sorba. Ideális esetben, ha miden beérkező kérést időben el tud látni, akkor ennek a sornak a hossza stabil 1 körüli érték. Ha a szolgáltatás teljesítőképessége végéhez közeledik, akkor elkezdenek felgyűlni a feladatai, ezáltal a sorhossz monoton növekedésnek indul.

Szükség van támogatásra az előszűrő szolgáltatástól, hogy gyűjteni tudjuk a futó szolgáltatások belső sorhosszát.

\subsubsection{Ütemezés megvalósítása}

Mivel az előszűrő szolgáltatás állapotmentes működést valósít meg, ezért könnyedén lehet mozgatni az egyes adatközpontok között, illetve több példányban is futtatni egyszerre.

Az \acrshort{iot} eszközök egy előre beállított címre küldik a hangmintákat. Ez a cím az egyes adatközpontoknál más és más lehet. Mivel a szolgáltatásokat adatközpontok között mozgatjuk, ezért szükség van támogatásra a az eszközök részéről is, hogy dinamikusan meg tudjuk változtatni a küldés célját.


\subsection{Robot vezérlés}

A felhő alapú robotkarok alkalmazásánál a peremhálózati adatközpontba egy vagy több alacsony szintű mozgást vezérlő komponens kerülhet. Ezek egymással egy osztott memóriát megvalósító \textit{Redis} adatbázison keresztül kommunikálnak. Ezek a komponensek belső állapottal rendelkeznek. Létrehozásukkor megkezdik a hozzájuk rendelt \textit{program} letöltését és futtatását. Ha a \textit{program} véget ért, akkor a komponensek kilépnek.

\subsubsection{Ütemezési döntés meghozása}

Ebben az alkalmazásban annak a megállapítása, hogy milyen logika alapján lehet eldönteni, hogy hol futtassuk az alkalmazásunkat jelentősen egyszerűbb: A valósidejű vezérléshez az elérhető legkisebb késleltetést kell elérnünk. Ahhoz, hogy meg tudjuk állapítani, hogy melyik az a peremhálózati adatközpont, amely ilyen tulajdonságokkal rendelkezik, ismernünk kell a robotkarokat tartalmazó telephely és az összes számításba jövő peremhálózati adatközpont közötti késleltetést.

Ha ezt ismerjük, akkor egy egyszerű minimum függvényt használva, ki tudjuk választani az ideális futtatás helyét.

\subsubsection{Ütemezés megvalósítása}

A vezérlést megvalósító komponens belső állapottal rendelkezik. Futás közbeni átütemezése ezért nem megvalósítható. A robotkarok mozgatása nem engedhet meg kiesést, hiszen a vezérlés elvesztése akár katasztrofális következményekkel is járhat. A belső állapottal rendelkező komponensek áthelyezése kiesés nélkül viszont komplex feladat.

Mivel \aref{sec:edge_layer_plans}.\ szekcióban kikötöttük, hogy minden programnak biztonságos állapotba kell helyeznie a robotkarokat lefutása végén. Illetve ebből az ismert állapotból legyen képes megkezdeni a vezérlést, ezért lehetőségünk van arra, hogy két lefutás között helyezzük át a programot. 

Az áthelyezés így jelentősen leegyszerűsödik, hiszen csak arra van szükség, hogy a vezérlő komponenseket a megfelelő adatközpontban indítsuk el.

A vezérlést megvalósító szolgáltatás komponensek indításáért ebben az alkalmazásban külön szolgáltatás felel, ezért ez az a szoftverkomponens, amelynek támogatnia kell a dinamikus ütemezési döntések alkalmazását. 


\section{Ütemező rendszer}

Bár a két alkalmazás működése és igényei jelentősen eltérnek, szerettem volna egy olyan rendszert megalkotni, aminek segítségével mindkét alkalmazás ütemezése megoldható.

\subsection{Metrikák gyűjtése és felhasználása}

% bele van tolva influx db-be
% Az infulxdbj nagyon jó mert tud egy csomó midnent például deriválni

\subsection{Algoritmus}


%Egy ilyen algoritmusnak fel kell tudnia mérni azokat 

\subsection{Megvalósítás}


\begin{figure}[h!]
	\centering
	\includegraphics[width=0.5\textwidth]{figures/turbomemer-legit}
	\caption{asd}
	\label{fig:turbomemer}
\end{figure}

