Ugrás a tartalomhoz

Operációs rendszerek mérnöki megközelítésben

Benyó Balázs, Fék Márk, Kiss István, Kóczy Annamária, Kondorosi Károly, Mészáros Tamás, Román Gyula, Szeberényi Imre, Sziray József

Panem Kiadó

4.4. Elosztott szolgáltatások

4.4. Elosztott szolgáltatások

4.4.1. Jellemzők

Mint azt korábban láttuk, az elosztott rendszer hálózattal összekötött, elosztott szoftverrel felruházott autonóm számítógépek összessége. Ebben az architektúrában az elosztott szoftver két fő feladatot lát el: az aktivitások koordinálását és az erőforrások megosztását. Egy elosztott rendszer akkor teljesíti a vele szemben támasztott elvárásokat, ha a felhasználója egyetlen, integrált számítási eszközt lát, az elosztottság számára rejtve marad. Az alábbiakban áttekintjük azokat a jellemzőket, amik alapján egy elosztott rendszert minősíteni lehet.

4.4.1.1. Az elosztott rendszerek legfontosabb jellemzői

Az elosztott rendszerekkel szemben számos követelmény merül fel. Ezek közül a legfontosabbak:

  • erőforrás-megosztás,

  • nyitottság,

  • konkurencia,

  • skálázhatóság,

  • hibatűrés,

  • átlátszóság,

  • biztonság.

A továbbiakban részletesen elemezzük ezeket a követelményeket.

Erőforrás-megosztás

Az erőforrások osztott használata mindig jelentős szerepet töltött be a számítógépes rendszerek történetében. Ezt elsősorban gazdasági és rendszerszervezési okokra lehet visszavezetni. A hardver- és szoftverkomponensek fejlődése egyre finomabb megközelítést tett lehetővé az osztott erőforrás használathoz. Míg a ’60-as évekre elsősorban az időosztásos rendszerek voltak jellemzőek, ahol a hangsúly elsősorban a CPU osztott használatára helyeződött, addig a ’70-es évek elején megjelentek a többfelhasználós rendszerek, felvetve egyéb hardverberendezések, mint például a nyomtatók, lemezegységek és perifériák osztott használatának az igényét, ahol kényelmi és költségkímélő szempontok domináltak. A szoftvereszközök rohamos fejlődése szinte elengedhetetlenné tette a koncepcionális erőforrások, az adatok osztott használatát. Manapság komplex szoftverrendszer fejlesztése elképzelhetetlen osztott adat és program használat nélkül. A fejlesztőcsapat együtt használhatja a fejlesztőeszközöket, közvetlen betekintést nyernek egymás munkájába, sőt az osztott használat a bonyolult rendszerek karbantartását is megkönnyíti. A kereskedelmi alkalmazások egyre elterjedtebben alkalmazzák azt a megközelítést, hogy a felhasználók egyetlen aktív adatbázis osztottan használt adatobjektumaihoz férnek hozzá, ahelyett, hogy mindenhol egy-egy saját másolattal dolgoznának, így a kényelmes használat mellett lényegesen egyszerűbb a konzisztencia karbantartás is. A hálózati és elosztott alkalmazások egyre szélesedő területe, amikor a számítógépekkel együttműködő felhasználói csoportok hatékony munkavégzését támogatják. Ez elvezetett egy újfajta munkamódszer kialakulásához, az ún. számítógéppel támogatott együttműködő munkavégzéshez (Computer Supported Coope­rative Working – CSCW, amit groupware néven is ismernek), ahol egy adott nagy komplexitású feladat elvégzésén egyszerre párhuzamosan többen is dolgoznak, és a feladat megoldásához szükséges összes szoftverkomponenst (programokat, modelleket, adatelemeket, adatbázisokat) közösen, osztottan használják.

Míg a többfelhasználós rendszerekben az erőforrások osztott használata nyilvánvaló (egy rendszer, a kernel felügyeli az erőforrásokat), addig elosztott rendszerekben újfajta architektúrára, támogatásra van szükség. Ez az új elem az erőforrás-menedzser, aminek az a feladata, hogy biztosítsa egy adott erőforrás optimális és igazságos használatát. Az erőforrás felhasználói az erőforrás-menedzserrel kommunikálnak, tőle kérnek hozzáférést az erőforráshoz. Az utóbbi időben két elterjedt modellt alkalmaznak: a kliens–szerver-modellt és az objektummodellt.

A kliens–szerver-modellben a szerver egy adott erőforrás menedzsere, a kliensek kéréseken keresztül próbálják az erőforrást használni. Ennél a modellnél nagyon fontos, hogy a kliens–szerver kapcsolat mindig egy adott feladatra vonatkozik, egy másik feladatkörben a szerver is lehet kliens (egy má­sik szerver számára). Az általános modellben egy tetszőleges számítógép fut­tathatja a klienst és a szervert (kliens/szerver lehet azonos gépen is). Na­gyon fontos, hogy egy elosztott rendszerben egy adott típusú szolgáltatást egy­szerre több, egymással ekvivalens szerver is nyújthat, így meg kell különböztetni a szolgáltatást magától a szolgáltatást konkrétan nyújtó szervertől!

Egy rendszerben azonban nem lehet minden erőforrást ezzel a modellel kezelni, bizonyos erőforrásoknak lokálisnak kell maradni. Ezek közül a legfontosabbak a CPU, a memória és a lokális hálózat interfész. Ezeket tipikusan az operációs rendszer, a kernel kezeli.

Az objektum alapú modell hasonló az objektumorientált programozás modelljéhez. Itt minden osztott erőforrást egy objektumként modellezünk, az erőforrást bezárjuk az objektumba. Az objektumok egyedi azonosítókkal rendelkeznek, így mozgathatók. A szolgáltatáskérést egyszerűen az objektumnak küldött üzeneteken keresztül lehet megvalósítani. A modell előnye, hogy egyszerű, rugalmas keretet biztosít az erőforrások kezeléséhez, másrészt az osztott erőforrásokat azonos módon lehet kezelni.

Nyitottság

A nyitottság kérdése a rendszer bővíthetőségével foglalkozik. Alapvetően az elosztott modellben azzal a feltételezéssel élünk, hogy minden erőforrásból korlátlan mennyiség áll rendelkezésünkre (ha mégsem, akkor a rendszert zökkenőmentesen bővíthetjük). Ebből adódóan egy elosztott rendszerrel szemben természetes elvárás, hogy ha a rendszert valamilyen szempontból bővítjük (például újabb gépeket adunk hozzá, újabb szolgáltatásokat integrálunk, újabb szerverekkel bővítjük), akkor ne kelljen architekturális változtatásokat végrehajtani, a felhasználók elől a bővítés rejtve maradjon. A bővíthetőség egyaránt vonatkozik hardverelemekre (további perifériák, memória, kommunikációs interfész), illetve szoftverelemekre is (az operációs rendszer szolgáltatásai, kommunikációs protokoll, erőforrás-megosztó szolgáltatások). Így a nyitottság mértékét az határozza meg, hogy az új osztott erőforrásokat kezelő szolgáltatásokat mennyire lehet „folytonosan” hozzáadni a rendszerhez (működés megszakítása, illetve komponensek duplikálása nélkül).

Felmerül a kérdés, hogy hogyan lehet elérni a nyitottságot? Erre elég nehéz kimerítő választ adni, azonban egy elengedhetetlen feltételnek mindenféleképpen meg kell felelni: a főbb szoftver interfészeket nyilvánosságra kell hozni (publikálni kell). A korai rendszerek zártak voltak, mivel nem feleltek meg ennek az igen fontos feltételnek. Összefoglalva, a nyitott elosztott rendszerek főbb ismérvei:

  • a főbb (operációs rendszer) interfészek publikáltak,

  • egységes folyamatok közötti kommunikáció, publikált interfészek az osztott erőforrások eléréséhez,

  • eltérő HW/SW, de a publikált szabványokhoz igazodni kell.

Nyitottság szempontjából a később ismertetett Unix az azt megelőző rendszerekhez képest „nyitottabbnak” számít:

  • Az alkalmazásfejlesztők számára nyitottabb, mert hozzáférnek a rendszer által nyújtott összes szolgáltatáshoz.

  • A hardverforgalmazók és a rendszeradminisztrátorok számára is nyi­tottabb, mert az operációs rendszert viszonylag egyszerűen lehet bővíteni, könnyen hozzá lehet adni új perifériákat.

  • A szoftverforgalmazók és a felhasználók számára is nyitottabb, mert hardver-független. A szoftverfejlesztők olyan programokat írhatnak, amelyek módosítás nélkül futnak több hardverplatformon is. (Persze, mint azt később látni fogjuk, ez az állítás csak akkor igaz, ha adott UNIX változatra készülnek a programok, vagy azzal a feltételezéssel élnek, hogy az adott UNIX változat megfelel bizonyos később ismertetett szabványoknak.)

Konkurencia

A konkurencia és a párhuzamos végrehajtás természetesen vetődik fel az elosztott rendszerekben, mivel a felhasználók egymástól elkülönülő tevékenységeket végeznek, független erőforrások (is) megtalálhatók a rendszerben és a szerverfolyamatok külön számítógépeken is futnak. Ezen tevékenységek szétválasztása lehetővé teszi, hogy a feldolgozás párhuzamosan folyjon a különböző számítógépeken. Azonban nagy hangsúlyt kell fektetni az osztottan használt erőforrások hozzáférés szabályozására és frissítésére, a szinkronizációs sémákat gondosan meg kell tervezni, valamint biztosítani kell, hogy a konkurens végrehajtás biztosította előnyök nem tékozlódnak el egy rossz szinkronizációs séma miatt.

Ha a számítógép csak egyetlen processzort tartalmaz, és egyszerre több folyamatot szeretnénk futtatni, akkor a folyamatok végrehajtását össze kell fésülni, megfelelő támogatást biztosítva a folyamatok közötti váltáshoz, az adatszerkezetek mentéséhez és visszaállításához. Ebben az esetben a folyamatok koncepcionálisan úgy érzékelik, hogy párhuzamosan futnak. Ezt virtuális párhuzamosságnak nevezik. Ha egy gépben N processzor található, akkor N folyamat futhat valóban fizikailag is párhuzamosan. Ekkor, ha a folyamatok közel függetlenek, a gyorsulás az adminisztratív tevékenység idejét leszámítva majdnem N-szeres lehet. Azonban az esetek nagy részében együttműködő folyamatokkal van dolgunk, amelyek egymás eredményeit felhasználják, kommunikálnak egymással, így az N-szeres sebességnövekedés közel sem érhető el. Az elosztott rendszereknél sok számítógép kapcsolódik össze egy hálózaton keresztül. Amennyiben a folyamatok az egyes gépekre szétoszthatók, akkor hasonló a helyzet a többprocesszoros rendszerekéhez: a feldolgozás itt is jelentősen felgyorsítható. Ezen struktúrát tipikusan a gyakran használt szolgáltatások használják ki intenzíven. Például az állományszerverek nagy terhelésnek vannak kitéve egy elosztott rendszerben, ezért szokás több állományszervert is működtetni, méghozzá különböző gépeken. Így a rendszer szempontjából az állományszerver nyújtotta szolgáltatás a kliensei számára lényegesen felgyorsulhat. (Meg kell jegyezni, hogy a nagyteljesítményű szerverek ráadásul tipikusan többprocesszoros architektúrákon futnak, tovább javítva a szolgáltatás teljesítményét.)

Skálázhatóság

Az elosztott rendszerek eltérő méretűek lehetnek, kezdve a legkisebb, két gépből álló rendszertől a lokális hálózatra épített akár több száz gépet is magába foglaló rendszerig. A skálázhatóság fogalma azt jelenti, hogy amikor a rendszer méretét növeljük, akkor ne kelljen a rendszer architektúráját vagy a szoftver alkalmazásokat megváltoztatni. Egy rendszer tervezésénél figyelembe kell venni annak várható életciklusát, az esetleges felmerülő bővítési igényeket, és úgy kell kialakítani, hogy ezek az ésszerű igények radikális változtatás nélkül megvalósíthatóak legyenek.

Az elmúlt években tanúi lehettünk egy skálázhatósági problémának: pár évvel ezelőtt a budapesti telefonszámok még hatjegyűek voltak. A telefonok, illetve faxberendezések rohamos terjedésével azonban a hat számjegy kevésnek bizonyult, így át kellett térni a hétjegyű telefonszámokra, ami miatt a régi telefonszámok megváltoztak, vagyis a régi számok tulajdonosai a rendszer bővítése során radikális változtatást érzékeltek. A tervezésnél persze nem szabad átesni a ló túlsó oldalára, nem szabad irreális követelményekre tervezni, a praktikusságot, kényelmes használatot is szem előtt kell tartani. Valószínűleg egyetlen olvasónk sem repesne a boldogságtól, ha például 20 számjegyes telefonszámokat kellene használnia, holott az a közeljövőben biztosan nem fog skálázhatósági problémákhoz vezetni.

A skálázható rendszerekben azt az egyszerű tervezési filozófiát alkalmazzák, hogy semmilyen erőforrás nem korlátozott, ha a rendszer bővülésével valamilyen erőforrásnak mégis szűkében lennénk, újabbat adunk a rendszerhez. Például, ha az elosztott állományszolgáltatás lelassul, mert a szerver nem képes már tolerálható időn belül kiszolgálni a megsűrűsödött kéréseket, újabb állományszervert állíthatunk szolgálatba.

Hibatűrés

A számítógépes rendszerek bonyolultságukból adódóan néha meghibásodnak. Mivel a hardver- és szoftverhibák miatt hibás eredmények születhetnek, illetve a programok a feladataik elvégzése előtt is befejezhetik futásukat, így feltétlenül foglalkozni kell a hibatűrés megvalósításával.

A hibatűrő viselkedés megvalósításához mind hardverredundanciát (hardware redundancy) (redundáns komponensek alkalmazása), mind pedig szoftverfelépülést (software recovery) (olyan szoftverek alkalmazása, amik hibákból felépülnek, folytatják a helyes működést) alkalmaznak.

A hardver redundanciát gyakran meleg tartalék formájában valósítják meg, vagyis egy adott kritikus funkciót megvalósító berendezés mellett párhuzamosan működtetnek egy másik, azonos, vagy azonos funkciót nyújtó berendezést. Ennek a megoldásnak hátránya, hogy nagyon költséges, azonban számos kritikus alkalmazásnál a biztonsági szempontok dominálnak és megkövetelik a meleg tartalékot. Nagyon sok alkalmazásnál azonban ennek költségei megengedhetetlenek, más megoldásokat kell alkalmazni.

Az elosztott rendszerekben a redundancia finomabb szinten is tervezhető, például kritikus szerverek replikálhatók. Másrészt az elosztott rendszerekben a redundáns hardvert ki lehet használni nemkritikus tevékenységek végrehajtására, amíg nincs rá szükség.

A szoftverfelépülés megvalósításához, mint azt már korábban láttuk, olyan szoftver komponenseket kell tervezni, amelyek segítségével az állandó adatok meghibásodás észlelésekor visszaállíthatók, a számítások visszagörgethetők (recovery, roll-back).

Az elosztott rendszerek egy másik előnyös tulajdonsága, hogy hardver- hibák jelenlétében is nagyfokú rendelkezésre állást biztosítanak. Egy többfelhasználós rendszerben egyetlen hiba hatására majdnem minden esetben a rendszer elérhetetlenné válik az összes felhasználója számára. Ezzel szemben, amikor egy elosztott rendszerben meghibásodik valamelyik komponens, a hiba csak a meghibásodott komponensen folyó munkát érinti.

Átlátszóság (fizikai széttagoltság elrejtése)

Az átlátszóság (transparency) nem más, mint egy elosztott rendszerben a komponensek elosztott természetének elrejtése a felhasználó és az alkalmazásfejlesztő elől, hogy azok a rendszert egy egységes egészként, nem pedig független komponensek laza összességeként lássák. Ennek eléréséhez hálózati és kommunikációs, explicit menedzsment és integrációs technikákra van szükség. Az alábbiakban röviden vázoljuk a nyolcféle átlátszóság definícióját.

  • A hozzáférés átlátszóság (access transparency) lehetővé teszi a helyi és a távoli erőforrások azonos műveleteket használó, azonos módon történő kezelését.

  • A hely átlátszóság (location transparency) lehetővé teszi információs objektumok elérését azok helyének ismerete nélkül. A hozzáférés át­lát­szóságot és a hely átlátszóságot együttesen szokás hálózati átlátszóságnak (network transparency) nevezni.

  • A konkurencia átlátszóság (concurrency transparency) lehetővé teszi folyamatok konkurens együttműködését osztott információs objektumok használatán keresztül, anélkül, hogy azok zavarnák egymást.

  • A másolat átlátszóság (replication transparency) lehetővé teszi, hogy az információs objektumokból (a nagyobb megbízhatóság, jobb teljesítmény érdekében) több másolat is létezzen a rendszerben anélkül, hogy a felhasználó és a programok tudomást szereznének a másolatokról.

  • A hiba átlátszóság (failure transparency) lehetővé teszi a meghibásodások elrejtését, lehetővé téve a felhasználók és az alkalmazói programok számára, hogy a feladataikat hardver- vagy szoftverhibák jelenlété­ben is elvégezzék.

  • A vándorlási átlátszóság (migration transparency) lehetővé teszi az információs objektumok szabad mozgatását a rendszerben anélkül, hogy befolyásolnák a felhasználó, illetve az alkalmazói programok működését.

  • A teljesítmény átlátszóság (performance transparency) lehetővé teszi a rendszer átkonfigurálását, hogy a rendszer teljesítménye terhelésváltozáskor javítható legyen.

  • A skálázási átlátszóság (scaling transparency) lehetővé teszi a rendszer bővíthetőségét, a rendszer struktúrájának, illetve az alkalmazások algoritmusainak megváltozása nélkül.

A fenti átlátszóságok közül a két legfontosabb a hozzáférés és a hely átlátszóság, ezek megléte vagy hiánya van a legnagyobb hatással az elosztott erőforrások használhatóságára.

Az alábbiakban egy példát mutatunk a hálózati átlátszóság hiányára. A Unix jól ismert rlogin parancsával egy felhasználható beléphet egy megnevezett gépre. Itt máris sérül a hely átlátszóság, mert a gépet mindenképp meg kell nevezni. Továbbá az rlogin használatakor követett eljárás eltér a lokális gépre történő bejelentkezéstől, mivel a lokális gépre történő bejelentkezésnél a login programot a rendszer automatikusan futtatja, nem kell azt explicite meghívni. Ebből adódóan a hozzáférés átlátszóság sem teljesül. Egy átlátszóságot megvalósító rendszerben elképzelhető, hogy a felhasználó nem egy adott gépre, hanem egy domainbe lép be. Ekkor a felhasználó jogosultságot kapna az adott domain összes szolgáltatásának a használatához.

Ezzel szemben az elektronikus levelezés a hálózati átlátszóság tulajdonságát mutatja. Egy elektronikus levelezési cím, mint például roman@mit. bme.hu egy felhasználói és egy domain névből áll. A domaineket szervezeti struktúrák alapján definiálják és osztják ki. A felhasználókhoz egy adott domainen belül rendelnek levelezési nevet. Ha egy ilyen felhasználónak küldünk levelet, ahhoz nem kell ismernünk a felhasználó fizikai vagy hálózati helyét, illetve magának a levélküldésnek a folyamata is független a címzett helyétől. Ebből adódóan az Interneten történő elektronikus levelezés rendelkezik a hálózati átlátszóság tulajdonsággal.

4.4.1.2. Elosztott rendszerek tervezési szempontjai

Az előző alfejezetben áttekintettük az elosztott rendszerek hasznosságát leíró főbb jellemzőket. Ebben az alfejezetben az elosztott rendszerek tervezésénél figyelembe veendő legfontosabb tervezési szempontokat vizsgáljuk. Bár egy elosztott rendszer vagy alkalmazás tervezésénél számos olyan szempontot is figyelembe kell venni, ami nem kapcsolódik a rendszer elosztottságához, mint például szoftver mérnöki technikák, ember–gép-kapcsolat és algoritmus tervezés, az alábbiakban csak azokkal a tervezési szempontokkal foglalkozunk, amelyek kifejezetten a rendszer elosztott természetéből fakadnak. A továbbiakban az alábbi témaköröket tárgyaljuk:

  • megnevezés,

  • kommunikáció,

  • programstruktúra,

  • terheléskiosztás,

  • konzisztencia karbantartás.

Megnevezés

Ha egy folyamat olyan erőforráshoz akar hozzáférni, amit nem a folyamat maga felügyel, akkor meg kell neveznie az erőforrást. A továbbiakban név alatt egy olyan megnevezést értünk, amit az emberi felhasználók könnyen értelmezni tudnak, mindamellett programok is használhatnak, míg azonosító alatt csak programok által értelmezhető megnevezést értünk. Ebben az esetben tipikusan valamilyen kompakt ábrázolásmódot, bitmintát alkalmaznak.

Azt a folyamatot, amely során egy nevet leképeznek egy olyan alakra, ami lehetővé teszi az erőforrásokon való műveletvégzést, névfeloldásnak (name resolution) nevezzük. Elosztott rendszerekben a névfeloldás talán az egyik legfontosabb szolgáltatás, melynek során általában egy kommunikációs azonosítót állítanak elő. Például az Internetes kommunikációban a kommunikációs azonosító két részből áll: egy host azonosítóból és egy port számból.

Mivel a névfeloldás erősen befolyásolja az elosztott rendszer hatékonyságát, használhatóságát, így megválasztásánál nagyon körültekintően kell eljárni. A választásnál az alábbi ortogonális tervezési szempontokat kell figyelembe venni: egyrészt választhatunk véges vagy potenciálisan végtelen névteret, másrészt kialakíthatunk strukturált vagy lapos (egyszintű) névteret.

A nevek feloldása mindig valamilyen környezetben történik és a név feloldásához mindig meg kell adni azt a környezetet is, amiben a feloldást el kell végezni. Például az állományrendszer esetében minden egyes könyvtár egy környezetet jelent.

A nevek és azonosítók mindig a rendeltetésüknek leginkább megfelelő alakot öltik. Bizonyos neveket az emberek számára olvasható alakúra terveznek, hogy az emberi felhasználó könnyen eligazodjon közöttük. Az állománynevek, mint például ~roman/dokumentumok/konyv és a magasszintű hálózati nevek, mint például az Internetes domain nevek – például mit.bme.hu – ebbe a kategóriába esnek. Más neveket ezzel szemben úgy alakítanak ki, hogy azok tömör ábrázolásmódot biztosítsanak, helytakarékosak legyenek, esetleg az azonosított erőforrás elhelyezkedéséről áruljanak el valamit. (Meg kell jegyezni, hogy az utóbbi esetben sérül a hely átlátszóság.)

Nagyon elterjedten alkalmaznak hierarchikus névteret. Az egyik legjelentősebb előnye, hogy a név minden egyes része eltérő környezetben kerül feloldásra, így ugyanaz a név komponens többször is felhasználható. Ebből adódóan egy hierarchikus névtér potenciálisan végtelen névteret jelöl ki.

A megnevezési sémák kialakításánál figyelembe lehet venni védelmi szempontokat is. Ki lehet alakítani olyan névteret, amely már a név megválasztásával véd a jogosulatlan használat ellen. Ennek leggyakoribb módja, hogy olyan azonosítót alkalmaznak, aminek az előállítása számításigényes olyan folyamatok számára, amelyek azt nem birtokolják. A számításigény annyira megnövelhető, hogy ezáltal praktikusan lehetetlenné válik jogosulatlan nevek megszerzése azok véletlen generálásával.

Kommunikáció

Egy elosztott rendszer komponensei mind logikailag, mind pedig fizikailag széttagoltak, együttműködésükhöz kommunikációra van szükség. Egy fo­lya­matpár közötti kommunikáció a küldő és a fogadó folyamatok olyan műveleteit foglalja magába, aminek eredményeképp adatátvitel jön létre a küldő folyamat környezetéből a fogadó folyamat környezetébe és szinkronizáció valósul meg a két folyamat között. A kommunikációt két alapvető programo­zás­technikai primitív, a send és a receive (küldés és fogadás) valósítja meg. A kommunikáció ebben a sémában üzenetküldésen alapszik. A kommunikációs mechanizmus, mint azt korábban láttuk, lehet szinkron vagy blokkolódó, vagyis a küldő folyamat bevárja az üzenet vételét, vagy aszinkron vagy nem blokkolódó, vagyis a küldő folyamat továbbhalad anélkül, hogy megvárná az üzenet fogadását.

A továbbiakban megvizsgálunk három kommunikációs sémát: a kliens–szerver sémát, a csoportos multicastot és a függvényszállítást.

Kliens–szerver séma

A kliens–szerver kommunikációs modellt szervizek nyújtására dolgozták ki. A kommunikáció három lépésből tevődik össze:

  • A kliens elküldi a kérését a szervernek.

  • A szerver elvégzi a kliens számára a kért műveletet (szolgáltatást).

  • A szerver elküldi a választ a kliensnek.

A kliens–szerver kommunikációs sémát meg lehet valósítani a send és receive primitívekkel, azonban azt nagyon gyakran nyelvi szintre emelve távoli eljáráshívásokkal valósítják meg. Ennek részleteit a későbbiekben ismertetjük.

A kommunikáció során leggyakrabban az ún. Request-Reply protokollt használják, erre optimalizálják a kommunikációt. (A kérés tartalmaz egy kommunikációs azonosítót, ahová a választ a szervernek vissza kell küldeni.)

Mint azt korábban láttuk, az elosztott rendszereknél a rendszer nyíltsága nagyon fontos követelmény. A szerverek és az általuk nyújtott szolgáltatások könnyű bővíthetősége és integrálhatósága érdekében a szerverekhez dinamikusan kell az azonosítókat hozzárendelni. Ennek legelterjedtebb módja, hogy a rendszerben működik egy (vagy több) név szolgáltatás, ahová az új szervereknek be kell jelentkezni, regisztrálni kell. A szerver regisztráció­kor kap egy azonosítót. A kliensek a szerver azonosítóját a név szolgáltatótól kapják meg.

Csoportos multicast

A csoportos multicasting esetén a folyamatok szintén üzenetküldéssel kommunikálnak, azonban ebben az esetben az üzenetet nem egyetlen folyamatnak, hanem egy folyamatcsoportnak küldik el. Egy csoportos üzenetküldéshez a csoport minden egyes folyamatának egy üzenet fogadása kapcsolódik. Szokás megkülönböztetni a broadcastot (üzenetszórás) a csoportos mul­ticasttól. Az üzenetszórást elterjedten használják a lokális hálózatoknál. Ek­kor az üzenetet mindenki megkapja, aki a hálózathoz kapcsolódik. A csoportos multicast ezzel szemben valamilyen logikai csoportosítás alapján szelektál ebből a sokaságból.

A csoportos multicast használatát az alábbi motivációk támasztják alá:

  • Objektumok megkeresése. (Például ha több állományszerver van a rend­szerben, és keresünk egy állományt, akkor csoportos multicastot küldhetünk a szervereknek, és csak az válaszol, aki tárolja a keresett állományt.)

  • Hibatűrés. (Például a kliens a kérését nemcsak egyetlen szervernek küldi el, hanem szerverek egy csoportjának. Ha a szervercsoport vala­melyik szervere meghibásodik, akkor egy másik szerver nyújtja a kért szolgáltatást.)

  • Többszörös frissítés. (Esemény értesítésre szolgálhat. Például egy pontos idő szolgáltató adott időközönként „szétsugározhatja” a pontos időt másodlagos idő szolgáltatóknak „most 17:00 az idő” jellegű üzenetekkel.)

A hálózati hardver nem biztos, hogy támogatja a csoportos multicastot. Ebben az esetben szoftverből, az üzenetek szekvenciális elküldésével lehet csoportos multicastot megvalósítani.

Függvényszállítás

Tulajdonképpen a függvényszállítás tekinthető a kliens–szerver-modell egy speciális esetének is. Míg a kliens–szerver-modellben tisztán adatok áramolnak (bár az első üzenet azt határozza meg, hogy a szerver mit is hajtson végre a kliens számára), addig a függvényszállítás esetén utasításblokkok, eljárás definíciók is mehetnek az üzenetekben, a szerveren interpreter értelmezi azokat. Ezzel a technikával a szerver képességei dinamikusan bővíthetők, egy speciális feladat megoldására „kiképezhető”. A függvényszállítás legismertebb példái a postscript nyomtatók és például a Sun NeWs ablakozó rendszer.

Programstruktúra

A centralizált számítógép-rendszerek operációs rendszerét gyakran nevezik monolitikusnak, mert az általuk nyújtott absztrakciókat egy mereven lezárt interfész biztosítja, mint például a Unix-rendszerhívás interfésze. Ezzel szemben az elosztott rendszerekben az alkalmazói programok számos szolgáltatást érhetnek el, amelyek mind a saját interfészüket biztosítják a bezárt erőforrások eléréséhez. Mivel az elosztott rendszereknél a nyitottság kulcs- szerepet tölt be, így azok számára egy merev, lezárt interfész alkalmatlan.

A centralizált és az elosztott rendszerek réteg struktúrája eltérő képet mutat. A 4.6. ábra mutatja a centralizált rendszerek rétegstruktúráját.

4.7.ábra. táblázat - Elosztott rendszerek réteg struktúrája

Alkalmazások

Programnyelvi támogatás

Operációs rendszer

Hardver


Mint az jól látszik, a négy réteg – a hardver, operációs rendszer, a programnyelvi támogatás és az alkalmazások – egymásra épülnek. Minden két réteget egy határfelület választ el, a felsőbb rétegek csak az alattuk lévő rétegek szolgáltatásain keresztül érhetik el az alsóbb rétegeket. Ebben az elrendezésben az operációs rendszer a fő szoftverréteg. Az operációs rendszer kezeli a legfontosabb erőforrásokat és fontos szolgáltatásokat biztosít az alkalmazások és a felhasználók számára. A főbb feladatok magukban foglalják a memóriaallokációt és -védelmet, a folyamatok létrehozását és a processzor ütemezést, a periferiális berendezések kezelését, a felhasználó hitelesítést és hozzáférés szabályozást, az állomány kezelést, az óra szolgáltatásokat stb.

Ezzel szemben az elosztott rendszerek eltérő rétegszerkezetet mutatnak (4.7. ábra).

4.8.ábra. táblázat - Az RPC-üzenetek felépítése

Alkalmazások

 
   
   
 

Elosztott programozási támogatás

Nyílt szolgáltatások

     

Operációs rendszer kernel szolgáltatások

 

Számítógépes és hálózati hardver

 

Itt már nem csak két szomszédos réteg található, illetve az operációs rendszer feladatai az alapvető erőforrások – a memóriaallokálás és -védelem, a folyamatok létrehozása és processzor ütemezés, a folyamatok közötti kommunikáció és a periferiális berendezések kezelése – kezelésére korlátozódnak.

A nyitottság itt azt jelenti, hogy az elosztott rendszereket egy adott felhasználói kör vagy alkalmazási kör igényeinek megfelelően lehet konfigurálni.

Terhelés szétosztás

Egy centralizált rendszerben a rendelkezésre álló számítási és memória erőforrásokkal az operációs rendszer a pillanatnyi terhelésnek leginkább megfelelő módon gazdálkodik. Az elosztott rendszerek legegyszerűbb architektúrájában munkaállomások kapcsolódnak össze egy lokális hálózattal, és ehhez a hálózathoz kapcsolódnak még különböző szerverek, mint például állomány szolgáltatók, nyomtató szolgáltatók stb. Ebben a struktúrában a munkaállomások képviselik a számítási kapacitást. Ezt a modellt szokás munkaállomás-szerver modellnek nevezni. Mint azt majd a későbbiekben látni fogjuk, a felhasználói kezelői felület konzisztencia szempontjából előnyös, ha az erősen interaktív alkalmazások feladatai magán a munkaállomáson futnak, amely képernyője előtt ül a felhasználó, mivel így a hálózati késleltetés kiiktatható. Ezt a munkaállomás-szerver modell hatékonyan tudja megvalósítani. Nyilvánvaló azonban, hogy az egyszerű munkaállomás-szerver modell nem optimális a rendszerben található számítási és memória erőforrások kihasználása tekintetében, továbbá nem teszi lehetővé, hogy egyetlen, nagy számítás- és memóriaigényű feladatokat futtató felhasználó további számítási és memória-erőforrásokra tegyen szert.

A rendelkezésre álló számítási kapacitás jobb kihasználását célozza a munkaállomás-szerver modell módosításán alapuló processzor pool modell. A modell elsődleges célja, hogy a rendelkezésre álló számítási kapacitást dinamikusan, az igényeknek megfelelően ossza szét a felhasználók között. Ebben a modellben akár egyetlen felhasználó is használhatja a processzor pool nyújtotta teljes számítási kapacitást, így nagy rugalmasságot biztosítva a számítási kapacitás rendszeren belüli felhasználásában. A processzor pool modellt támogató elosztott rendszerek egy munkaállomás rendszerből állnak, amihez hozzácsatoltak egy vagy több processzor poolt. A processzor pool elemei alacsony költségű számítógépek, gyakran nem tartalmaznak mást, mint egy processzort, memóriát és hálózati csatolót. A költségkímélés miatt gyakran ezek a számítógépek egyetlen alaplapra vannak integrálva és osztoznak egy közös tápegységen. A modell segítségével a felhasználók kis hardver erőforrásokkal rendelkező számítógépeken, sőt hálózati terminálokon – mint például az X terminálok is végezhetnek hasznos munkát, hisz a processzor pool nyújtotta számítási kapacitás a rendelkezésükre áll. Ekkor a felhasználó munkaállomása vagy terminálja csak eszközt biztosít a pool számítási kapacitásának kihasználásához. Mint láttuk, ezen modell járulékos hardver elemeket igényel. Egy munkaállomás-szerver modellben a tétlen, kihasználatlan számítási kapacitással rendelkező munkaállomások fölös kapacitását a munkaállomás-szerver modell szoftver kiterjesztésével hasznosítani lehet. Ez nem igényel járulékos hardver elemeket, azonban a terhelés szétosztás gondos körültekintést igényel az azt megvalósító szoftver rendszertől.

Meg kell itt említenünk, hogy a manapság rendelkezésre álló ún. osztott memóriás multiprocesszoros számítógép rendszerek hatékonyan alkalmazhatók mindkét fent ismertetett modell megvalósítására, különösen nagy számításigényű, több processzorra szétosztható feladatok megoldására. Ilyen feladatok gyakran jelentkeznek leterhelt szerverek esetén, ott tág tér nyílik ezen architektúra alkalmazása számára.

Konzisztencia-karbantartás

Az elosztott rendszerekben a számítási erőforrások széttagoltsága miatt fokozottan kell foglalkozni a konzisztencia kérdésével. Az alábbiakban áttekintjük az elosztott rendszerekben felmerülő különféle konzisztencia­problé­mákat.

A legfontosabb konzisztenciatípusok:

  • frissítés konzisztencia,

  • másolat konzisztencia,

  • cache konzisztencia,

  • hiba konzisztencia,

  • óra konzisztencia,

  • felhasználói interfész konzisztencia.

Frissítés konzisztencia

A frissítés konzisztencia nem csak az elosztott rendszereknél jelentkezik. A probléma számos olyan alkalmazásnál felmerül, ahol osztott adathasználatra van szükség. A legkézenfekvőbb ilyen alkalmazások az adatbázis kezelő alkalmazások. Az elosztott rendszereknél azonban kiemelten foglalkozni kell a frissítés konzisztenciával, mivel egy elosztott rendszerben nagy valószínűséggel nagyon sok felhasználó fér hozzá az osztottan használt adatokhoz (például egy elosztott állományrendszerhez), másrészt magának a rendszernek a működése függ bizonyos adatbázisok konzisztenciájától. A rendszerben tehát biztosítani kell, hogy összetartozó adatok változását a folyamatok atominak, azonnal végbemenőnek érzékeljék, annak ellenére, hogy technikailag a változások bizonyos időintervallum alatt következnek be.

Másolat konzisztencia

Egy fontos adatforrásról másolatok készítése és a másolatok, replikák használata elterjedt módszer az adatbázisok területén. A másolatok használatának hatékonysági előnyeit az elosztott rendszerekben is kiaknázzák. Azonban a másolatok készítése és használata (amennyiben a másolatokat az egyes felhasználók módosíthatják) magában hordozza az inkonzisztencia veszélyét. Mivel az adatok egy közös forrásból származnak, így a másolatoknak, replikáknak minden pillanatban azonosaknak kell lenniük. Ezt az azonosságot elég nehéz biztosítani, mivel az elosztott rendszerben az információ átadásra egy kommunikációs hálózatot kell használni, ami a fizikai széttagoltság miatt eltérő késleltetéseket jelent az egyes komponensek felé. Egy tipikus másolat inkonzisztencia típus, amikor az információt hordozó üzenetek eltérő sorrendben érkeznek be az egyes rendszer komponensekhez, akár a logikai ok-okozat sorrendet is felborítva. Az Internet netnews tipikus példája a másolat inkonzisztenciának. Itt előfordulhat, hogy egy hírcsoportnak küldött üzenet bizonyos csomópontokra inkonzisztens sorrendben érkezik meg – a kérdésekre adott válaszok gyakran hamarabb megérkeznek, mint maga a feltett kérdés.

Cache konzisztencia

A cache-elési technikák minden számítógépes rendszerben, így az elosztott rendszerekben is kulcsszerepet töltenek be. Nélkülük számos elosztott szolgáltatás hatékonysága elfogadhatatlan lenne. Például, ha egy folyamatnak minden egyes alkalommal igénybe kellene vennie a név feloldási szolgáltatást, ahelyett, hogy a helyi cache-ben keresné ki a kérdéses információt, akkor a rendszer működése szinte elfogadhatatlanná válna. Azonban ez a helyzet nagyon hasonlít a másolat konzisztenciánál vázolt helyzethez. Amenynyiben a cache-ben tárolt globális adatot egy másik folyamat, csomópont módosítja, akkor a helyi cache-ben tárolt információ érvénytelenné válik. Ezért biztosítani kell valamilyen mechanizmust, amivel a helyi másolatokat frissíteni lehet. Tipikus megoldás, hogy a szerver tárolja, hogy egy adott adatelemet mely csomópontok kérdeztek le, így mely csomópontok lokális cache-ében találhatók meg nagy valószínűséggel. Amikor az adott adatelem módosul, a szerver egy üzenetet, értesítést küld az összes érintett csomópontnak.

Hiba konzisztencia

Egy centralizált számítógép rendszer meghibásodása esetén az azon futó fo­lyamatok egyformán érzékelik a hibát, egyszerre hibásodnak meg – ilyen rendszerekben egyetlen hibamód jelentkezik. Elosztott rendszerekben ha egy komponens meghibásodik, akkor a többi komponens folytatja futását, még azok is, amik a meghibásodott komponenssel együttműködtek. Ha azonban az együttműködő komponensek, folyamatok a későbbiekben függnek a meghibásodott komponens további működésétől, akkor valamilyen későbbi időpontban ezek is meghibásodhatnak. Ebből adódóan eltérő fázisban történhetnek újabb meghibásodások. Ez az elosztott rendszerek többszörös hibamódja. Az együttműködő programok eltérő pontot érhetnek el a meghibásodásig. Ahhoz, hogy biztosítani lehessen, hogy az összes program által tárolt állandó adatok konzisztensek maradjanak, a meghibásodás után felépülési eljárásokkal az állandó adatokat vissza kell görgetni valamilyen ismert, konzisztens állapotba.

Óra konzisztencia

Az alkalmazásokban és rendszer szoftverekben alkalmazott algoritmusok jelentős része időbélyegeket alkalmaz, konzisztens működésük függ az időbélyegekbe foglalt idő információ konzisztenciájától. Centralizált rendszerben ez nem jelent problémát, mert az egy gépen futó folyamatok ugyanazon idő szolgáltatótól – ebben az esetben a rendszer órájától – szerzik be az idő információt. Egy elosztott rendszerben azonban minden folyamat a saját gépnek az óráját használja. Sajnos ezek az órák nem szinkronban járnak, így elosztott rendszerekben a fizikai idő kezelése problémát okozhat. A problémát a számítógépek közötti információküldés véges sebessége és az egyes gépek közötti eltérő mértékű kommunikációs késleltetés okozza. A konzisztencia biztosítása érdekében az órákat időről-időre valamilyen módszerrel szinkronizálni kell. Ezek az algoritmusok figyelembe tudják venni a hálózati késleltetést és számos alkalmazás számára kellő pontosságú idő információt tudnak biztosítani.

Szerencsére egy elosztott rendszerben számos esetben nem az abszolút idő pontos ismeretére van szükség, hanem események, mint például állományok frissítésének ideje, relatív sorrendje a fontos. Ezen problémára kidolgozták a logikai órákat, amik segítségével az esemény sorrendezés problémája kezelhető az elosztott rendszerekben.

Felhasználói kezelői felület konzisztencia

Ez a probléma elsősorban elosztott környezetben futtatott interaktív feladatokra vonatkozik. Ergonómiai mérések azt támasztják alá, hogy az ember 0,1 másodperces késleltetést még nem érzékel megszakításnak. Így az interaktív rendszerekben a válaszidőt ez alatt a határ alatt kell tartani. Elosztott rendszerekben, ahol a kezelői felületen végrehajtott változások gyakran valamilyen távoli számítási csomóponton indítanak műveleteket, ez szigorú megkötést jelenthet. Az interaktív késleltetés a felhasználói beavatkozás szerverhez történő elküldésének, feldolgozásának, a válasz visszaküldésének és a képernyő állapotának megváltoztatásához szükséges idők összege. Amennyiben a hálózati késleltetés jelentős, akkor a felhasználó érzékeli az elosztottságot, a rendszer nem lesz átlátszó. Ezen probléma kezelésére is gyakran alkalmazzák a cache-elési technikákat.

4.4.2. Elosztott fájlrendszerek

Az elosztott fájlkezelés a helyi operációs rendszer fájlkezelési szol­gál­ta­tá­sai­nak kiterjesztése számítógép hálózaton keresztül kap­csolódó számítógépekre.

Az elosztott fájlrendszer felhasználói a rendszert alkotó gépeken található fájlokat használják a fájl pontos helyének ismerete nélkül. A fájl lehet helyi (local), azaz a felhasználó számítógépéhez kapcsolódó valamelyik háttértáron elhelyezkedő, illetve távoli (remote), azaz egy másik számítógéphez csatolt periférián található. Ideális esetben a fájl tényleges elhe­lyezkedése a felhasználó előtt rejtve van.

Az elosztott fájlrendszer az elosztott rendszerek (distributed systems) tipikus alkalmazási példája. Elosztott rendszerek esetén a szolgáltatások hálózatba kötött számítógépeken úgy működnek, hogy a felhasználónak (és alkalmazásainak) nincs tudomása azok tényleges elhelyezkedéséről, illetve nem szükséges azt tudniuk, hogy mi módon építhető ki a kapcsolat saját kliens gépeik és a szolgáltatásokat üzemeltető szerver gépek között. (Ezzel ellentétben a hálózati modellben a hasonlóképpen elosztott szolgáltatások eléréséhez szükséges az elérési mód ismerete.)

4.4.2.1. Az elosztott fájlrendszer szolgáltatás

Elosztott fájlrendszerek esetén a fájlt tároló számítógép a szolgáltató, amely a többi csomópont, az ügyfelek számára szolgáltatásként műveleteket biz­tosít a fájljain. Az előző fejezetben ismertetett Telnet és FTP protokollok is lehetővé teszik a távoli fájl hozzáférést, illetve fájlok mozgatását a hálózatba kapcsolt gépek között, de egyrészt ezek használata külön tudást igényel, másrészt nem használják ki igazán a kliens gép operációs rendszere nyújtotta lehetőségeket. Az elosztott fájlrendszer egy olyan megoldás, amely a felhasználó és alkalmazásai számára a helyi hozzáféréssel azonos módon teszi lehetővé műveletek végrehajtását távoli állományokon.

Az elosztott fájlkezelést kezdetben a hagyományos operációs rendszerre épülő olyan szoftver réteg valósította meg, amely több operációs rendszer fájlkezelése között teremtett kapcsolatot. A korszerű elosztott operációs rendszerek integráns része az elosztott fájlkezelés.

Legelterjedtebb a UNIX operációs rendszer NFS (network file system) elosztott fájlrendszere, amely PC-alapú operációs rendszerekből is elérhető. Manapság egyre inkább terjed a PC-alapú rendszerekből kialakult másik elosztott fájlrendszer, az CIFS (Common Internet File System), amely az SMB (Server Message Block) protokollon alapszik.

A fájlokat egyedi nevük alapján azonosíthatjuk. A név a felhasználó elől elrejti a fájl elhelyezkedésének, tárolásának részleteit. Elosztott fájlkezelés ese­tén a névnek azt is el kell(ene) takarnia, hogy a fájl melyik számítógép háttértárján talál­ható.

4.4.2.2. Az állományok azonosítása

Az állományok azonosításánál két különböző szintet különböztetünk meg, a felhasználói szintű neveket, illetve a rendszerszintű fájlazonosítókat. A fájlkezelő feladata a kétszintű azonosító egymáshoz rendelése.

A fájlnevek és a fájlok a felhasználó számára átlátszó (transparent) egymáshoz rendelésénél két fogalmat külön­bözhetünk meg:

  • rejtett elhelyezkedés (location transparency): a fájl neve nem utal arra, hogy az melyik gépen található,

  • elhelyezkedés-függetlenség (location independence): a fájl neve nem változik meg akkor sem, ha a fájl átkerül egy másik gépre.

Szorosan ide tartozik a fájlok az elosztott rend­szer felü­gyelete alatti, kezdeményezésre történő vándorlásának (file mi­gration) fogalma.

Míg az első esetben a felhasználói nevek leképzése statikus táblázatok alapján történ­het, ad­dig az elhelyezkedés-független elnevezési rendszerben dinamikusan változó leképzési in­formációt kell használni. A jelenleg elter­jedt, kiforrott elosztott fájlkezelő rendszerek nem támogatják ezt a – lényegesen bonyolultabb – módszert.

Az elhelyezkedés-független nevek előnyei:

  • Az elnevezés elrejt minden, a fizikai tárolással kapcsolatos információt, a fájl az információtárolás teljesen absztrakt fogalma marad.

  • A fájlvándorlás lehetőséget nyújt arra, hogy az elosztott operá­ciós rend­szer a rendelkezésre álló teljes háttértár területet egységesen kezelje, a szabad területekkel rendszerszinten gazdálkodjon. Lehetőség van a háttértárak ki­használtságának dinamikus kiegyensúlyozására.

  • Az elnevezési rendszer szerkezete teljesen független a számítógépek összekap­csolódásának konkrét szerkezetétől, nem szükséges speciális fájlokat – például egy egységes könyvtár-struktúrában a gyökér könyvtárat – előre kijelölt csomópontokon tárolni.

4.4.2.3. Elnevezési módszerek

Az elnevezési rendszer feladata, hogy a fájlneveket leképezze konkrét csomó­pontra és azon belüli fizikai elhelyezkedésre.

  • Csomópont explicit megnevezése. A fájlokra hivatkozás két részre bontható: a csomópont meg­nevezése és a csomópont helyi fájlrendszerében a fájl neve; például a VMS operá­ciós rendszerben <csomópont név>: :<fájlnév>. Bár ez a fajta megnevezés nem felel meg a rejtett elhelyezkedés követelményének, hiszen a fel­használónak a hi­vatkozásban meg kell jelölnie a fájl konkrét helyét, ám a módszer a hálózati operációs rendszereknél töb­bet nyújt azzal, hogy a távoli fájlokon a helyi fájlokkal teljesen azonos műveletek végezhetők.

  • A távoli fájlrendszer a helyi könyvtár-hierarchia része. A távoli fájlrendszert – vagy annak egy részét – a helyi könyvtár-hierarchia egy pontjára csatlakoztatják (mount). Ehhez a művelethez meg kell nevezni a távoli gépet is, de ezután az ott lévő fájlok a helyi fájlokkal azonos módon kezelhetők. Ez a megoldás található például a UNIX operációs rendszerekben el­terjedt NFS (Network File System) rendszerben. A megoldás korlátozott érvényű – csak a távoli gépen felajánlott hierar­chiarészek láthatók – és egy bizonyos fájlra a hálózat különböző gépein különböző elérési útvonalon kell(het) hivatkozni.

  • A teljes elosztott rendszert lefedő egységes elnevezések: A fájlokra globális, a rendszer egészén érvényes nevekkel hi­vatkozhatunk.

A fentebb felsorolt leképzési módok táblázatok segít­ségével valósíthatók meg. Az implementáció lehetőségei és problémái:

  • Állománycsoportok szerinti leképzés. Ha a leképzési táblákban minden fájl szerepel, a táblák kezel­hetetlenül nagyokká válhatnak. Célszerűbb a fájlokat csoportokba (component units) szervezni és a leképzést ezekre a csoportokra együtt végezni. Például az NFS rendszerben ilyen cso­portnak tekinthetők a (távoli) könyvtárak, könyvtár-hierar­chiák.

  • Leképzési táblák többszörözése. A leképzési táblákban tárolt információhoz a rendszer minden csomópontja hozzá kell férjen. Ez megoldható egy központi nyilván­tartással is, de így ezt a nyilvántartást kezelő csomópont kiesése a rendszer szétesését vonja maga után. A táblázatok több­szörözésének in­dokai:

    • decentralizált, hibatűrő rendszer,

    • adatbiztonság,

    • a táblázatok gyors elérése.

  • Nem szükséges a teljes táblázatot a rendszer több csomópontján tárolni, elég lehet a táblázatok egy – a helyi rendszer számára szükséges – részének helyi átmeneti tárolása is (caching). A fájlok vándor­lásánál természetesen a leképzési táblákban tárolt információt minden másolatban aktualizálni kell.

  • Kétszintű leképzési táblák. A több leképzési táblában történő módosítást egyszerűsíti, ha bevezetünk elhe­lyezkedés-független alacsony szintű fájl azonosítókat. A „felső” szintű leképzés a felhasználói neveket ezekre az azonosítókra képzi le, amelyek tartal­mazzák azt, hogy a fájl melyik csoportba tartozik. Egy másik leképzési mechanizmus végzi el a csoportok csomópontokra történő leképzését.

Az elosztott fájlkezelés a fájloknak a rendszerben való megtalálásához szük­séges idő, a hálóza­ton történő megbízható adatátvitelhez szükséges információtöbblet és a nagyobb adminisztrációs teher mi­att óhatatlanul lassabb, mint a helyi fájlkezelés, de rejtett szolgáltatás esetén az elosztott fájlkezelés tel­jesítményének a hagyo­mányos fájlrendszerrel összehason­lítha­tó­nak kell lennie. Az elosz­tott fájlkezelés teljesítménye a következőképpen növelhető.

  • Speciális hardverelemekkel:

    • gyors kommunikációs csatornákkal,

    • a szolgáltatók nagy sebességű háttértáraival,

    • a szolgáltatók speciális architektúrájával, nagy központi táraival;

  • Szoftvermódszerekkel:

    • gyors, kevés kiegészítő információt tartalmazó kommunikációs pro­tokollokkal,

    • a szolgáltató operációs rendszerének, ütemezési algoritmusainak a fela­dathoz hangolásával,

    • a szolgáltatónál, illetve az ügyfélnél végzett átmeneti tárolással.

4.4.2.4. Az ügyfelek kéréseinek kielégítése

Miután a név alapján a rendszer megtalálta a hivatkozott fájlt, a fel­hasz­náló a fájlokon a helyi fájlkezelésnek megfelelő műveleteket akarja végezni. Ezt két elvileg különböző, a gyakorlatban gyakran összefonódó módon lehet elvégezni.

(a) Távoli szolgáltatásokon keresztül. A felhasználói műveletek mint kérések eljutnak a szolgáltató csomóponthoz, amely ezen kéréseket végrehajtja, majd az eredményt – amely lehet például a fájlban tárolt in­formáció, illetve a művelet végrehajtásának ered­ményessége – a hálózaton visszaküldi a kérőnek. A hálózaton a szolgáltatóhoz továbbított kérések pontosan megfeleltethetők a helyi fájlrendszer felé kiadott műveleteknek: írás, olvasás, létrehozás, törlés, át­nevezés, attri­bútumok lekérdezése, módosítása.

A távoli szolgáltatást tipikusan a távoli eljáráshívás mechanizmusára építve implementálják:

Minden, a fájlrendszernek szóló művelethez tartozik egy távoli eljárás. Az ügyfélfolyamatok a kívánt művelet paramétereit az eljárás paramétereibe írják, majd meghívják a megfelelő eljárást. A szolgáltató az eljárás visszaadott paramétereiben válaszol a kérésre.

A szolgáltatóban minden távoli eljáráshíváshoz tartozik egy speciális „démon” (daemon) folyamat, amely feladata, hogy a különböző kliensek felől érkező kéréseket kiszolgálja. A folyamat egy hozzá rendelt kaput (portot) figyel, ha ott egy kérés érkezett, a szükséges műveletet végrehajtja, majd a választ a kérésből megál­lapít­ható feladónak küldi vissza. (Az ügyfél folyamat és a démon között aszimmetrikus megnevezésen ala­puló kommunikáció valósul meg. Az ügyfélnek meg kell neveznie egy kaput, és ezzel a hozzá tartozó démont, a démon azonban bárkitől elfogad kéréseket.)

(b) Helyi átmeneti tárak segítségével. Az elosztott fájlrendszer teljesítményének növelésére, a hálózati adat­forgalom csökkentésére a helyi gépek a szükséges fájlokat, illetve azok részeit átmeneti­leg tárolják, a kí­vánt műveleteket azon végzik. A módszer elve azonos a virtuális tárke­ze­lésnél megismert átmeneti tárkezeléssel (caching):

ha szükséges, az új információnak helyet csinálunk,

a szükséges információt a hálózaton keresztül az átmeneti tárba töltjük,

a műveleteket a helyi másolaton végezzük,

változás esetén a módosult információt visszaírjuk a távoli gépre.

A távoli eljáráshívás speciális problémái

  • A hálózati kommunikáció nem megbízható. A fájlkezelő rendszernek vi­gyáznia kell arra, hogy minden kérést pontosan (legfeljebb) egyszer hajtson vég­re. A megoldáshoz a kéréseket az ügyfelek sorszámozzák – időbélyeget (time stamp) fűznek hozzá –, a szolgáltató az egyszer már kiszolgált kéréssel azonos sorszámú következő kéréseket elhanyagolja.

  • Az ügyfél programokban a távoli eljárásokat a szolgáltató megfelelő kapu­ira kell leképezni, ahol a kívánt démon várakozik. A leképzés lehet

    • statikus, minden művelethez előre kijelölt kapu tartozik,

    • dinamikus, műveletenként a megfelelő kapu számát egy speciális, mindig egy kötött kapuban ücsörgő démonnak, a házasságközvetítőnek (matchmaker) küldött kérésre adott válaszból kapjuk.

A helyi átmeneti tárak alkalmazásának problémái

  • Az átviteli egység méretének meghatározása. A gyakorlatban a különböző rendszerek a háttértár egy blokkjától teljes fájlokig különböző méretű egységekben végzik az átvitelt.

Fi­gyelembe kell venni

    • a rendelkezésre álló átmeneti tár méretét, (ne legyen túl kevés blokk benne),

    • az alapszintű hálózati protokoll, illetve az RPC mechanizmusában megengedett blokkméretet.

  • Hol legyen az átmeneti tárolás?

    • Általában a helyi gép központi tárában; ez gyors megoldás és hát­tértár nélküli rendszerekben is alkalmazható.

    • A helyi gép háttértárán; ami megbízhatóbb, hiszen a helyi gép katasztrófája után is megmarad az átmeneti tárban lévő információ, vagy teljes fájlok egy időben történő másolásánál a központi tár ezeknek a tárolására már nem elegendő.

  • A változások érvényre juttatása (update). A helyi másolaton végzett módosításokat a szolgáltatóval közölni kell. Ez történ­het:

    • azonnal; lassú, de biztonságos(abb) módszer,

    • késleltetve (delayed write); gyors, de a helyi rendszer esetleges katasztrófája miatt nem biztonságos megoldás.

Az írás történhet:

    • ha szükség van az átmeneti tárban helyre,

    • időközönként,

    • a fájl lezárásakor.

  • Az átmeneti tár konzisztenciája. Ugyanazt a fájlt az elosztott rendszerben több ügyfél használhatja egy­szerre, amennyiben valamelyik a fájlt megváltoztatja, a többi ügyfél má­solata már nem aktuális. A másolat felújítása történhet

    • az ügyfél kezdeményezésére (az ügyfél, ha „gyanakszik”, kérheti a szolgáltatótól annak ellenőrzését, hogy a saját másolata helyes-e),

    • minden hozzáférésnél,

    • a fájl újra megnyitásánál,

    • időközönként,

    • a szolgáltató kezdeményezésére.

A szolgáltató nyilvántartja összes ügyfeléről, hogy azok mit tárolnak helyileg (speciális üzeneteket igényel az ügyfelektől), ha a fájljaiban olyan változás van, amely valahol inkonzisztenciát okoz, értesíti az ügyfeleket. Az, hogy a szolgáltató mikor értesíti az ügyfelet arról, hogy a máso­lata ér­vényte­len, a rendszerben megvalósítandó elosztott fájlkezelési stratégia (con­sis­tency semantics) függvénye: történhet azonnal vagy csak akkor, amikor a fájlt a módosító lezárja. Amennyi­ben a szolgáltató értesül arról, hogy az ügyfelek mikor és milyen műveletekre nyitnak meg egy fájlt, előrelátható prob­lémák esetén már megnyitáskor üzenhet az ügyfélnek, hogy ne al­kalmazzon helyi tárolást, hanem használja a távoli szolgáltatásokat.

A két módszer összehasonlítása

Az átmeneti tárolás előnyei:

  • a műveletek jelentős része helyben végrehajtható, az ügyfél programjai lényege­sen gyor­sabban futhatnak, csökken a hálózat, illetve a szolgáltató terhelése,

  • nagy blokkok egyszerre történő átvitele viszonylag gazdaságosabb, mert

    • a hálózati protokoll a blokk méretéhez képest kevesebb többletinfor­mációt je­lent,

    • a szolgáltató lemezműveletei is gyorsulhatnak, ha egyszerre nagy blokkok átvitelét kérjük.

A távoli szolgáltatás előnyei:

  • nincs konzisztencia probléma, hiszen a fájl egyetlen példányát a szolgál­tató kezeli. A konzisztencia biztosítása bonyolult algoritmusokat, hálózati több­letforgalmat igényelne,

  • ott is működik, ahol az ügyfél erőforrásai nem teszik lehetővé az átmeneti tárolást,

  • a távoli szolgáltatások elérésének felülete megfelel a helyi fájlkezelő szolgál­tatások igénybevételének módjával.

4.4.2.5. A szolgáltató implementációja

  • Állapotot tároló (stateful) szolgáltató. A szolgáltató az ügyfelek kéréseiről, kiszolgálásuk folyamatáról, álla­potáról a saját központi tárában információkat tárol. Az új fájlok megnyitásáról értesül, és ehhez egy kapcsolat-leírót készít, amellyel a lezárásig nyomon követi az átvitelt. Előnyei:

– nagyobb teljesítmény,

– a fájlokhoz való egymás utáni hozzáférések már egy előkészített fájlra hivatkoznak,

– szekvenciális olvasás esetén a szolgáltató előre olvashat,

– az ügyfelek átmeneti tárolása miatti konzisztencia problémákat fi­gyel­­heti, kezel­heti.

Hátrányai:

– a szolgáltató leállásakor az állapotinformáció elveszik újrain­duláskor,

– ilyenkor az ügyfelek átviteli kéréseit nem tudja kiszolgálni, az ügyfeleknek is terminálinuk kell,

– az ügyfelekkel konzultálva újra fel kell építenie az elveszett álla­potinformációt, ez bonyolult protokollt igényel,

– a szolgáltatónak fel kell ismernie, ha egy ügyfél váratlanul terminált (orphan de­tection), hogy a hozzátartozó állapotinformációt érvénytelenítse.

  • Állapot nélküli (stateless) szolgáltató. A szolgáltató az ügyfelekről nem tárol semmilyen információt, az ügyfelek min­den kérése önállóan is kielégíthető. (A fájlok megnyitására és lezárására nincs szük­ség.) Előnye, hogy az állomások meghibásodását jól tolerálja, ha az ügyfél nem kap választ a kérésére, egyszerűen újra kísérletezik. Hátránya, hogy lassú, mert

– kérésenként több információt kell átvinni,

– a fájlt minden kérés kiszolgálásához a helyi fájlrend­szerben újra meg kell találni.

4.4.2.6. A fájlok többszörözése

Az elosztott fájlrendszerekben érdemes lehet egyes fájlokat meg­sok­szo­roz­ni (file replication):

  • növeli a rendszer hibatűrő képességét, ha a másolatokat olyan csomópontokon helyez­zük el, amelyek meghibásodás szempontjából függetlenek egymástól,

  • gyorsabb kiszolgálást biztosíthat, ha a rendszer megtalálja a „legközelebbi” vagy a legkevésbé terhelt szolgáltatón lévő másolatot.

Felmerülő problémák:

  • a fájl megnevezését a felhasználó számára láthatatlanul valamelyik máso­lathoz kell kötni,

  • a rendszernek automatikusan kell kezelni a fájlok többszörözését, a máso­latok különböző csomópontokon történő elhelyezését, megszüntetését,

  • a szükséges változtatásokat az összes másolaton el kell végezni.

4.4.3. Folyamatkezelés

Az elosztott rendszerek kialakítását leggyakrabban a kliens–szerver-modellel és egy protokollal, a távoli eljáráshívással (remote procedure call, RPC) kötik össze, melyet gyakran használnak a modell megvalósítására.

4.4.3.1. Kliens–szerver-folyamatok

A kliens–szerver-modell alapötlete egy szoftver rendszer olyan particio­ná­lá­sa, amely meghatározza a rendszer által nyújtott szolgáltatásokat (szervizeket) a hozzájuk tartozó algoritmusokkal (szerverekkel), valamint tartalmazza az adott alkalmazásnak megfelelő kliens programokat, melyek a szerverek szolgáltatásait igénybe véve oldják meg a feladatot a felhasználó számára. Ebben a modellben a kliens alkalmazás programok nem kommunikálnak egymással, hanem direkt módon érik el a szerverek szolgáltatásait.

A szervereken ún. démon folyamatok (daemon processes) várják a kliensektől beérkező kéréseket. Egy démon folyamat általában csak a kapcsolat kezdeti kiépítését végzi el egy, a kliens kiszolgálásához rendelt szerver folyamathoz. A démon folyamatok állandóan futó folyamatok, melyek a szolgáltatás állandó elérhetőségét biztosítják. TCP/IP vagy UDP/IP protokoll feletti kommunikáció esetén a démon egy TCP vagy UDP porthoz kötött folyamat, amely a porton beérkező kérésekhez rendel kiszolgáló rutint. UNIX-rendszer alatt az önálló folyamatokon kívül létezik egy általános megoldás is a feladat elvégzésére: az Internet démon (internet daemon, röviden inetd). Ennek több TCP és UDP port, és a hozzájuk tartozó szerverprogram is megadható egy erre szolgáló konfigurációs fájlban (inetd.conf), így egyetlen folyamattal lehet megvalósítani a kérések fogadását. A démon folyamatok UNIX alatt a háttérben futnak, nem tartozik hozzájuk terminál viszony. Elindulásuk után elszakadnak a terminál kapcsolatuktól, ily módon garantálva azt, hogy a terminál kapcsolat lebomlása után is tovább fussanak.

A hálózati számítási modellben (amelynek alappillére a kliens–szerver-modell) a szerverek eléréséhez a kliens alkalmazásoknak tisztában kell lenni a szerverek pontos címével (például IP-cím és portszám), a szolgáltatásuk elérésének módjával, valamint a kapott eredmények értelmezésével. Az elosztott számítási modell szintén alkalmazza a kliens–szerver-megközelítést, de ebben az esetben a kliens elsősorban a szerverek által nyújtott szolgáltatások alapján éri el a szervert, mintsem annak címének pontos ismerete alapján. Egy elosztott rendszerben a kliens–szerver-kapcsolat kiépítését egy külön kommunikációs közbülső réteg (middleware) biztosítja.

Rengeteg példát találunk kliens–szerver-rendszerekre, mint a fájlszerverek (hálózati fájlmegosztás), adatbázis-szerverek, hálózati autentikációs szerverek, webszerverek stb. Ezek túlnyomó többsége a hálózati számítási modellt követi, kisebb részük, mint például az NFS és az elosztott objektumorientált rendszerekre épülő alkalmazások az elosztott számítási modell felé közelítenek.

Egy elosztott környezetben a szerverek egyszerre több klienssel is kapcsolatban állnak, és a kliensek egy időben több szerver szolgáltatásait is igénybe vehetik. A kliens és szerver folyamatokat tervezésük során alkalmassá kell tenni az ilyen többirányú kapcsolatok kiépítésére. Egy kliens és egy szerver közötti kapcsolat kiépítése, a kötés (binding), az a folyamat, amelynek során a kliens megtalálja a számára szükséges szolgáltatást nyújtó szervert, és kettőjük között kialakul a kommunikációs kapcsolat. Többféle kötési rendszer létezik, azaz többféle módot választhatunk a szerver kiválasztására és a kapcsolat kiépítésére. Például egy webszerver esetén a kliens (webböngésző) a szerver címének (internetcím és portszám) ismeretében a HTTP protokollban meghatározottak szerint küld egy üzenetet a szervernek. A szerver általában külön kiszolgáló eljárást rendel a klienshez (hogy egy időben több kérést is kiszolgálhasson), mely értelmezi a klienstől kapott üzenetet, elkészíti a választ és elküldi a kliensnek. A kliens–szerver kapcsolat a webrendszerben ekkor le is bomlik (nem perzisztens). Ha a gépünk óráját akarjuk beállítani, akkor ezt olyan kliens program segítségével is megtehetjük, amely nem közvetlenül egy szervert szólít meg a feladat megoldására, hanem a hálózatra egy szórt (broadcast) üzenetet küld, és az összes szervertől beérkező válasz alapján állítja be gépünk óráját.

A kötés folyamatát tovább bonyolíthatja, ha alkalmazásuk megbízhatóságának növelése, nagyobb adatbiztonság, vagy egyszerűen csak a gyorsabb válaszidők érdekében több, konkurrens, ugyanazt a szolgáltatást nyújtó szervert is üzemeltetünk. Ez a replikáció (replication). Egy szerver kiesése (például az NFS rendszerben egy fájlszerviz leállása) ilyenkor a kliens–szerver-kötés megváltozását eredményezheti (NFS esetében a fájl szerviz tartalék szervere szolgálja ki a következő klienskérést), gyakran olyan módon, melyről a kliens nem is szerez tudomást.

Átmeneti gyorsítótárak alkalmazása (caching) szorosan összefügg a replikációval. Ez a fájlrendszereknél és adminisztrációs adatbázisoknál gyakran alkalmazott technika a kliens által gyakran kért információt egy helyi átmeneti tárolóban helyezi el a klienshez közel. Ily módon a következő megegyező kérés kiszolgálási sebessége megnő, ugyanakkor az adatok konzisztenciájának biztosítása nagyobb feladatokat ró a szerver kidolgozójára. Az elosztott gyorsítótárak egy speciális fajtája a proxy, mely elsősorban a web- szerverek területén elterjedt. A proxy egy olyan szervert takar, amelyik valamilyen más szerveren tárolt információt helyileg is megőriz a kliensek számára. A proxy általában nem közvetlenül a szervertől kérdezi le az adatokat, hanem egy másik, a szerverhez a hálózaton közelebb elhelyezkedő proxytól. Ily módon a proxy-szerverek egy hierarchikus rendszert alkotnak, amelyben egy kliens kérés addig továbbítódik az adatot eredetileg tároló szerver felé, míg egy proxy átmeneti tárában azt meg nem találja. Egy proxy-rendszer elsősorban a hálózati kapcsolat lassúsága miatti időkésést hivatott csökkenteni.

Kliensek és szerverek közötti kommunikáció kialakításának legelterjedtebb formája a távoli eljáráshívás (remote procedure call, RPC). Ennek során a szolgáltatásokat eljárások valósítják meg, a kliensek pedig a szolgáltatásokat az eljárások meghívásával veszik igénybe. A távoli eljárások meghívása az alkalmazások szempontjából nagyon hasonlatos a helyi eljárások meghívására – a lényeges különbséget (a hálózati kapcsolat kialakítását, az adatok átjuttatását és az eredmények visszaküldését) a távoli eljárást megvalósító rendszer elfedi az alkalmazások elől.

4.4.3.2. Távoli eljáráshívás – RPC

Az RPC-rendszer egy protokoll-leírást és egy programozói interfészt tartalmaz. Alapvetően egy kliensgép számára lehetővé teszi, hogy egy kiválasztott szervergépen egy előre meghatározott eljárást lefuttasson. A kliensgépen futó folyamat eljárás hívása a szervergépen futó folyamat egy eljárásának meghívását eredményezi. A bemenő paraméterek és a visszatérési érték átviteléről, valamint a szervereljárás meghívásáról az RPC-alrendszer gondoskodik. Több magasabb szintű szolgáltatás épül az RPC-rendszerre, mint például az NFS (Network File System) és a NIS (Network Information System).

Az RPC-protokoll alapvetően a kliens és a szerver közötti kommunikáció adatformátumát határozza meg. Ezenkívül foglalkozik az üzenetek átvitelé­nek mechanizmusával, illetve a kapcsolatban álló felek azonosításával is. A protokoll megbízható kapcsolatot épít ki a kommunikáló felek között, azaz garantálja a kérések továbbítását a célállomásig, illetve a válaszok visszajuttatását. Bár az RPC alapvetően szállítási protokoll független rendszer, általában UDP/IP (User Datagram Protocol/Internet Protocol) felett implementálják, mely alapvetően megbízhatatlan (ellentétben a TCP/IP protokollal). Az RPC-réteg feladata a biztonságos átvitel megvalósítása az üzenetek periodikus megismétlésével a nyugtázás vételéig.

A 4.8. ábra egy tipikus RPC-kérés–válasz párt szemléltet. Az xid az átvitel azonosító, mely egyértelműen megjelöli a kérést. Az azonosítót a kliens egyedileg készíti minden üzenete számára, a szerver pedig ugyanezt az azonosítót alkalmazza a válaszában. Ily módon a kliens egyértelműen azonosíta­ni tudja azokat a kéréseket, amelyekre választ kapott a szervertől. A direction mező azt jelzi, hogy az aktuális üzenet egy kérés, vagy egy válasz. Az rpc_vers mező az RPC-protokoll verziószámát rögzíti, a prog és vers azonosítók a szerver folyamat (RPC-szolgáltatás) program és verzió azonosítói. Ezek után az azonosítással kapcsolatos információk következnek, majd a kérésben a meghívott eljárás paraméterei, a válaszban pedig az eljárástól érkező eredmények.

Az RPC egy egységes, ún. kiterjesztett adatreprezentációt (Extended Data Representation – XDR) használ a hálózati adatforgalomban. Az XDR szabvány (Sun Microsystems) egy gépfüggetlen adatábrázolási mód. Többféle egyszerű adattípust definiál, illetve szabályokat határoz meg bonyolultabb adatstruktúrák létrehozására.

5.7.ábra. táblázat - A UNIX prioritási tartományai

RPC-hívás

 

RPC-válasz

xid

 

xid

direction (= hívás)

 

direction (= válasz)

rpc_vers (= 2)

 

reply_stat

prog

 

Autentikációs

vers

 

információ

proc

 

accept_stat

Autentikációs információ

 

Eljárásspecifikus eredmények

Eljárásspecifikus argumentumok

  

Alapvető adattípusai a következők:

  • Egész szám. 32 bites entitás, ahol a 0. bájt reprezentálja a legnagyobb helyiértékű bájtot. Előjeles egészeket kettes komplemens alakban tárolnak.

  • Változó hosszúságú adatfolyam. Egy négy bájtos hossz mezővel leírt adat. A hossz mező után az adatfolyam következik. Az adatot nullák egészítik ki a négy bájtos határig.

  • Szöveg. Az adatfolyamhoz hasonlóan egy hossz mezővel kezdődő ASCII karaktersorozat, nullákkal kiegészítve a négy bájtos határra (amennyiben a szöveg hossza épp néggyel osztható, nincs lezáró nulla, ellentétben a UNIX-rendszereknél szokásos gyakorlattal).

  • Tömb. Azonos típusú elemekből álló vektor, mely szintén egy négy bájtos hossz mezővel kezdődik, majd a vektor elemei következnek. Minden elemnek néggyel osztható hosszúságúnak kell lennie. Bár az elemeknek azonos típusúnak kell lenniük, hosszuk különbözhet (például szövegekből álló tömb esetén).

  • Struktúra. A struktúrák komponenseit sorrendben tárolja a szabvány azzal a megkötéssel, hogy minden komponens hosszát néggyel oszthatóra igazítja nullák beszúrásával.

Az adatstruktúrák meghatározásán kívül az XDR egy formális nyelvet is bevezet az adatok leírására. Az RPC-rendszer is ezen nyelv kiterjesztését használja a távoli eljáráshívás formális leírására.

Az XDR alapvető hátránya, hogy az adatreprezentációjától jelentősen eltérő reprezentációt használó architektúrákon erőforrásigényes lehet a szükséges konverziók megvalósítása. Ez elkerülhető lenne, ha az adatok átalakítása helyett a kommunikációban részt vevő felek egymás adatreprezentációs különbségeiket tisztáznák csak. Ilyen megoldást alkalmaz a DCE (Distri­bu­ted Computing Environment, OSF 1992) RPC az XDR helyett.

Az RPC az adatcserén és a távoli eljárások meghívásán kívül programozási eszközöket is nyújt a kommunikációs szoftverek megvalósításához. A már említett RPC nyelv, mely az XDR formalizmusát követi, alkalmas a szerver interfészének formális leírására. A formális leírásból az rpcgen program képes a szerver és a kliens programok megfelelő részeit, valamint a szükséges XDR konverziós függvényeket elkészíteni C nyelven. Az így kapott C forráskódú modulokat a kliens és szerver alkalmazással kibővítve kapjuk a teljes kommunikáló rendszert. A következő programlista egy egyszerű távoli idő szerver interfészét mutatja.

/*

* date.x – Specification of remote date and time service.

*/

/*

* Define 2 procedures:

* bin_date_1() returns the binary time and date (no arguments).

* str_date_1() takes a binary time, returns a human-readable string.

*/

program DATE_PROG {

version DATE_VERS {

long BIN_DATE(void) = 1; /* procedure number = 1 */

string STR_DATE(long) = 2; /* procedure number = 2 */

} = 1; /* version number = 1 */

} = 0x31234568; /* program number = 0x31234568 */

4.4.3.3. Szálak alkalmazásának előnyei

A mai RPC-rendszerekhez általában szorosan kapcsolódik a szálak (threads) alkalmazása, mely lehetővé teszi egy program számára, hogy több feladatot is végrehajtson egyazon időben. Bár a szálaknak kevés köze van a hálózati kommunikációhoz, mégis gyakran alkalmazzák őket a kliens–szerver-rendszerekben. Használatukkal ugyanis lehetővé válik a kliens kérések párhuzamos kiszolgálása, illetve párhuzamos szerver kérések elküldése egyazon folyamaton belül.

A szálak alkalmazásának több előnye is van. Ezek egy része a szerverek teljesítményét növeli, más részük a tervezéskor és megvalósításkor könnyíti a programozók dolgát.

Képzeljük el a következő példát!

Egy RPC-szerver a klienstől érkező feladata megoldásához más szerverek szolgáltatását is igénybe veszi. Azok további szervereket kapcsolnak a feladat megoldásába, míg végül valamelyikük az eredeti kliens valamely szolgáltatását szeretné igénybe venni. Kialakult a holtpont. Helyi függvényhívások esetén ez rekurzióhoz vezetne, az RPC esetén azonban holtpont alakul ki. Ez a helyzet feloldható a szálak alkalmazásával. Ha az RPC-szerver a beérkező eljáráshívásokhoz különálló szálakat rendel (melyek a folyamatokkal ellentétben képesek ugyanazon adatstruktúrákon dolgozni), a holtpont feloldódik, átalakul rekurzióvá.

A szálak alkalmazásával mind a szerverek, mind a kliensek párhuzamosíthatják futásukat az RPC-kommunikáció alatt. A szerverek minden beérkező RPC-kérésre különálló szálat indítanak el (adott maximumig). A kliens a távoli eljárást egy külön szálban indítja el, így annak eredményére várakozva más feladatokat is megoldhat. Egy távoli eljárás meghívása során a kliens és szerver programokban létrejövő szálakat logikailag egy szállá foghatjuk össze. Ez az RPC-szál (RPC thread). Az RPC-szál a kliens oldalon keletkezik (mint kliens szál), majd kiterjesztődik a hálózaton keresztül a szerverre, ahol szerver szállá válik, amin belül végrehajtódik a távoli eljárás. Az eljárás lefutása után a szál „visszatér” a klienshez és ismét kliens szálként szolgáltatja a függvény visszatérési értékeit. A szerver egyszerre több RPC-szálat is fogadhat a kliens kérések kiszolgálása érdekében. Praktikusan létezik a szerverben párhuzamosan futtatható szálak számának egy maximális értéke, mely után a következő beérkező RPC-szál várakozni kezd mindaddig, míg egy szerver szálnak létrehozása lehetővé nem válik. Ez a mechanizmus része a DCE (Distributed Computing Environment) 1.1 RPC specifikációjának.

A szálak természetesen nem csak a távoli eljáráshívás modelljében használatosak. A mai korszerű operációs rendszerek mindegyike kínál megoldást a szálak létrehozására. Szálak alkalmazásával általában egyszerűbben megvalósítható konkurens futási környezetet alakíthatunk ki. Lehetővé válik a párhuzamos feldolgozás a lehető legkisebb vízfejjel – mind kernel, mind alkalmazás szinten. A kernel a szálak közötti váltást lényegesen kevesebb adminisztrációval oldja meg, míg az alkalmazások mentesülnek a folyamatok közötti kommunikációs terhektől a szálak közötti adatcserében.

A szálak alkalmazásának ugyanakkor vannak hátrányai is. Szálakat alkalmazó programoknál sokkal körültekintőbben kell eljárni a tervezés során. A szálak okozta konkurens adat- és erőforrás hozzáférés az alkalmazás készítőjére hárítja a kölcsönös kizárás tervezésének és megvalósításának feladatát. E nélkül a többszálú rendszer adatai könnyen inkonzisztens állapotba kerülhetnek. Másrészt a szálak futása nem szakad el teljesen a folyamat futásától. Egy operációs rendszerben a szálak megvalósításától függhet a folyamatok és a szálak futási viszonya és viselkedése. Amennyiben a szálakat felhasználói szinten, a kerneltől függetlenül valósítják meg (user-level threads) és egy szál kiad egy olyan rendszerhívást, ami blokkolható, az egész folyamat futása blokkolódik. Kernel szintű szálak megvalósítása esetén (kernel-level threads) ez a probléma nem áll fent. Ez azonban újabb követelményeket jelent a rendszerhívások megvalósításával szemben. Az ilyen operációs rendszerek külön jelzik, ha egy rendszerhívás biztonságos a szálak szempontjából (thread-safe). Ettől eltérő esetben (a gyakorlati esetek többségében) a szálakban a rendszerhívások alkalmazása gondosan tervezendő (például kölcsönös kizárás alkalmazásával) az újrahívások elkerülése végett.

4.4.4. Időkezelés és koordináció elosztott rendszerekben

Mint azt korábban láttuk, az elosztott rendszerek számos tekintetben eltérő követelményeket támasztanak a rendszer funkcióival és kialakításaival szemben, mint a centralizált rendszerek. Az időkezelés sem kivétel ez alól: elosztott rendszerekben az idő, és annak konzisztens kezelése központi jelentőségű. Egyes alkalmazásokban a pontos, valós időre van szükség (például naplózás, számlakezelés), míg az esetek jelentős részében elegendő olyan időkezelés, amely biztosítja a rendszerben bekövetkező események sorrendezését. Az alábbiakban áttekintjük az ezen feladatok ellátásával kapcsolatos fogalmakat és a szükséges eszközöket.

4.4.4.1. Időkezelés

Az időkezelés két alapvető funkciót hivatott támogatni: a valós idő pontos ismeretét (ami elengedhetetlen például naplózási, számlázási feladatok ellátásához), illetve a rendszerben bekövetkezett események sorrendezését (event ordering). Ez a két feladat eltérő igényeket támaszt az időkezeléssel szemben, és mint azt majd látni fogjuk, az előbbit fizikai órák, míg az utóbbit logikai órák használatával lehet a leghatékonyabban megoldani.

Koordinált Univerzális Idő (KUI)

Az emberek életében az idő kitüntetett szerepet tölt be. Míg a hétköznapi életben nagyon gyakran megelégszünk az idő „hozzávetőleges” ismeretével, számos, elsősorban csillagászati alkalmazások ennél precízebb idő fogalmat igényelnek. Ma az idő mérésére a legpontosabb eszköz az atomóra. Ennek pontossága 10-13 sec/sec.

A Nemzetközi Atomidő az atomóra pontosságával méri az eltelt időt, mely szerint egy másodperc 9192631777 átmenet a Cs133 alapállapotának 2 hiper­fi­nom szintje között. Ez pontos időmérést tesz lehetővé. Azonban az emberiség az időt a csillagászati időhöz igazítja, így bevezették a Koordinált Univerzális Idő – KUI (Coordinated Universal Time) fogalmát, aminél meghatározott időközönként szökőmásodperceket kell beiktatni, vagy törölni.

Ezt a koordinált univerzális időt használják a valós fizikai idő etalonjaként. Ezt az időt rádióállomások (például az amerikai WWV), űrszondák (például GOES: Geostationary Operational Environmental Satellites), (GPS: Global Positioning System) sugározzák, így amennyiben külső szinkronizálásra van szükség, akkor az ezeket a jelet vevő berendezések segítségével ez megtehető. A szinkronizálás pontossága az alkalmazott módszertől függően 0,1–10 milliszekundumos nagyságrendbe esik.

Ezen berendezések alkalmazásánál azonban a jel vételének módját figyelembe kell venni, mert az meghatározza a szinkronizálás pontosságát. Ha például Magyarország keleti és nyugati határánál egy-egy időszolgáltató egy közeli földi rádióállomás alapján szinkronizál a KUI-hez, akkor ezen két időszolgáltató órája között nagyságrendileg milliszekundumos eltérés lesz. Ennek oka az eltérő terjedési idő, ami sajnos a légköri zavarok miatt nem becsülhető pontosan.

A valós, fizikai idő kezelése

A valós fizikai idő mérésére a rendszer órája szolgál. Egy centralizált rendszerben ez egyetlen órát jelent, míg elosztott rendszerben a rendszer minden egyes számítási csomópontja tartalmazhat egy saját fizikai órát. Ekkor nagyon fontos, hogy biztosítsuk ezen fizikai órák együtt járását. Mivel az órák referencia jelét egy analóg berendezés (tipikusan egy kvarc oszcillátor) szolgáltatja, így a referencia jelek adott pontosságúak. A kvarc oszcillátorok tipikusan 10-6–10-7 sec/sec pontosságúak. Ebből adódóan az egyes órák a rendszerben csúsznak egymáshoz képest, így azokat időről időre szinkronizálni kell, hogy a rendszerben adott pontossággal tudjunk egy ún. globális időt mérni.

Elosztott rendszerekben nagyon gyakran az az elvárás, hogy az egyes órák adott pontossággal együtt járjanak. Ezt a követelményt a belső szinkro­ni­zá­ció­val tudjuk biztosítani. Ekkor az órák az időről időre elvégzett szinkronizálás miatt együtt járnak, egymáshoz képest nem csúsznak, pontosabban a csúszás jól kontrollált. Ezzel szemben bizonyos esetekben az elosztott rendszer együtt működik más rendszerekkel, és elvárás, hogy az órák a valódi fizikai időt mérjék. Ilyenkor nem elég, hogy a rendszer órái egymáshoz képest nem csúsznak, a valós fizikai időhöz, a Koordinált Univerzális Időhöz képest sem csúszhatnak. Ezt a külső szinkronizálással lehet elérni, amikor időről időre a Koordinált Univerzális Időhöz szinkronizál a rendszer.

A továbbiakban vázlatosan áttekintjük az elosztott rendszerekben alkalmazott legismertebb óra rendszereket.

Elosztott rendszerekben alkalmazott óra rendszerek

Elosztott rendszerekben három típusú óra rendszert szokás alkalmazni a fizikai idő nyilvántartására: a pontos központi órával rendelkező rendszereket, a központilag felügyelt órákkal rendelkező rendszereket és a teljesen elosztott órás rendszereket. Az alábbiakban ezen rendszerek főbb tulajdonságait adjuk meg.

Pontos központi órával rendelkező rendszerek

A pontos központi órával rendelkező rendszerek az alábbi jellemző tulajdonságokkal rendelkeznek:

  • Egy pontos óra szolgáltatja az időt az egész rendszernek. (A többi óra jelenlétéről nem veszünk tudomást, amíg a központi óra meg nem hibásodik.)

  • A hibatűrés meleg tartalékként jelenik meg. Ha a központi pontos óra meghibásodik, egy másik óra veszi át a szerepét.

  • A módszer pontos (az alkalmazott órától függően ns – ms), de drága.

  • Speciális, a processzorba integrált hardvert igényel. Az óra ezt állítja, a többi folyamat ezt olvassa.

  • Kommunikációs költség alacsony: 1 üzenet/szinkronizáció/hely, vagy broadcast.

  • Példa: GPS, 4 szatelit, körülbelül ns-os pontosság.

Központilag felügyelt órákkal rendelkező rendszerek (master-slave)

A központilag felügyelt órákkal rendelkező rendszerek az alábbi jellemző tulajdonságokkal rendelkeznek:

  • A pontosnak elfogadott master óra lekérdezi a slave-eket.

  • Csúszásokat mér, korrekciót küld a slave-eknek.

  • Ha a master meghibásodik, akkor valamilyen választási algoritmus alap­ján egy új mastert kell választani.

  • Az átviteli időt becsülik.

Elosztott órás rendszerek

Az elosztott órás rendszerek az alábbi jellemző tulajdonságokkal rendelkeznek:

  • Minden hely homogén, azonos algoritmust futtat.

  • Minden hely a többi óra üzenete alapján frissíti a saját óráját (becsüli saját pontosságát).

  • A hibatűrés protokoll alapú. A csomópontok észreveszik, ha valamelyik óra meghibásodott, és figyelmen kívül hagyják annak értékét.

  • Nagy kommunikációs költség.

Az órák szinkronizálásánál nem szabad azzal a naiv feltételezéssel élni, hogy elég ismerni az egyes órák közötti eltérést, és akkor megoldható a szinkronizálás. Ez a gondolatmenet azért hibás, mert az egyes órák csúsznak (drift) egymáshoz képest. A kvarc oszcillátor alapú órák is csúsznak, vagyis az időt más „frekvenciával” mérik, mint a pontos referencia óra, így az általuk mutatott idő egyre jobban eltér attól. A csúszás lehet nagyon pici, de ez az idő múltával akkumulálódik. Például kvarc oszcillátoros órák esetén 10-6 sec/sec pontosságot feltételezve 1000000 másodperc, vagyis 11,6 nap alatt csúsznak 1 másodpercet.

Óracsúszás kompenzálása

Egy adott gép órája kétféleképpen csúszhat a valós, pontos órához képest: késhet, illetve siethet. Az első esetet viszonylag egyszerűen le lehet kezelni. Ha a valós időt Tval, a pontatlan lokális időt Tlok jelöli, és Tval > Tlok, akkor Tlok := Tval állítással a problémát meg lehet oldani. Ez a módosítás teljesíti a természetes elvárást, hogy az idő értéke növekedjen. Sajnos ennél nehezebb problémával találjuk szemben magunkat, ha a lokális óra siet. Nem tehetjük meg, hogy egyszerűen visszaállítjuk, mert ekkor az a feltételezés, hogy az idő előre halad nem teljesülne. (Például a Unix make csak azokat az állományokat fordítja újra, amelyeknek a forrása frissebb, mint a hozzájuk tartozó object állomány. Ha megengednénk az óra visszaállítását, akkor előállhatna az az eset, hogy módosítunk egy forrásállományt, és a make mégsem fordítja újra, mert közben a szinkronizálás miatt az órát a rendszer visszaállította, és így az object állomány későbbinek tűnik.) Így azt kell elérni, hogy az óra lassabban járjon. A hardverórát általában nem lehet lassítani, így a szoftverórát kell állítani. Az alábbiakban ismertetünk egy óracsúszás kompenzációs algoritmust. Ehhez az alábbi jelöléseket vezetjük be:

S(t): szoftveróra,

H(t): hardveróra,

d(t): kompenzáció,

S(t) = H(t) + d(t).

Amennyiben a módosítást folytonosnak szeretnénk, akkor d(t) legyen egy lineáris függvény:

d(t) = aH(t) + b.

Tegyük fel, hogy S(t) = Tcsúszás amikor H(t) = h, és ekkor a pontos referenciaóra Tvalódi-t mutat.

Ha azt akarjuk elérni, hogy S N további tikk (óraütés) után mutassa a pontos időt, akkor

Tcsúszás = (1+a)h + b,

Tvalódi+N = (1+a)(h+N) + b.

innen

a = (Tvalódi – Tcsúszás)/N

és

b = Tcsúszás – (1+a)h.

Tehát ezt a módszert alkalmazva elérhető, hogy a szoftverórát úgy járassuk lassabban, hogy az N tikk, vagyis óraütés múlva a pontos időt mutassa.

Óraszinkronizációs módszerek

Az alábbiakban vázlatosan áttekintünk három óraszinkronizációs módszert.

Cristian algoritmus

Cristian algoritmusa átmenet a pontos központi órával rendelkező és a központilag felügyelt órás rendszerek között. Az algoritmus feltételez egy pontos időszolgáltatót, amihez a kliensek időkéréseket juttatnak el, ha a pontos időre van szükségük. Amikor az időszolgáltató kap egy idő kérést, a nagyobb pontosság érdekében a válaszul összeállított üzenetbe a lehető legutolsó pillanatban helyezi bele az időt. Ezt az üzenetet visszaküldi a kliensnek. A kliens a megkapott üzenetből kiolvassa az időt és kompenzálja az átviteli idővel.

A nagyobb pontosság elérése érdekében az oda-vissza üzenet úthoz tartozó idő átlagával kompenzál. Az átviteli időt úgy modellezi, hogy Tátvitel = min + x, vagyis az átvitelt felbontja két komponensre: a min azt az időt jelöli, amennyi időt az átvitel akkor igényelne, ha csak az időt kérő folyamat futna és nem lenne más hálózati forgalom, illetve egy járulékos tagra, ami a többi folyamat és a többi hálózati forgalom hatását modellezi. Ezzel a modellel a szinkronizálás pontosságára a ±(Toda-vissza/2-min) eredmény adódik.

A Berkeley algoritmus

A Berkeley algoritmus egy tipikus master-slave algoritmus. Itt a Cristian algoritmussal ellentétben a master folyamatosan lekérdezi a slave órákat és kiszámítja az egyes órák csúszásait. Továbbá nem a master által mutatott időt küldi el a slave-eknek, hanem a csúszást, ezáltal csökkentve az átviteli késleltetés okozta pontatlanságot. A nagyobb pontosság érdekében a kompenzációra felhasznált értékeket átlagolja, ezáltal a kommunikációs csatorna változó késleltetését és egyéb járulékos hibáit is csökkenti. Az algoritmus már hibatűrő tulajdonságokkal rendelkezik. Egyrészt a kirívó értékeket figyelmen kívül hagyja, másrészt amennyiben a master csomópont meghibásodik, egy (a későbbiek folyamán tárgyalt) választási algoritmussal új master csomópont kerül megválasztásra. Az algoritmussal elért pontosság durván 20–25 ms.

A Network Time Protocol

A Network Time Protocol egy időszolgáltató architektúrát és protokollt ír le, amit eltérő hálózatokból összekötött elosztott rendszerben az idő információ terjesztésére lehet használni. Ez az algoritmus képezi az Internetes óra­szinkro­nizáció alapját. A megtervezésénél az alábbi főbb szempontokat vették figyelembe:

  • kliensek pontosan szinkronizálhassanak a KUI-hez,

  • megbízható szolgáltatás legyen, éljen túl hosszú idejű szétcsatolást,

  • kellően gyakori szinkronizálást tegyen lehetővé,

  • védjen időszolgáltatás hamisítás ellen.

Ennek megvalósítása érdekében egy hierarchikus struktúrát építettek ki. Az algoritmus terminológiájában a stratum a szinteket jelöli a hierarchiában. Az 1-es stratumon az ún. elsődleges időszolgáltatók helyezkednek el, amelyek valamilyen célberendezés segítségével közvetlenül a KUI-hoz szinkronizálnak. A 2-es stratumon másodlagos időszolgáltatók helyezkednek el, amelyek elsődleges időszolgáltatókhoz szinkronizálnak. A sémából jól látszik, hogy minél magasabb stratumon helyezkedik el egy időszolgáltató, annál távolabb van a KUI-től, így annál pontatlanabb az általa szolgáltatott idő, viszont annál kisebb a költsége. Nagyon sok alkalmazás nem igényli, hogy az általa „látott” idő KUI pontosságú legyen, számos alkalmazásnál elegendő olyan óra pontosság, amit a hétköznapi életünkben használunk. A struktúra erősen hibatűrő és a „graceful degradation” (elegáns letörés) tulajdonságot mutatja.

A rendszerben három típusú szinkronizálás valósul meg:

  1. Multicast (LAN). Kis késleltetést feltételez, pontatlan, de sok alkalmazás számára ez a pontosság is elégséges.

  2. Eljáráshívás. Kliens–szerver-modellt alkalmaz, nagyobb pontosságot ér el az előbbi típusnál. Akkor alkalmazzák, ha nagyobb pontosságot kell elérni, vagy ha a multicast nem támogatott.

  3. Szimmetrikus mód. <ofszet, konfidenciaintervallum, késleltetés> alakú üzeneteket használ. A gépek az utolsó nyolcat tárolják, a legkisebb késleltetésűt választják.

Míg 1991-ben megközelítőleg 20–30 elsődleges szerver és 2000 másodlagos szerver kapcsolódott az Internethez, addig ezek a számok mára nagyságrendekkel növekedtek. A Network Time Protocollal megközelítőleg 30 milliszekundumos pontosság érhető el.

Itt meg kell jegyezni, hogy ez az időszolgáltatás ún. best-effort szolgáltatás, nincs garantált időkorlát.

Logikai idő és logikai órák

Az eddigiekben tárgyaltuk a fizikai órákat és kezelésüket, elsősorban az elosztott rendszerek óráinak szinkronizálási kérdéseire koncentráltunk. A bevezetőben említettük, hogy az egyik legfontosabb időkezeléssel kapcsolatos feladat az esemény sorrendezés. Míg tetszőleges folyamatban a folyamat eseményeit egyértelműen sorba lehet rendezni a folyamat fizikai órája alapján, addig elosztott rendszerekben sajnos fizikai órát nem lehet események sorrendezésére használni, mert a folyamatok fizikai óráit nem lehet tökéletesen szinkronizálni. Ezért szükség van valamilyen módszerre, amely biztosítja a folyamatok eseményeinek sorrendezését elosztott környezetben. Már korábban is láttuk, hogy erre a feladatra a fizikai órák nem igazán alkalmasak. Ezt támasztja alá az is, hogy például 10 ms-os pontosságot figyelembe véve, ez a pontosság nem elégséges számos alkalmazás számára azok eseményeinek sorrendezésére. Egy 10 MIPS-es gép ennyi idő alatt 100 000 utasítást végez el, ami alatt számos, például szinkronizációs esemény következhet be. Ebből jól látszik, hogy ha a rendszerben az események az óra felbontásánál gyakrabban (nagyobb frekvenciával) következnek be, akkor azokat fizikai órával nem lehet sorrendezni, szükség van valamilyen, kifejezetten az események sorrendezését támogató absztrakcióra.

Mielőtt rátérnénk a módszer tárgyalására, definiáljuk a korábban-történt (happened before) relációt. Ennek értelmezéséhez tekintsük először azonban az alábbi két triviálisnak tűnő kijelentést:

  1. Ha két esemény ugyanabban a folyamatban történt, akkor azok sorrendje megegyezik azzal a sorrenddel, ahogyan azt a folyamat látja.

  2. Amikor egy folyamat üzenetet küld egy másik folyamatnak, akkor az üzenet elküldése megelőzi az üzenet megkapását.

Ezek után már definiálható a korábban-történt (KT) reláció, az alábbi jelölésekkel:

: x és y két esemény, mindkettő egyazon P folyamatban történt, és x megelőzte y-t.

: x korábban-történt relációban van y-nal (x és y nem feltétlenül egy folyamat eseményei)

KT1: Ha $ P folyamat, melyre , akkor x -> y adódik

KT2: ˙m üzenetre send(m) -> rcv(m), ahol

– send(m) az üzenet elküldésének,

– rcv(m) pedig az üzenet megkapásának eseménye.

KT3: Ha x, y és z olyan események, amelyekre

x -> y és y -> z, akkor x -> z

Ezek után már bevezethetjük a logikai órákat.

Logikai órák

A korábban történt rendezéshez támogatást kell nyújtani, hogy azt számszerűen meg lehessen ragadni. Ezt a szerepet hivatott betölteni a logikai óra. A logikai óra monoton növekvő szoftver számláló, amelynek az értéke nem kell, hogy bármilyen fizikai órához kapcsolódjon. Minden P folyamatnak van egy saját logikai órája, CP, amelyet a folyamat események időcímkével való ellátására használ. A következőkben a P folyamatban az a esemény időcímkéjét CP(a) jelöli, míg egy tetszőleges folyamat b eseményét C(b). A folyamatok az alábbi szabályok szerint (LSZ) állítják a logikai órájukat, illetve az üzenetekben az alábbi időcímkéket küldik:

LSZ1: CP minden egyes esemény P-beli bekövetkezte előtt inkrementálódik: CP := CP + 1

LSZ2:

(a) Amikor egy P folyamat egy m üzenetet küld, akkor a folyamat az m üzenetet t = CP időcímkével látja el.

(b) Amikor egy Q folyamat megkap egy (m, t) üzenetet, kiszámolja CQ := max(CQ, t)-ot és aztán alkalmazza LSZ1-et az rcv(m) esemény időcímkével történő ellátása előtt.

A fenti logikai órára teljesül az alábbi összefüggés:

a ® b Ţ C(a) < C(b)

Vagyis ha egy a esemény korábban történt egy b eseménynél, akkor az a eseményhez kisebb logikai óraérték tartozik, mint a b eseményhez. Könnyen belátható azonban, hogy a fenti összefüggés fordítottja nem igaz, vagyis C(a) < C(b)-ből nem következik, hogy a ® b. Ez az eset tipikusan konkurens eseményeknél áll fenn.

Teljesen rendezett logikai órák

Az előbbiekben tárgyalt logikai óra konstrukció csak részleges rendezést ad az eseményeken, hisz léteznek olyan különböző folyamatokhoz tartozó események, amelyekhez azonos logikai óraérték tartozik. Azonban viszonylag egyszerűen ki lehet terjeszteni a fenti sémát, hogy az teljes rendezést adjon. Ehhez a folyamatok azonosítóját is fel kell használni az időcímkék megkonstruálásához. Ha a a Pa folyamat egy eseménye, amely Ta helyi időcímkével rendelkezik, és b a Pb folyamat egy eseménye, amely Tb helyi időcímkével rendelkezik, akkor az ezen eseményekhez tartozó globális időcímkék: (Ta, Pa), illetve (Tb, Pb). Ezek segítségével a teljes rendezés: (Ta, Pa ) < (Tb, Pb) akkor és csak akkor, ha Ta < Tb vagy Ta = Tb és Pa < Pb.

Itt feltételeztük, hogy a folyamatokra létezik egy teljes rendezés, ami a gyakorlatban mindig fennáll.

4.4.4.2. Elosztott koordináció

Elosztott folyamatoknak is koordinálni kell a tevékenységüket, különös tekintettel az osztottan kezelt erőforrásokra. A Sun NFS egy állapotmentes szerver, így ott állományok megosztott kezelésére nem lehet a szerveren zárakat használni, hisz ez ellentmondana az állapotmentességnek. Így ebben az esetben a Unix egy külön daemon – a lockd segítségével oldja meg a szinkronizálást. Azonban gyakran célszerű az erőforrást kezelő szerverrel szervesen egybeépíteni a szinkronizálási eszközöket.

A leggyakrabban előforduló szinkronizálás osztottan használt erőforrások esetén a kölcsönös kizárás. Elosztott rendszerekben az elosztottság a korábban megismert megvalósításokkal szemben újabb igényeket támaszt, amelyeket elosztott kölcsönös kizárási algoritmusokban figyelembe kell venni. A továbbiakban ezekre nézünk meg néhány példát.

Elosztott kölcsönös kizárás

Egy osztottan használt erőforrással kapcsolatosan a kölcsönös kizárással (KK) szemben az alábbi követelményeket támasztjuk:

KK1(biztonság): Egy időpillanatban egyszerre csak egyetlen folyamat tartóz-

kodhat a kritikus szakaszban.

KK2(haladás): Egy folyamat, amely be akar lépni a kritikus szakaszba, véges

időn belül beléphet. Ez a kritérium a rendszer holtpont

mentességét és kiéheztetés mentességét fogalmazza meg.

KK3(rendezés): A kritikus szakaszba a folyamatok a korábban-történt ren-

dezés alapján lépnek be, vagyis ha valaki korábban kérte

a belépés jogát, az korábban is kapja meg.

Központi szerver algoritmus

Az elosztott kölcsönös kizárás legegyszerűbb megvalósítása a központi szerver algoritmus. Itt minden egyes osztott erőforráshoz hozzárendelünk egy szervert, amelyre a kölcsönös kizárást meg kell valósítani. Ez a szerver engedélyezi a belépést a kritikus szakaszba. Minden alkalommal csak egy folyamatot enged be. Ha már tartózkodik egy folyamat a kritikus szakaszban, akkor a további kéréseket várakoztatja. Ezt a modellt úgy is elképzelhetjük, hogy a szerver birtokol egy tokent az általa felügyelt kritikus szakaszhoz. A szakaszba mindig csak az a folyamat léphet be, amelyik birtokolja a tokent. Mivel kezdetben egy token volt a rendszerben, így a kölcsönös kizárás biztosított. A szerver semmi mást nem tesz, mint amennyiben egy folyamat be akar lépni a kritikus szakaszba és a token a szervernél van (vagyis a kritikus szakaszban nem tartózkodik egyetlen folyamat sem), akkor a kérő folyamatnak odaadja a tokent, ellenkező esetben várakozásra kényszeríti. A megoldás problémája, hogy a szerver kritikus hibapont, annak meghibásodását megfelelően kezelni kell.

Logikai órákat alkalmazó elosztott algoritmus

Egy másik megközelítés a logikai órákat alkalmazó elosztott algoritmus. Logikailag ez az algoritmus is a belépést engedélyező token meglétéhez köti a kritikus szakaszba történő belépést, itt azonban a token a rendszerben lévő többi folyamattól kapott megfelelő üzenetek együtteséből áll elő. Az algoritmus lényege, hogy ha egy folyamat be szeretne lépni a kritikus szakaszba, akkor az összes többi folyamatnak elküld egy üzenetet, ami ezen szándékát jelöli, és az üzenetet ellátja a szándék időpontját jelző időbélyeggel. A folyamat ekkor bevárja, hogy a rendszer összes folyamata válaszoljon. Amikor az összes válasz megérkezett, a folyamat beléphet a kritikus szakaszba. Ameny-nyiben egyszerre több folyamat is be akar lépni a kritikus szakaszba, akkor több belépési szándékot jelölő üzenet is van a rendszerben. Ekkor, ha egy folyamat be akar lépni a kritikus szakaszba, és egy másik folyamattól egy hasonló jellegű üzenetet kap, akkor az üzenet időbélyegét összehasonlítja a saját üzenete időbélyegével. Amennyiben a saját időbélyege kisebb, akkor nem válaszol a kérésre, hanem egy várakozási sorban várakoztatja, és majd csak a kritikus szakaszt elhagyva válaszol neki. Amennyiben a saját időbélyege nagyobb, akkor azonnal válaszol a kérésre (ekkor majd a másik folyamat fogja őt várakoztatni). Jól látszik, hogy a sorrendezési kritérium is teljesül az algoritmusra.

A gyűrű alapú algoritmus

A gyűrű alapú algoritmus egy logikai gyűrűt épít a folyamatokból, amelyben egy token kering. Amelyik folyamat be akar lépni a kritikus szakaszba, az megvárja a token megérkezését, és belép, majd a kritikus szakasz elhagyása után küldi tovább a tokent.

Ezek az algoritmusok azt sugallják, hogy azok az osztottan használt erőforrás menedzserétől függetlenül futtathatók. Ez valóban így van, azonban egy praktikus implementációban célszerű a kölcsönös kizárást az osztott erőforráshoz a lehető legközelebb megvalósítani, vagyis célszerű ezt a feladatot is az erőforrás menedzserre ruházni.

A továbbiakban a választási algoritmusokat tárgyaljuk.

Választási algoritmusok

Elosztott rendszerekben a választási algoritmusok nagy szerepet kapnak. Feladatuk egy folyamatcsoportból egy kitüntetett folyamat kiválasztása. Ezen folyamat több szempontból is lehet kitüntetett: például kölcsönös kizárást biztosító szerver, koordinátor, token generátor, időszolgáltató stb.

A választási algoritmus eredményeként kiválasztott folyamattal szemben a fő követelmény, hogy a kiválasztott folyamat egyedi legyen, a csoport minden folyamata ugyanazt a folyamatot gondolja megválasztottnak, még akkor is, ha egyszerre több folyamat is elindítja a választást.

A továbbiakban két algoritmust vizsgálunk meg: a bully algoritmust, amely esetén a résztvevő folyamatok ismerik egymás azonosítóit, azok prioritását, illetve a gyűrű algoritmust, amelynél csak az egyik szomszéd kommunikációs azonosítójára van szükség.

A bully (erőszakos) algoritmus

Az algoritmus akkor alkalmazható, ha a folyamatcsoport tagjai ismerik egymás azonosítóit (illetve a hozzájuk rendelt prioritásokat – gyakran a prioritás megegyezik az azonosítóval), és hálózati címeit. Az algoritmus a folyamatcsoportból kiválasztja a legnagyobb prioritású még aktív folyamatot, és megválasztja koordinátornak. Az algoritmus működése során feltételezzük, hogy a kommunikáció megbízható, de a folyamatok maga a választási algoritmus alatt is meghibásodhatnak, továbbá a tárgyalás leegyszerűsítése érdekében a folyamat azonosítója egyben a prioritása is, és a nagyobb azonosító nagyobb prioritást jelöl. Az algoritmusban három eltérő típusú üzenet jelenhet meg:

  • választás: – a választás megkezdését jelzi,

  • válasz: – választási üzenetre adott válasz,

  • koordinátor: – az új, megválasztott koordinátor szétküldi az azonosítóját.

Az algoritmus mindig azzal kezdődik, hogy egy folyamat észreveszi a koor­dinátor meghibásodását. Legyen ez Pi. Ekkor:

  • Pi választás(Pi) üzenetet küld minden egyes Pj folyamatnak, amelyre j > i (az indexek prioritási sorrendet jelölnek). Ezután Pi várakozik vá­lasz(Pj)-re Tvv ideig. Ha nem érkezik válasz, akkor Pi magát tekinti a legnagyobb prioritású, még működő folyamatnak (hisz a magasabb prioritásúaktól nem kapott választ), és az alacsonyabb prioritású fo­lyamatoknak kiküld egy koordinátor(Pi) üzenetet, vagyis, megválasztja magát koordinátornak.

  • Ha érkezett valamilyen Pj folyamattól válasz, amelyre j > i, akkor Pi vár Tvk ideig, hogy a magasabb prioritású folyamat koordinátornak deklarálja magát. Amennyiben Tvk idő alatt nem jön ilyen üzenet, újabb választást kezdeményez.

  • Ha egy folyamat egy koordinátor(Pj) üzenetet kap, akkor feljegyzi az üzenetben szereplő folyamat azonosítóját, és ettől kezdve ezt a folyamatot koordinátorként kezeli.

  • Ha egy Pj folyamat választás(Pi) üzenetet kap, akkor visszaküld egy válasz(Pj) üzenetet, és Pj is kezdeményez egy választást, hacsak már nem kezdeményezett korábban.

Mint azt korábban említettük, az algoritmus kezeli a választási algoritmus futtatása során történő folyamat meghibásodásokat is. Erre szolgál a Tvk várakozási idő szerepeltetése az algoritmusban. Tvk a koordinátor megválasztási üzenet megérkezésére történő várakozás időkorlátját jelöli. Mint láttuk, ha egy folyamat észleli a koordinátor meghibásodását, választási üzenetet küld minden nála nagyobb prioritású folyamatnak (mivel ezek lehetnek a potenciális következő koordinátorok). Ha ezek közül valaki válaszol, az azt jelenti, hogy működőképes és ő akar lenni a koordinátor. Ehhez egy adott Tvk időkorláton belül egy üzenettel koordinátornak kell nyilvánítania magát. Ha az üzenet mégsem érkezik meg Tvk időn belül, ez azt jelenti, hogy a folyamat a választási algoritmus befejeződése előtt meghibásodott. Ekkor újabb választás indul.

Amikor egy meghibásodott folyamat újra indul, azonnal választást kezdeményez. Amennyiben ennek a folyamatnak a legnagyobb prioritású az azonosítója, akkor úgy dönt, hogy ő lesz a koordinátor, még akkor is, ha a korábbi koordinátor működőképes. Ezért kapta az algoritmus a nevét, vagyis, hogy erőszakos, hisz minden körülmények között a legmagasabb prioritású működő folyamat lesz a koordinátor.

Az algoritmus működésének bemutatására tekintsük az alábbi egyszerű példát (4.9. ábra):

Négy folyamat alkotja a folyamatcsoportot, ezek P1, P2, P3 és P4. P2 észreveszi a P4-es koordinátor folyamat meghibásodását, és egy választást kezdeményez. (a 4.9. ábra 1. lépése). A választás üzenet elküldése után P2 Tvv ideig vár a válaszra, ami azt jelzi, hogy P3 él, így ő lehet a koordinátor. A 2. lépésben P3 visszaküldi a választ P2-nek. Ekkor P2 Tvk ideig ismét elkezd várakozni, hogy P3 bejelentse, hogy ő lett a koordinátor. Ekkor P3 meghibásodik (3. lépés). Mivel P2 az időkorláton belül nem kapott koordinátori üzenetet, magát tekinti megválasztott koordinátornak, így egy koordinátor(P2) üzenetet küld P1-nek. Egy idő után a P4-es folyamat újra indul, és azonnal értesít mindenkit, hogy ő a koordinátor.

4.9. ábra. ábra - Bully algoritmus. P2 kordinátorrá választása P4 és P3 meghibásodása után. Majd P4 koordinátorrá választása annak újraindulása után

Bully algoritmus. P2 kordinátorrá választása P4 és P3 meghibásodása után. Majd P4 koordinátorrá választása annak újraindulása után


Az algoritmus során küldött üzenetek száma. A legkedvezőbb esetben a második legnagyobb prioritású folyamat veszi észre a koordinátor meghibásodását és kezdeményez választást. Ekkor rögtön megválaszthatja magát, és szétküld (n-2) koordinátor üzenetet az alacsonyabb prioritású folyamatoknak. A legrosszabb esetben a Bully algoritmus O(n2) üzenetet igényel. Ebben az esetben a legkisebb prioritású folyamat észleli a koordinátor meghibásodását, és mind az (n-1) folyamat választást kezdeményez, választás üzeneteket küldve a magasabb prioritású folyamatoknak.

A gyűrű algoritmus

A folyamatcsoportban lévő folyamatokat egyirányú logikai gyűrűbe kell szervezni. Ez nem jelent megkötést a fizikai topológiára. Ebben az esetben feltételezzük, hogy az egyes folyamatok nem ismerik egymás azonosítóit, így prioritásukat sem, csak azt tudják, hogyan kell kommunikálni az egyik, mondjuk az óra járásával megegyező szomszédjukkal. Az algoritmus célja a legnagyobb prioritású egyedi koordinátor megválasztása. Az algoritmus feltételezi, hogy a folyamatok az algoritmus alatt nem hibásodnak meg, és elérhetők maradnak.

Kezdetben minden folyamat a választásban nem résztvevőnek van jelölve. Bármelyik folyamat kezdeményezhet választást. Ekkor első lépésben választásban résztvevőnek jelöli magát, és az azonosítóját egy választás üzenetben elküldi a szomszédjának.

Amikor egy folyamat egy választás üzenetet kap, összehasonlítja az üzenetben foglalt azonosítót a sajátjával. Amennyiben a beérkezett azonosító nagyobb, a folyamat továbbítja az üzenetet a szomszédjának. Azonban, ha a beérkezett azonosító kisebb a saját azonosítójánál, akkor a folyamat először megvizsgálja, hogy résztvevő-e. Amennyiben nem, akkor az üzenetben lecseréli az azonosítót a sajátjára, és résztvevőnek jelöli magát, majd továbbítja a választás üzenetet a szomszédjának. A folyamat akkor is résztvevő-nek jelöli magát, ha nem cserélte le az azonosítót.

Amennyiben az azonosító megegyezik az üzenetet kapó folyamat saját azonosítójával, akkor a kör bezárult, a folyamat a legnagyobb prioritású folyamat a körben, ő lesz a koordinátor. A folyamat nem résztvevőnek jelöli magát, és egy megválasztott üzenetet küld a szomszédjának a saját azonosítójával, így tudatva a koordinátor kilétét.

Ha egy nem koordinátor folyamat megválasztott üzenetet kap, magát nem résztvevőnek jelöli, megjegyzi a koordinátor azonosítóját és továbbítja az üzenetet a szomszédjának.

Folyamatok résztvevőnek, illetve nem résztvevőnek jelölésének az értelme akkor domborodik ki, amikor egyszerre több folyamat kezdeményez választást. Ekkor a fenti jelöléseket ki lehet használni, és minimalizálni lehet az üzeneteket.

Az algoritmus során küldött üzenetek száma. Ha csak egy folyamat kezdeményezi a választást, akkor a legrosszabb eset olyankor áll fenn, amikor a kezdeményező óra járásával ellentétes szomszédja birtokolja a legmagasabb azonosítót.

4.10. ábra. ábra - A gyűrű választási algoritmus működése. A választást most a 19-es csomópont kezdeményezte

A gyűrű választási algoritmus működése. A választást most a 19-es csomópont kezdeményezte


Ekkor ezen szomszéd eléréséhez n-1 üzenet szükséges, amely addig nem nyilvánítja magát koordinátornak, amíg a saját üzenetét vissza nem kapja újabb n üzenettel később. Ekkor a megválasztott üzenet is n-szer megjelenik, így összesen 3n-1 üzenetre van szükség. A 4.10. ábra egy gyűrűs választási algoritmust mutat. A választást a 19-es folyamat kezdeményezte. A választás üzenet jelenleg a 33-as azonosítót tartalmazza, de a 45-ös folyamat ezt majd lecseréli a saját azonosítójára, ha majd megkapja az üzenetet. A jelölt körök a résztvevő folyamatokat jelölik.

4.4.5. Elosztott rendszerek biztonsági kérdései

Az elosztott rendszerek fokozottan ki vannak téve a különféle biztonsági ve­szé­lyeztetéseknek. Bár a biztonság megteremtéséhez szükséges eszközök többsége adott, alkalmazásuk azonban alapos tervezést és széles körű vizsgálatokat igényel.

Elosztott rendszerek biztonságát különböző biztonsági módszerek alkalmazásával érthetjük el. Ezen módszerek azonban nem alkalmazhatóak önállóan, vagy folyamatosan bővíthetően – a rendszer egyidejű, a kívánalmaknak megfelelően teljes körű védelmére van szükség. Egy elosztott, nyílt rendszerben a teljes körű biztonság megteremtése egyetlen rendszerrel nem valósítható meg. Helyi, egyes gépeket, szolgáltatásokat védő rendszerek telepítése könnyebb feladat, ezek azonban egy elosztott rendszerben kezelhetetlenül bonyolultá tehetik a rendszert. A felhasználók által megjegyzendő jelszavak számának minimális szinten tartása megköveteli, hogy egy elosztott rendszerben egyetlen azonosítás elegendő legyen a teljes rendszer használatára.

Nem elegendő a módszerek teljes körű alkalmazása sem: a biztonság meg­teremtésére és megőrzésére ún. biztonságpolitikára is szükség van. Nem elegendő a módszerek bevezetése, azok alkalmazását is pontosan szabályozni kell. Hiába alkalmazzuk a lehető legkifinomultabb, legbiztonságosabb azonosító rendszert, ha a felhasználók az íróasztalukon kitűzve tárolják jelszavaikat. A biztonságpolitikának a módszerek helyes alkalmazásán kívül hangsúlyt kell fektetnie a felhasználók oktatására és ellenőrzésére is.

4.4.5.1. Mi a biztonság?

Egy rendszer biztonsága alatt különböző emberek különböző dolgokat értenek. A számítógépeket használók többsége a számítógépes vírusokra és az In­ter­net-kalózok támadásaira gondol, ha a számítógépek biztonságáról van szó. Mások a bizalmas adatok védelmét, titkosságát és a hozzáférés szabályozását értik e fogalom alatt. Egy rendszer biztonságossá tétele mindezen problémák kezelését megköveteli. Általában a következő területeket értjük alatta:

  • Azonosítás (authentication). Felhasználók és számítógépek megbízható és egyértelmű azonosítása, üzenetek biztonságos aláírása és bizonyos események, akciók egyértelmű rögzítése.

  • Felhatalmazás (authorization). A felhasználók, számítógépek és programok által végrehajtható akciók nyilvántartása.

  • Titkosítás (encryption). Hozzáférés szabályozása bizalmas információk­hoz.

  • Rendszer védelem (system protection). A rendszerek megbízható és folyamatos működésének biztosítása (vírus védelem, szolgáltatások folyamatos fenntartása, véletlen rendszerhibák elkerülése).

4.4.5.2. Kik a támadók és mik a fenyegetések?

Elosztott rendszerekben tárolt információ megszerzésére, illetve a rendszerek működésének megzavarására emberek és programok (folyamatok) törekedhetnek. A továbbiakban a támadó kifejezést alkalmazzuk az elosztott rendszerben tárolt információt vagy erőforrást illetéktelenül megszerezni próbáló ügynökre. A támadó a rendszer valamilyen biztonsági hibáját használja ki a támadás véghezvitele során. A biztonsági hiba lehet a biztonsági módszerek vagy a biztonságpolitika hibája.

A következő főbb fenyegetés fajták léteznek:

  • jogosulatlan megbízók információszerzése,

  • információ (beleértve programokat is) jogosulatlan módosítása,

  • az erőforrások jogosultság nélküli használata,

  • zavarkeltés a rendszer megfelelő működésében anélkül, hogy a támadónak ebből haszna származna.

4.4.5.3. A támadás módszerei

A fenyegetések valóra váltásához hozzá kell férni a rendszerhez. Ennek legelterjedtebb módjai:

  • Lehallgatás. Az elosztott rendszer komponensei közötti üzenetváltásokról jogosultság nélküli információ szerzése. Ez történhet úgy is, hogy a támadó közvetlenül a hálózatról szerzi be az üzeneteket, vagy nem megfelelően védett tárolt információt olvas el.

  • Maszkírozás. Egy felhasználó vagy program rendszerbeli azonosítóját használva a támadó üzenetet küld, illetve fogad a megfelelő jogosultságok nélkül.

  • Üzenetmódosítás. A támadó üzeneteket fog el és megváltoztatja a tartalmukat, majd a megváltoztatott üzenetet továbbküldi a rendszer megtévesztése céljából.

  • Visszajátszás. A támadó a rendszer egy üzenetét eltárolja, és egy későbbi időpontban újra lejátssza. A visszajátszás ellen nem lehet egyszerű titkosítással védekezni, mert a visszajátszást használni lehet erőforrás lopásra és vandalizmusra is, még akkor is, ha a támadó nem érti az üzenetet.

A fenti támadások véghezviteléhez a támadónak hozzá kell férnie a rendszerhez, hogy futtathassa a programot, amely megvalósítja a támadást. A legtöbb támadásért a rendszer jogosult felhasználói a felelősek nem megfelelő jelszóhasználati gyakorlatukkal. A legegyszerűbb beszivárgási módszer a jelszó feltörés, vagyis a szisztematikus próbálgatás. Léteznek szótárak, amelyek a leggyakrabban használt jelszavakat tartalmazzák. Ez ellen megbízható jelszó választásával lehet védekezni.

4.4.5.4. Az elosztott biztonsági rendszer tervezése

Elosztott rendszerekben a fenyegetettség fő forrása a kommunikációs csatornák nyitottsága. Fel kell tételezni, hogy a rendszer minden szintjén lévő kom­mu­nikációs csatorna és program ki van téve a fenti fenyegetéseknek. A lehetséges betolakodókat nem könnyű azonosítani, így olyan világnézetet kell alkalmazni, amely nem feltételez bizalmat. De ahhoz, hogy használható rendszert építhessünk, néhány megbízható komponensből kell kiindulni. Egy ha­té­kony tervezési megközelítés lehet annak feltételezése, hogy minden kommunikáció megbízhatatlan forrásból jön, amíg az ennek ellenkezőjét nem bizonyítja. A kommunikáló felek megbízhatóságát minden egyes kommunikációs csatornahasználatkor bizonyítani kell.

A biztonság megvalósítására használt mechanizmusokat nagy gonddal kell ellenőrizni, például egy biztonságos kommunikációs protokollnak és az azt megvalósító programnak bizonyíthatóan helyesnek kell lenni az összes lehetséges üzenet szekvenciára. A bizonyításnak ideális esetben formális alapokon kell nyugodnia.

A biztonsági rendszer tervezése során elsősorban nem a biztonsági módszerek „erőssége” befolyásolja a teljes rendszer biztonságát, hanem alkalmazásuk körülményei és teljessége. Biztonsági rendszerek véleményezése során a felhasználók gyakran esnek a technikai részletek elsődleges minősítésének hibájába. Sokkal jobban figyelnek a titkosításban alkalmazott kulcsok hosszára, mintsem alkalmazásuk helyességére és teljességére. A biztonsági rendszerek tervezésének első aranyszabálya szerint tökéletes biztonság nem létezik. A biztonság mindig a védendő rendszer értékének és a biztonsági rendszer kiépítési költségének kompromisszumán alapszik. Drágább és jobb technológia alkalmazása javíthatja a rendszer biztonságát, azonban mindig létezni fog sikeres (és egyre költségesebb) támadási technika a rendszer ellen. A rendszer védelmi mechanizmusait úgy kell megválasztani, hogy a támadó által elérhető nyereség (vagy okozott kár) mindig lényegesen kevesebb legyen a támadás költségénél.

A rendszer tervezésének második aranyszabálya szerint a legtöbb biztonsági problémát mindig az emberek viselkedése okozza. Semmilyen biztonsági mechanizmus nem lehet sikeres, ha használói nem viselkednek biztonságos módon. Ezért a rendszer tervezése során olyan megoldásokat és módszereket kell alkalmazni, melyek ösztönzik a felhasználók biztonságos viselkedését.

Az összes biztonsági technika három alapvető mechanizmuson alapszik: titkosításon, azonosítási mechanizmusokon, és hozzáférés szabályozáson.

4.4.5.5. Titkosítás

Biztonságos rendszerek megvalósításában a titkosítási módszerek központi szerepet játszanak. Amikor valamilyen információt titkosítunk, akkor egy olyan transzformációt végzünk rajta, ami az inverz transzformáció ismerete nélkül lehetetlenné (pontosabban praktikusan lehetetlenné, vagy a titkosított adatok értékéhez mérten lényegesen költségesebbé) teszi az információ visszafejtését. A gyakorlatban használt titkosítási algoritmusok két nagy cso­portba oszthatók: titkos kulcsú és nyilvános kulcsú titkosítási algoritmusok.

A titkos kulcsú titkosítás során a sima szöveget egy előre megegyezett függvénnyel titkosítják, egy titkos kulcsot használva. A megfejtés során az inverz függvényt kell alkalmazni ugyanazon titkos kulccsal. Így, ha biztosítjuk, hogy a titkos kulcsot csak a kommunikációban résztvevő két folyamat birtokolja, akkor az információ titkosságát biztosítottuk. Mivel a kulcsokat titokban, mások elől elrejtve tartjuk, így a függvényt, illetve az inverz függvényt nem kell titokban tartani.

Általánosságban a titkosító függvény és annak inverze lehet különböző, de választható olyan függvény is, amelynek az inverze megegyezik magával a függvénnyel. A gyakorlatban ilyen függvényeket alkalmaznak. A titkosító algoritmusnak biztonságosnak kell lennie szisztematikus feltörési kísérletekkel szemben is. A leggyakoribb ilyen próbálkozás, hogy a rendelkezésre álló sima szöveg, és a hozzá tartozó titkosított szöveg alapján megpróbálják kitalálni a kulcsot, illetve titkosított szövegekre alkalmazzák az inverz függvényt véletlenül megválasztott kulccsal, és ha az eredmény értelmesnek tűnik, akkor a kulcs helyes.

A nyilvános kulcsú titkosítás egy olyan titkosító módszer, amelyben a kommunikáló feleknek nem kell bízni egymásban. A kommunikációban minden egyes résztvevő létrehoz egy kulcspárt, egy kódoló és egy dekódoló kulcsot. A dekódoló kulcsot titokban tartja (titkos kulcs), a kódoló kulcsot nyilvánosságra hozza (nyilvános kulcs). Mindenki, aki titkos üzeneteket szeretne küldeni neki, a kódoló kulcs segítségével titkosítja az üzenetét, melyet csak a dekódoló kulccsal rendelkező fél tud visszafejteni. A módszer a két kulcs között kapcsolatot teremtő olyan függvényen alapul, amelyre a kódoló kulcs ismeretében nagyon nehéz meghatározni a dekódoló kulcsot. A függvény olyan Y = f(X) függvény, amelyre X kiszámítása Y ismeretében annyira számításigényes, hogy gyakorlatilag kivitelezhetetlen. Ez a nyilvános kulcsú titkosítás, amely során nincs szükség titkos kulcsok küldözgetésére a kommunikációs csatornán. A módszer két nagyon nagy prímszám szorzatának használatán alapul, kihasználva azt a tényt, hogy ilyen nagy számok prímfelbontásának meghatározása olyan számításigényes, hogy gyakorlatilag kivitelezhetetlen. (Megjegyzendő, hogy matematikailag nem bizonyított, hogy nem létezik gyors felbontási algoritmus, de praktikusan elfogadott tény.)

A titkosítás alkalmazható bizalmas információk elrejtésére, amikor csak az fejtheti meg az üzenetet, aki birtokolja a megfejtéséhez szükséges kulcsot. A módszer kommunikáció hitelesítésénél segédeszközként is használatos. Ha a vevő sikeresen dekódol egy üzenetet, feltételezheti, hogy az hiteles forrásból származik, mert a küldő ismerte a kulcsot. Az azonosítás finomabb formájának, a digitális aláírás létrehozásában is alkalmazható. Ennek feladata azt ellenőrizni, hogy az üzenet valóban sértetlenül és a feltételezetett feladótól érkezett-e meg, valamint annak biztosítása, hogy a feladó a későbbiekben ne tagadhassa le az üzenet elküldését.

4.4.5.6. Hozzáférés-szabályozás

A hozzáférés-szabályozás feladata az adatokhoz és erőforrásokhoz való hozzájutás szabályozása és korlátozása az azonosított felhasználók és programok körére. A hozzáférés-szabályozás az erőforrások használóinak azonosítása után az erőforrás használati szabályok (például időpont – erőforrás – felhasználó mátrix) alapján engedélyezi vagy tiltja meg a hozzáférést.

4.4.5.7. Azonosítás

Az azonosítás az elosztott rendszer résztvevőinek egyértelmű és megbízható hitelesítését jelenti. Centralizált többfelhasználós rendszerekben viszonylag egyszerűen meg lehet oldani az azonosítást: a munkamenet elején valamilyen jelszó ellenőrzéssel hitelesíteni lehet a felhasználót (vagy programot), és az azonosítás után a munkamenetet egy olyan tartománynak lehet tekinteni, amelyben az összes műveletet az azonosított felhasználó nevében lehet elvégezni. Ez a megközelítés feltételezi a rendszer erőforrásainak centralizált kezelését, ami nehezen oldható meg, vagy általában nem kívánatos elosztott rendszerekben.

Elosztott rendszerekben a hitelesítést általában egy kitüntetett szolgáltatás – az azonosító szolgáltatás – végzi, amely titkosítási eszközöket használ a feladat megoldására. A rendszer elosztott szolgáltatásai az azonosító szolgáltatást használhatják fel a felhasználók (és programjaik) azonosítására.

4.4.5.8. Azonosítás és kulcs szétosztás

Titkos kulcsú rendszerekben régebben a kulcsokat valamilyen más hordozón osztották szét. Például papíron oda lehet adni a kulcsot, majd később megsemmisíteni. Ez a módszer elosztott számítógépes hálózatokban nehezen járható megoldás, általában valamilyen más titkosítási mechanizmust alkalmaznak a titkos kulcsok átvitelére. A titkos kulcsok tárolására és elosztására speciális kulcsszervereket lehet használni, de a hitelesítésre nagy gondot kell fordítani.

Nyilvános kulcsú titkosítás esetén a nyilvános kulcs megkapóinak biztosnak kell lenniük, hogy a kapott kulcs hiteles, vagyis annak a kulcspárnak a nyilvános része, amelynek titkos kulcsát a kommunikációs partner birtokolja. Ellenkező esetben egy ál partner bizalmas információkhoz juthat, ha hamis nyilvános kulcsot ad. A hitelesség biztosítására elektronikus aláírásokat lehet használni.

A hitelesítés és a kulcsok biztonságos szétosztását Needham és Schroeder hitelesítő szerveren alapuló hitelesítési és kulcs szétosztási algoritmusán keresztül mutatjuk be. A hitelesítő szerver feladata, hogy folyamat pároknak biztonságos módon kulcsot biztosítson a kommunikációjukhoz. Ehhez a klienseivel a szerver titkosított üzenetekkel kommunikál. A továbbiakban az algoritmus titkos kulcsokon alapuló változatát tekintjük át.

A következőkben a Needham–Schroeder titkos kulcsú hitelesítési protokoll egyes lépéseit foglaljuk össze. A példában két állomás (A és B) a hitelesítési szerver (S) segítségével vált üzenetet. Az üzenetváltásban felhasználják kettőjük K titkos és nyilvános kulcsait.

A protokoll egyik gyenge pontja, hogy B-nek nincs információja arról, hogy a 3. üzenet friss. Egy behatoló megszerezheti a KAB kulcsot és a {KAB, A}KB hitelesítőt, és akkor A-nak adhatja ki magát. Ez a probléma időcímke használatával küszöbölhető ki. Az algoritmusnak létezik nyilvános kulcson alapuló változata is, de helyszűke miatt itt azzal nem foglalkozunk.

4.4.5.9. Kerberos: hitelesítési protokoll nyílt hálózati rendszerekre

A Kerberos egy titkos kulcsú titkosításon (DES) alapuló hitelesítési rendszer, melyet az MIT (Massachusetts Institute of Technology) fejlesztett ki az Athena projekt keretében. A Kerberos rendszerben a szolgáltatások igénylőit (legyenek azok felhasználók vagy programok) kliensnek, a szolgáltatásokat nyújtó programokat pedig szervernek nevezzük. A rendszer ún. megbízó leveleket (credentials) alkalmaz a hozzáférés-szabályozás megoldására. A megbízó levelek beszerzésének mechanizmusa a Kerberos azonosító rendszere.

A Kerberos egy megbízható kívülálló hitelesítési szerviz, amely a korábban ismertetett Needham és Schröder-modellen alapul. A rendszer a módszert kiegészíti az időbélyegek alkalmazásával.

A Kerberos tartalmaz egy adatbázist a klienseiről és szerverekről, illetve ezek kulcsairól. A kliensek és szerverek privát kulcsát csak a Kerberos, illetve a kulcs tulajdonosa ismeri. Felhasználók esetén a privát kulcs egy titkosított jelszó.

A Kerberos a titkos kulcsok ismeretében képes egyrészt a kommunikáló felek azonosítására, másrészt titkosított üzenetváltásra a rendszer minden sze­replőjével. A felek egymás közötti (a Kerberostól független) kommunikációjához a Kerberos ún. viszonykulcsot (session key) ad, mely egy adott kapcsolatban felhasználható az üzenetek titkosítására.

A Kerberos három különböző védelmi szintet határoz meg. Az alkalmazást készítő programozó választja ki ezek közül az alkalmazások igényeinek leginkább megfelelőt. Az alkalmazások egy részében elegendő a megbízható azonosítás a kapcsolat kezdetén (például az NFS esetében). Ennél egy szinttel magasabban minden egyes üzenetváltásnál szükséges a felek azonosítása. A harmadik szinten nemcsak az azonosítás, hanem az üzenetek titkosítása is megoldható.

Egy kliens csak akkor használhat egy szervizt, ha már korábban szerzett erre egy jegyet, azaz speciális megbízólevelet. Ezt kell bemutatnia a szervernek, annak bizonyítása céljából, hogy valóban jogosult a szerviz használatára. Ilyen jegy beszerzéséhez a kliensnek előbb azonosítania kell magát a Kerberos rendszer számára, majd egy megbízólevelet kell szerezni az ún. jegyosztóhoz (ticket granting service – TGS).

A jegyet tehát egyetlen szerver-kliens pár között használjuk. A jegy tartalmazza a szerver nevét, a kliens nevét, a kliens Internet-címét, egy időbélyeget, egy lejárati időt, és egy viszonykulcsot. A kibocsátott jegyet a kliens mindaddig használhatja a szerver elérésére, míg az érvényes. Mivel ezen jegy titkosított a szerver kulcsával, ezért a szerveren kívül más nem tudja ezt értelmezni, így szabadon átadható a kliensnek, mely nem tudja módosítani.

A kerberos jegy: {s,c,addr,timestamp,life,Ks,c}Ks

Ettől eltérően a hitelesítő jegyet a kliens csak egyszer használhatja, minden olyan esetben újat kell generálnia, amikor egy új szervizt akar használni. A hitelesítő jegy a következőket tartalmazza: a kliens nevét, a munkaállomás IP címét, és a munkaállomás aktuális idejét. A hitelesítő jegyet a szerverre és kliensre kiadott kapcsolati kulcssal titkosítja.

A kerberos hitelesítő: {c,addr,timestamp}Ks,c

A rendszerbe lépéskor az azonosítás a Kerberos szerver segítségével történik a felhasználó jelszavát használva. Az azonosítás után a Kerberos szerver állít ki olyan megbízóleveket, melyek a kliens hitelességét bizonyítják. Ilyen megbízólevéllel lehet a jegyosztótól a különböző szolgáltatásokhoz jegyet kérni. Az azonosításhoz a felhasználó átadja a felhasználói nevét és a TGS nevét a Kerberos szervernek. A Kerberos szerver ellenőrzi ezt a klienséről tárolt információk alapján. Ha rendben találja, akkor generál egy véletlen viszonykulcsot (Kc,tgs), amelyet később a kliens és jegyosztó szerver fog használni egymás közötti kommunikációjukra. A Kerberos ezenkívül elkészíti a jegyet (Tc,tgs) a TGS számára, amely tartalmazza a kliens nevét, a TGS nevét, az aktuális időt, a jegy élettartamát, a kliens IP-címét és az elkészített random viszonykulcsot (Kc,tgs). Ezt a jegyet a TGS privát kulcsával titkosítja (Ktgs), ily módon biztosítva, hogy a kliens ezt ne tudja megváltoztatni.

A hitelesítő szerver ezután visszaküldi a kódolt jegyet és a Kc,tgs viszony- kulcsot a kliensnek, annak privát kulcsával titkosítva (Kc). Ez lesz a válaszüzenet a felhasználó jelszavára. Ezzel véget ért a bejelentkezési folyamat. Most már a kapott jegy (Tc,tgs) segítségével a kliens a TGS-től beszerezheti a kívánt szerverre a megbízásokat (amíg a jegy élettartama le nem jár).

A Kerberos előnyös tulajdonságai:

  • titkosítja a rendszerben áramló adatokat,

  • nagyon megbízható,

  • TCP/IP protokollra implementálták,

  • a felhasználói felületen semmit sem kell változtatni,

  • sohasem kerül fel a hálózatra kódolatlan jelszó.

Hátrányai:

  • a Kerberos szerver egy kitüntetett gép a rendszerben, ezért ennek biztonságossága az egész rendszerét meghatározza (fizikailag is védeni kell),

  • a Kerberos szerver döntései mindenki számára elsődlegesek,

  • az összes szoftvert újra kell fordítani, „Kerberizálni”, hogy azok Kerbe­ros hívásokat használjanak.