HDFS este un sistem de fişiere distribuit implementat în cadrul Hadoop, diferenţa faţă de alte sisteme de fişiere de acest tip constând în faptul că este proiectat să ruleze pe dispozitive mai puţin performante, fiind capabil să gestioneze în mod coerent erorile. De asemenea, oferă un nivel de accesibilitate ridicat la datele aplicaţiei, fiind adecvat pentru aplicaţii care utilizează un volum de date de dimensiuni foarte mari. Pentru utilizator, sistemul de fişiere apare ca un singur disc, rulând peste sistemele de fişiere locale (ext4, xfs) şi fiind bazat pe conceptele dezvoltate de sistemul de fişiere Google (GFS).
Presupunerile de la care a plecat proiectarea sistemului de fişiere distribuit HDFS sunt:
Arhitectura HDFS este de tip master – slave şi conţine un nod de nume (eng. NameNode), server ce gestionează spaţiul de nume al sistemului de fişiere, reglementând accesul la fişiere şi mai multe noduri de date (eng. DataNode, de regulă unul pentru fiecare nod din cluster), client ce gestionează spaţiul de stocare ataşat nodurilor pe care rulează. În plus faţă de acestea mai există şi un nod de nume secundar (eng. Secondary NameNode) care se ocupă mai ales cu întreţinerea sistemului distribuit de fişiere, astfel încât acest proces să nu fie realizat doar la nivelul nodului de nume. Acesta nu este utilizat pentru asigurarea unui nivel de disponibilitate ridicat şi nici nu funcţionează ca rezervă pentru nodul de nume. Deşi pentru utilizator spaţiul de nume este vizualizat unitar, permiţând operaţiile uzuale de încărcare şi descărcare de fişiere (ca pentru orice sistem de fişiere), implementarea HDFS presupune împărţirea acestora în blocuri care sunt stocate în mai multe noduri de date. Dacă nodul de nume se ocupă cu operaţii legate de spaţiul de nume al sistemului de fişiere (deschidere, închidere, redenumire fişiere şi directoare), determinând şi maparea blocurilor la nodurile de date, nodurile de date au rolul de a trata cererile de citire şi de scriere ce provin de la utilizatori, realizând şi crearea şi ştergerea de blocuri, respectiv replicarea, în funcţie de instrucţiunile ce provin de la nodul de nume.
Atât nodul de nume cât şi nodul de date sunt programe scrise în Java, astfel încât pot să ruleze pe cât mai multe platforme. Tipic, nodul de nume rulează pe un server dedicat, în timp ce toate celelalte maşini din cluster conţin o instanţă a nodului de date. Există şi posibilitatea ca pe o singură maşină să existe mai multe instanţe ale nodului de date, însă un astfel de caz este destul de rar. Situaţii de acest tip pot fi întâlnite în situaţia în care se doreşte separarea seturilor de date provenind de la aplicaţii diferite. Existenţa unui singur nod de nume într-un cluster simplifică foarte mult arhitectura sistemului, întrucât nodul de nume negociază utilizarea resurselor şi reţine toate metadatele cu privire la fişierele stocate. Toate datele provenite de la utilizator sunt prelucrate neapărat de nodul de date.
Aşadar, arhitectura HDFS este organizată pe două niveluri:
În mod tradiţional, HDFS implementează o organizare a fişierelor de tip ierarhic, astfel încât un utilizator sau o aplicaţie pot crea directoare, stocând fişiere în cadrul acestora. Operaţiile suportate sunt de creare şi ştergere fişiere, relocarea unui fişier dintr-un director într-altul precum şi redenumirea unui fişier. Nu sunt implementate cote pentru utilizatori şi permisiuni de acces, dar nici obiecte de tip legătură (hard sau soft). Întreţinerea spaţiului de nume pentru sistemul distribuit de fişiere este realizat de către nodul de nume astfel că acesta înregistrează orice schimbare operată asupra sa sau proprietăţilor sale.
HDFS este proiectat pentru a stoca fişiere de dimensiuni foarte mari distribuite pe maşini în cadrul unui cluster ce conţine numeroase maşini. Astfel, fiecare fişier este reţinut ca o secvenţă de blocuri, de dimensiuni egale, fiecare dintre acestea fiind replicate pentru asigurarea toleranţei în cazul producerii de erori.
O aplicaţie poate specifica numărul de replici ale unui fişier ce ar trebui întreţinute de HDFS precum şi dimensiunea blocului. Aceste valori pot fi modificate ulterior.
Fişierele pot fi scrise o singură dată şi de către un singur proces la un moment dat de timp. Deciziile referitoare la replicarea unor blocuri sunt luate doar de nodul de nume. Acesta primeşte periodic rapoarte cu privire la blocuri de la fiecare nod de date din cluster, aceasta implicând funcţionarea corespunzătpare a nodului de date respectiv. Perioada între care se transmit rapoartele cu privire la blocurile conţinute de nodurile de date se numeşte bătaie de inimă (eng. heartbeat). Un raport conţine lista tuturor blocurile reţinute de un nod de date.
Modul în care sunt plasate replicile de către nodul de nume este esenţial pentru siguranţa şi performanţa HDFS motiv pentru care în implementarea acestui sistem distribuit de fişiere s-a pus în mod deosebit accentul pe optimizarea acestui proces. Deşi politica de distribuţie a replicilor nu a ajuns încă la forma finală, s-au realizat etape importante în dezvoltarea acesteia prin identificarea unui criteriu legat de rastelul (eng. rack) pe care se găseşte blocul ce se doreşte a fi replicat. Astfel, se are în vedere îmbunătăţirea disponibilităţii dar şi al utilizării lăţimii de bandă. Localizarea replicilor trebuie să ţină cont de faptul că lăţimea de bandă între două noduri ce aparţin unor rasteluri diferite este mai mică decât lăţimea de bandă între două noduri care fac parte din acelaşi rastel. Astfel, în cazul implicit (nivelul de replicare 3), politica de plasare a replicilor a HDFS este de stoca o replică pe un nod făcând parte din rastelul local, altă replică pe un alt nod din acelaşi rastel şi o alta pe un nod diferit dintr-un rastel diferit. În acest mod, se optimizează traficul între rasteluri diferite, îmbunătăţindu-se performanţa operaţiilor de scriere. Probabilitatea ca întregul rastel să nu fie disponibil datorită unei erori este mult mai mică decât cea ca un singur nod din cadrul rastelului să se defecteze, astfel că o acest tip de politică nu afectează garanţiile cu privire la disponibilitatea datelor. Totodată, se reduce lăţimea de bandă agregată când sunt citite datele, întrucât același bloc este plasat pe două rasteluri (în loc de trei). Printr-o astfel de politică, fişierul nu este distribuit în mod uniform în cadrul rastelurilor din cluster. Astfel, o treime dintre replici se găsesc pe nodul local, două treimi dintre replici sunt plasate pe rastelul local, cealaltă treime dintre replici fiind distribuite uniform de-a lungul celorlalte rasteluri.
Prin urmare, politica de distribuire a replicilor în cadrul clusterului îmbunătăţeşte performanţa operaţiei de scriere fără a se compromite nici siguranţa datelor şi nici performanţa operaţiei de scriere.
Pentru a se minimiza consumul global al lăţimii de bandă dar şi latenţa pentru operaţiile de citire, o citire de date se va realiza din locaţia cea mai apropiată de utilizatorul care a realizat o astfel de cerere. Astfel, în cazul în care există o replică pe acelaşi rastel ca nodul care realizează citirea, aceasta va fi preferată unei replici care se găseşte la distanţă.
La pornirea sistemului distribuit de fişiere HDFS, nodul de nume intră într-o stare specială denumită mod de siguranţă (eng. safemode) în care nu are loc replicarea de blocuri de date. În această stare, nodul de nume primeşte mesaje de la nodurile de date conţinând rapoarte cu privire la blocurile pe care le conţin fiecare din ele. Pentru fiecare bloc de date se specifică un număr minim de replici, el fiind considerat ca fiind replicat în siguranţă dacă nodul de nume a primit de la nodurile de date rapoarte cu privire la întrunirea acestei valori. Părăsirea modului se siguranţă se face numai după ce există un anumit procent (configurabil) de blocuri care sunt replicate în siguranţă. După depăşirea pragului cu privire la blocurile care sunt replicate în siguranţă, trebuie să mai treacă încă 30 de secunde după care se realizează trecerea din modul de siguranţă în starea de operare obişnuită. Doar în acest moment, nodul de nume identifică blocurile de date care nu dispun de un număr de replici suficiente şi realizează replicarea lor către nodurile de date.
În sistemul distribuit de fişiere HDFS, spaţiul de nume este reţinut de nodul de nume care utilizează în acest scop un jurnal de tranzacţii (EditLog
) pentru a reţine în mod persistent fiecare schimbare care se realizează la nivelul metadatelor. Operaţii precum crearea unui fişier sau modificarea factorului de replicare al unui fişier determină introducerea unei înregistrări în jurnalul de tranzacţii. Întregul spaţiu de nume al sistemului distribuit de fişiere (inclusiv maparea blocurilor de date la fişiere şi proprietăţile sistemului) se reţin într-un fişier denumit FsImage
.
EditLog
), nodul de nume utilizează un fişier în sistemul de fişiere al sistemului de operare gazdă. Acelaşi principiu este utilizat şi pentru stocarea imaginii spaţiului de nume al sistemului de fişiere (FsImage
).
Imaginea spaţiului de nume a sistemului distribuit de fişiere, împreună cu fişierul Blockmap
sunt încărcate în memorie, proiectarea acestora fiind suficient de compactă astfel încât o maşină ce dispune de 4 GB de memorie RAM să poată reţine informaţii despre un număr mare de fişiere şi directoare. La pornirea nodului de nume, acesta citeşte fişierele EditLog
şi FsImage
de pe disc, aplică toate tranzacţiile reprezentării încărcate în memorie a sistemului distribuit de fişiere, rezultatul obţinut fiind stocat şi pe disc sub forma unui fişier FsImage
, eliminând din fişierul EditLog
operaţiile care au fost deja reţinute persistent. Acest proces se numeşte punct de control (eng. checkpoint).
Un nod de date stochează informaţiile HDFS în sistemele de fişiere locale, fiecărui bloc corespunzându-i un anume fişier fără a se cunoaşte semnificaţia sa din perspectiva sistemului distribuit de fişiere. La pornirea nodului de date, sistemul local de fişiere este parcurs, generându-se lista blocurilor de date HDFS ce corespund fiecărui fişier, pe baza acesteia generându-se raportul transmis nodului de nume.
Un nod de date nu stochează toate fişierele în acelaşi director, întrucât pentru sistemul local de fişiere poate fi dificil să gestioneze în mod eficient un număr mare de fişiere localizate într-o singură locaţie. Din acest motiv, este utilizată o euristică pentru a determina numărul optim de fişiere din cadrul unui singur director, creând subdirectoare în mod corespunzător.
Toate protocoalele de comunicaţii din cadrul sistemului distribuit de fişiere HDFS sunt bazate pe protocolul TCP/IP. Un client realizează o conexiune către nodul de nume pe un port (configurabil), transmisia de date făcându-se folosind protocolul ClientProtocol
, la fel cum nodul de date comunică cu nodul de nume folosind protocolul DataNodeProtocol
, acestea fiind abstractizate sub forma unor apeluri la distanţă (eng. Remote Procedure Call). Prin proiectare, nodul de nume nu iniţiază niciodată apeluri la distanţă ci doar răspunde la astfel de apeluri transmise de clienţi sau noduri de date.
Obiectivul sistemului distribuit de fişiere HDFS este reprezentat de robusteţe, adică de a stoca datele în mod sigur chiar şi în situaţia în care au loc anumite defecţiuni. Cele mai frecvente tipuri de defecţiuni sunt datorate erorilor la nivelul nodului de nume, la nivelul nodurilor de date respectiv partiţiilor reţelei de calculatoare.
O defecţiune la nivelul nodului de nume poate fi legată de coruperea fişierelor EditLog
sau FsImage
, care sunt structuri de date centrale ale HDFS. O astfel de situaţie poate determina ca instanţa HDFS să nu mai fie funcţională. Din acest motiv, nodul de nume poate fi configurat astfel încât să întreţină mai multe copii ale acestor fişiere. Astfel, orice modificare realizată la nivelul acestor fişiere va determina propagarea actualizărilor spre copii în mod sincron. La pornirea nodului de nume, sunt selectate cele mai recente versiuni consistente ale fişierelor EditLog
sau FsImage
pentru a fi utilizate. Maşina care găzduieşte nodul de nume reprezintă singura cauză care poate determina defecţiunea întregului cluster HDFS, fiind necesară intervenţia manuală, de vreme ce repornirea automată sau utilizarea unui nod de siguranţă nu sunt implementate.
EditLog
şi FsImage
poate degrada numărul de tranzacţii care pot fi realizate de nodul de nume. Degradarea unei astfel de performanţe poate fi însă acceptată pentru că aplicaţiile care utilizează HDFS sunt intensive în privinţa transferului de date, nu însă şi în privinţa transferului de metadate.
Există posibilitatea ca un bloc de date ce provine de la un nod de date să fie corupt, datorită unor defecţiuni produse la nivelul dispozitivului de stocare, unor erori de reţea sau al unor probleme la nivelul aplicaţiilor. Din acest motiv, HDFS implementează sume de control pentru a verifica conţinutul fişierelor. De fiecare dată când este creat un fişier, se calculează şi sumele de control pentru fiecare bloc al fişierului, acestea fiind stocate în fişiere separate (ascunse) în acelaşi spaţiu de nume. Astfel, atunci când un client primeşte un fişier, verifică şi faptul că datele transmise de fiecare nod de date corespund sumei de control stocate în fişierul asociat. În cazul în care s-a produs o eroare, clientul poate opta pentru a primi blocul de la un alt nod de date ce conţine replica blocului respectiv.
Fiecare nod de date transmite periodic mesaje nodului de nume conţinând rapoate cu privire la blocurile conţinute. O defecţiune produsă la nivelul unei partiţii a reţelei de calculatoare poate face ca unele noduri de date să îşi piardă conectivitatea cu nodul de nume. Acest fapt este detectat prin lipsa mesajelor care ar fi fost transmise în mod normal, astfel încât nodurile de date respective vor fi marcate ca nefuncţionale, astfel încât nu se vor mai realiza cereri pentru operaţii de intrare / ieşire faţă de acestea, replicându-se corespunzător blocurile de date pe care le gestionau.
Arhitectura HDFS este compatibilă cu unele mecanisme de echilibrare (neimplementate încă în versiunea curentă). Astfel, datele vor fi mutate de pe un nod de date pe altul dacă spaţiul disponibil scade sub un anumit prag. De asemenea, în situaţia în care se înregistrează o cerere pentru un anumit fişier din partea mai multor clienţi, se vor crea replici suplimentare, echilibrându-se celelalte date din cadrul clusterului.
De asemenea, vor fi implementate şi instantanee (eng. snapshots), reprezentând copii ale unor date la un moment dat de timp, acestea putând fi utilizate atunci când instanţa HDFS este coruptă, astfel încât să se poată reveni la cea mai recentă configuraţie funcţională, realizându-se recuperarea din eroare cât mai rapid.
O cerere cu privire la crearea unui fişier nu este transmisă instantaneu nodului de nume, informaţiile fiind reținute în fişiere locale temporare până când acestea stochează date ce au o dimensiune echivalentă dimensiunii unui bloc de date. Doar în acest moment este contactat nodul de date care adaugă fişierul la ierarhia sistemului distribuit de fişiere, alocând un bloc de date corespunzător într-un nod de date pe care îl transmite clientului ca răspuns la cererea sa. Ulterior, clientul va transfera informaţiile din fişierul local temporar către nodul de date indicat şi când această operaţie se încheie, nodul de nume înregistrează crearea fişierului ca fiind persistentă. Stocarea temporară a fişierelor pe client este datorată faptului că aplicaţiile care utilizează HDFS au nevoie de fluxuri pentru scriere în fişiere şi în cazul în care un astfel de comportament nu ar fi adoptat, viteza la care operează reţeaua de calculatoare şi congestia ar avea un impact considerabil asupra ratei de transfer, diminuând performanţele încărcării de fişiere.
În momentul în care un client scrie date într-un fişier HDFS, el va primi de la nodul de nume lista nodurilor de date care vor stoca replici ale blocului în cauză. Transferul se va face în secvenţe de 4KB care după ce vor fi stocate de nodul de date, vor fi transmise mai departe următorului nod de date ce va reţine o replică a blocului de date respectiv (în cazul în care secvenţa din blocul de date nu a ajuns încă la toate nodurile de date ce vor conţine replici). Blocurile sunt astfel transmise între nodurile de date care vor reţine replicile sale printr-un mecanism de tip bandă de asamblare.
Similar, atunci când un fişier este şters de un utilizator sau o aplicaţie, acesta nu este îndepărtat din sistemul distribuit de fişiere HDFS ci transferat (pentru o perioadă de timp) în directorul /trash
de unde poate fi recuperat în mod rapid, după care este eliminat din spaţiul de nume, eliberându-se şi blocurile asociate fişierului respectiv în nodurile de date.
/trash
va putea fi configurată de către utilizator. Implicit, fişierele mai vechi de 6 ore sunt şterse. Operaţia de ştergere poate fi anulată doar atâta vreme cât fişierul respectiv se găseşte în directorul /trash
, prin preluarea sa direct de la această locaţie. Acesta conţine cea mai recentă copie a fişierului care a fost şters.
Dacă factorul de replicare al unui fişier este redus, nodul de nume selectează replicile suplimentare care pot fi şterse, astfel încât în cadrul mesajelor periodice schimbate cu nodurile de date va fi transmisă această informaţie, eliberându-se blocurile în cauză cu actualizarea spaţiului liber existent în cluster.
Accesul la HDFS se poate face direct, prin intermediul unui client, disponibil inclusiv din browser, fie prin intermediul unor interfeţe de programare (Java, C++) care obţin metadatele de la nodul de nume (locaţia blocurilor), accesând apoi informaţiile din nodurile de date. Un astfel de model este utilizat inclusiv de MapReduce. Alternativ, comunicaţia dintre clienţi şi HDFS poate fi realizată printr-un server intermediar (eng. proxy), dintre cele care sunt livrate împreună cu Hadoop:
HDFS utilizează un model de permisiuni pentru fişiere şi directoare asemănător modelului POSIX, astfel încât fiecare fişier şi director sunt asociate unui proprietar şi unui grup, specificându-se permisiuni diferite pentru utilizatorul care este proprietar, pentru alţi utilizatori care fac parte din cadrul aceluiaşi grup şi pentru alţi utilizatori.
Pentru fişiere permisiunea r
e necesară pentru a citi un fişier, iar permisiunea w
este solicitată spre a scrie un fişier sau pentru a adăuga informaţii la acesta. În cazul fişierelor, permisiunea x
nu este definită, neexistând noţiunea de fişiere executabile. De aceea, pentru fişiere nu există biţii setuid
sau setgid
, modelul fiind preluat (spre simplificare) şi în cazul directoarelor.
Pentru directoare, permisiunea r
este solicitată pentru a se lista conţinutul acestuia, permisiunea w
pentru operaţiile de creare sau ştergere în timp ce permisiunea x
este necesară pentru a accesa subdirectoarele acestuia. Totodată, poate fi folosit bit-ul lipicios (eng. sticky bit) pentru a împiedica operaţiile de ştergere sau relocare a unui director de altcineva în afară de superutilizator, respectiv proprietarul directorului sau al fişierului.
Permisiunile unui fişier sau director reprezintă modul acestora, reprezentarea sa făcându-se în acelaşi fel ca în Unix (inclusiv reprezentarea octală). În momentul în care este creat un fişier sau director, proprietarul său este determinat de identitatea utilizatorului autentificat în cadrul procesului care emite comanda iar grupul său este dat de grupul directorului părinte (regula BSD). Identitatea fiecărui proces care accesează sistemul distribuit de fişiere HDFS este compusă din numele utilizatorului şi lista de grupuri. Verificarea permisiunilor pentru un fişier sau un director se face prin compararea numelui utilizatorului cu proprietarul obiectului sau, în caz că acestea nu coincid prin compararea grupului obiectului cu membrii listei de grupuri. Dacă nu se identifică nici o potrivire, se testează celelalte permisiuni ale obiectului care se doreşte a fi accesat. O operaţie asupra unui fişier sau asupra unui director nu poate fi realizată dacă nu sunt întrunite drepturile necesare.
HDFS permite administratorului să stabilească anumite cote pentru numărul de denumiri folosite şi pentru spaţiul de stocare utilizat pentru fiecare director în parte. Operarea celor două tipuri de cote se realizează independent, însă modul de utilizare al acestora este asemănător.
Cota pentru numărul de denumiri este o constrângere referitoare la numărul de fişiere şi directoare din ierarhia aflată sub directorul indicat ca parametru. Astfel, nu vor putea fi create sau redenumite fişiere sau directoare în cazul în care nu se verifică această constrângere. Stabilirea unei cote va putea fi realizată şi în cazul când valoarea specificată va determina o violare a constrângerii. Un director nou creat nu are nici o cotă asociată. Cea mai mică cotă, 1, forţează un director să rămână gol (denumirea directorului este contorizată în cadrul cotei). Cea mai mare cotă este Long.Max_Value
.
Cota pentru spaţiul de stocare reprezintă o constrângere cu privire la numărul de octeţi utilizaţi de fişierele aflate în ierarhia directorului dat ca parametru. Alocarea unui bloc va eşua în cazul când cota respectivă nu ar permite scrierea întregului bloc. Fiecare replică a unui bloc va fi contorizată în cadrul cotei. Cotele vor fi menţinute şi în cazul redenumirii unui director (operaţia de redenumire va eşua însă în cazul în care prin aceasta se va încălca cota cu privire la spaţiul de stocare). Un director nou creat nu are nici o cotă asociată. Cota minimă este 0, permiţând totuşi crearea unui fişier (fără a se putea adăuga blocuri la acesta), iar cea mai mare cotă este Long.Max_Value
.
Directoarele nu folosesc spaţiu în sistemul local de fişiere şi prin urmare nu sunt contorizate în calculul cotei. În aceeaşi situaţie se găsesc şi metadatele. Cotele sunt calculate în funcţie de factorul de replicare al fişierului, modificarea acestuia generând ajustarea corespunzătoare a cotelor. Cotele sunt reţinute în mod persistent în fişierul FsImage
, detectarea unei încălcări a acestei constrângeri la încărcarea sa determinând afişarea unor mesaje de eroare. Modificările cu privire la cote sunt reţinute în jurnalul de tranzacţii.
Este implementat şi un shell unde pot fi emise comenzi ce interacţionează cu sistemul distribuit de fişiere HDFS ca şi cu alte sisteme de fişiere suportate de Hadoop cu ar fi sistemul de fişiere local, HFTP, S3 precum şi altele. Acesta este invocat folosind comanda:
./hadoop fs <args>
unde argumentele sunt URI-uri indicând calea către o anumită resursă.
Formatul unui URI este scheme://authority/path
unde scheme
este hdfs
pentru sistemul de fişiere distribuit HDFS şi file
pentru sistemul local de fişiere. Atât schema cât şi autoritatea sunt opţionale, în mod implicit fiind utilizată schema specificată în configuraţia curentă.
/parent/child
pot fi referite ca hdfs://namenode/parent/child
sau mai simplu, ca /parent/child
, în condiţiile în care configuraţia indică drept rădăcină calea hdfs://namenode
.
Forma unei comenzi în shell-ul HDFS este:
./hdfs [--config configurationDirectory] command [genericOptions] [commandOptions]
Opţiunile generice pe care le suportă toate aceste comenzi sunt:
-conf <configuration_file>
: specificarea unui fişier de configuraţie pentru o anumită aplicaţie;-D<property=value>
: indicarea unei valori pentru o anumită proprietate;-fs <local|namenode:port>
: precizarea unui anumit nod de nume;-jt <local|jobtracker:port>
: stabilirea unui anumit proces de tip monitorizare a sarcinilor;-files <file_list>
: indicarea unei liste de fişiere care vor fi copiate în clusterul map-reduce;-libjars <jar_list>
: indicarea unei liste de arhive .jar care vor fi incluse în classpath;-archives <archive_list>
: indicarea unei liste de arhive care vor fi dezarhivate pe maşinile unde este realizată procesarea; listele vor avea elementele separate prin caracterul ,
(virgulă).
Comanda dfs
realizează o operație asupra sistemului de fișiere.
./hdfs dfs -<command> -<option> <URI>
Listarea tuturor comenzilor care sunt suportate de către shell poate fi realizată prin comanda:
./hdfs dfs -help
în timp ce informaţii detaliate cu privire la o anumită comandă pot fi obţinute indicând şi denumirea comenzii respective:
./hdfs dfs –help <command>
O listă a tuturor comenzilor disponibile în shell-ul sistemului distribuit de fişiere HDFS este redată în continuare:
appendToFile | ./hdfs dfs –appendToFile <localsrc> … <dst> adaugă conţinutul uneia sau mai multor surse din sistemul de fişierele local (sau de la stdin, dacă se foloseşte caracterul -) către sistemul de fişiere destinaţie - întoarce 0 în caz de succes şi -1 în caz de eroare |
cat | ./hdfs dfs –cat [-ignoreCrc] <src> … copiază conţinutul fişierelor sursă la stdout - întoarce 0 în caz de succes şi -1 în caz de eroare |
checksum | ./hdfs dfs –checksum <src> … afişează informaţiile cu privire la suma de control a fişierelor sursă la stdout; nu este eficient ca această comandă să fie rulată pe un grup de fişiere, de vreme ce ea presupune contactarea tuturor nodurilor de date care conţin blocuri ale fişierului în cauză (suma de control depinde de conţinutul fişierului, dimensiunea blocurilor, algoritmul pentru determinarea sumei de control şi de parametrii utilizaţi pentru crearea fişierului) - întoarce 0 în caz de succes şi -1 în caz de eroare |
chgrp | ./hdfs dfs –chgrp [-R] GROUP PATH … modifică asocierea la un grup a fişierelor; utilizatorul trebuie să fie proprietarul lor sau un superutilizator; este echivalentă cu chown …:GROUP … ♦ opţiunea -R realizează modificările în mod recursiv, de-a lungul structurii de directoare |
chmod | ./hdfs dfs –chmod [-R] <MODE[,MODE].. | OCTALMODE> PATH … schimbă permisiunea asupra fişierelor; utilizatorul trebuie să fie proprietarul lor sau un superutilizator; modul permite specificarea permisiunilor folosind doar literele rwxXt pentru drepturi şi augo pentru tipurile de utilizatori (implicit se aplică pentru toţi utilizatorii); acesta poate fi indicat şi printr-un număr în baza 8, format din 3 cifre la care se adaugă informaţia cu privire la bitul lipicios (ce poate avea valoarea 0 sau 1).♦ opţiunea -R realizează modificările în mod recursiv, de-a lungul structurii de directoare |
chown | ./hdfs dfs –chown [-R] [OWNER][:[GROUP]] PATH … schimbă proprietarul fişierelor; utilizatorul trebuie să fie un super utilizator; dacă se specifică doar proprietarul sau grupul, atunci doar aceste proprietăţi sunt modificate; acestea sunt şiruri de caractere formate din litere, cifre şi caracterele -_.@/ , ţinându-se cont de capitalizare; trebuie evitată utilizarea caracterului . pentru separarea numelui proprietarului de numele grupului întrucât în cazul sistemului de fişiere local, atunci când numele de utilizator conţine caracterul . , efectul poate fi neprecizat'♦ opţiunea -R realizează modificările în mod recursiv, de-a lungul structurii de directoare |
copyFromLocal | ./hdfs dfs –copyFromLocal [-f] [-p] <localsrc> URI similară comenzii put , cu excepţia faptului că sursa trebuie să fie o referinţă către un fişier reţinut local♦ opţiunea -f va suprascrie destinaţia dacă aceasta există deja |
copyToLocal | ./hdfs dfs –copyToLocal [-p] [-ignorecrc] [-crc] URI <localdst> similară comenzii get , cu excepţia faptului că destinaţia trebuie să fie o referinţă către un fişier reţinut local |
count | ./hdfs dfs –count [-q] <paths> determină numărul de directoare, fişiere şi octeţi din căile compatibile cu modelele specificate; coloanele vor fi DIR_COUNT , FILE_COUNT , CONTENT_SIZE şi FILE_NAME ;♦ opţiunea -f adaugă coloanele QUOTA , REMAINING_QUOTA , SPACE_QUOTA , REMAINING_SPACE_QUOTA - întoarce 0 în caz de succes şi -1 în caz de eroare |
cp | ./hdfs dfs –cp [-f] [-p] <src> … <dst> copiază fişierele de la sursă la destinaţie; dacă sunt specificate mai multe surse, destinaţia trebuie să fie director ♦ opţiunea -f (force) va suprascrie destinaţia dacă aceasta există deja♦ opţiunea -p (preserve) va conserva timpul de acces şi al ultimei modificări, proprietarul şi modul- întoarce 0 în caz de succes şi -1 în caz de eroare |
createSnapshot | ./hdfs dfs –createSnapshot <snapshotDir> [<snapshotName>] creează un instantaneu asupra unui director |
deleteSnapshot | ./hdfs dfs –deleteSnapshot <snapshotDir> <snapshotName> şterge un instantaneu asupra unui director |
df | ./hdfs dfs –df [-h] [<path> …] afişează capacitatea, spaţiul liber şi utilizat al sistemului de fişiere; dacă sistemul de fişiere conţine mai multe partiţii şi nu a fost indicată nici o cale către o anumită partiţie, se vor afişa stările partiţiilor rădăcină ♦ opţiunea -h va afişa dimensiunile fişierelor într-un format mai uşor de citit |
du | ./hdfs dfs –du [-s] [-h] URI [URI …] afişează dimensiunile fişierelor / subdirectoarelor conţinute în directorul dat sau doar a fişierului (dacă este indicat un singur fişier) în forma dimensiune denumire (calea absolută) ♦ opţiunea -s va genera un sumar agregat al dimensiunilor fişierelor afişate (în loc de fişiere separate)♦ opţiunea -h va afişa dimensiunile fişierelor într-un format mai uşor de citit- întoarce 0 în caz de succes şi -1 în caz de eroare |
dus | ./hdfs dfs –dus <args> afişează un rezumat al dimensiunilor fişierelor; alternativă la comanda ./hdfs dfs -du -s |
expunge | ./hdfs dfs –expunge goleşte conţinutul directorului /trash |
get | ./hdfs dfs –get [-p] [-ignorecrc] [-crc] <src> … <localdst> copiază fişierele în sistemul local de fişiere ♦ opţiunea -p va conserva timpul de acces şi al ultimei modificări, proprietarul şi modul♦ opţiunea -ignorecrc face să poată fi copiate şi fişierele care nu verifică sima de control♦ opţiunea -crc se foloseşte pentru copierea sumei de control asociată fişierului- întoarce 0 în caz de succes şi -1 în caz de eroare |
getmerge | ./hdfs dfs –getmerge [-nl] <src> <localdst> primeşte un director sursă şi un fişier destinaţie ca intrare şi concatenează toate fişierele din directorul sursă în fişierul destinaţie care se găseşte în sistemul local de fişiere; fişierele din directorul sursă sunt păstrate ♦ opţiunea -nl face ca după sfârşitul fiecărui fişier din directorul sursă să fie adăugată o linie nouă înainte de a fi copiat fişierul următor |
ls | ./hdfs dfs –ls [-d] [-h] [-R] [<path> …] pentru un fişier, întoarce parametrii acestuia în următorul format permissions number_of_replicas userid groupid filesize modification_date modification_time filename pentru un director, întoarce conţinutul său (ca în Unix) în următorul format permissions userid groupid modification_date modification_time dirname dacă nu se specifică nici o cale, se afişează conţinutul directorului /user/<currentUser> ♦ opţiunea -d face ca directoarele să fie afişate ca fişierele♦ opţiunea -h formatează dimensiunile fişierelor astfel încât să poată fi uşor de citit♦ opţiunea -R afişează recursiv conţinutul directoarelor- întoarce 0 în caz de succes şi -1 în caz de eroare |
lsr | ./hdfs dfs –lsr <args> versiune recursivă a ls ; echivalent cu ls -R din Unix |
mkdir | ./hdfs dfs –mkdir [-p] <path> … creează directoare în locaţiile primite ca argumente ♦ opţiunea -p face ca operaţia să nu eşueze în situaţia în care directorul există deja- întoarce 0 în caz de succes şi -1 în caz de eroare |
moveFromLocal | ./hdfs dfs –moveFromLocal <localsrc> … <dst> similar comenzii put , cu excepţia faptului că localsrc este şters după ce este copiat |
moveToLocal | ./hdfs dfs –moveToLocal [-crc] <src> <localdst> nu este încă implementată (se afişează mesajul “Not implemented yet”) |
mv | ./hdfs dfs –mv <src> … <dst> mută fişiere de la sursă la destinaţie; comanda acceptă mai multe surse, caz în care destinaţia trebuie să fie un director; atât sursa cât şi destinaţia trebuie să facă parte din acelaşi sistem de fişiere - întoarce 0 în caz de succes şi -1 în caz de eroare |
put | ./hdfs dfs –put [-f] [-p] <localsrc> … <dst> copiază una sau mai multe surse din sistemul de fişiere local în sistemul de fişiere destinaţie; de asemenea citeşte de la stdin scriind rezultatul în sistemul de fişiere destinaţie (în caz că este folosit caracterul -) ♦ opţiunea -f face ca operaţia să nu eşueze în situaţia în care fişierul destinaţie există♦ opţiunea -p conservă timpul de acces şi timpul de modificare, proprietarul şi modul- întoarce 0 în caz de succes şi -1 în caz de eroare |
renameSnapshot | ./hdfs dfs –renameSnapshot <snapshotDir> <oldName> <newName> redenumeşte un instantaneu al unui director de la o anumită valoare la alta |
rm | ./hdfs dfs –rm [-f] [-r|-R] [-skipTrash] <src> … şterge fişierele specificate ca argumente; şterge numai fişierele şi directoarele ce nu sunt goale ♦ opţiunea -f face ca în cazul când fişierul nu există să nu se afişeze un mesaj diagnostic, modificând valoarea întoarsă pentru a reflecta o eroare♦ opţiunea -[rR] şterge directoarele în mod recursiv♦ opţiunea -skipTrash face ca directorul /trash (în cazul în care este activat) să fie evitat, iar fişierele specificate să fie şterse imediat; această opţiune poate fi utilă atunci când este depăşită cota unui director- întoarce 0 în caz de succes şi -1 în caz de eroare |
rmr | ./hdfs dfs –rmr [-skipTrash] <src> … şterge fişierele specificate ca argumente în mod recursiv ♦ opţiunea -skipTrash face ca directorul /trash (în cazul în care este activat) să fie evitat, iar fişierele specificate să fie şterse imediat; această opţiune poate fi utilă atunci când este depăşită cota unui director- întoarce 0 în caz de succes şi -1 în caz de eroare |
rmdir | ./hdfs dfs –rmdir [–ignore-fail-on-non-empty] <dir> … şterge directoarele speficate de fiecare parametru în parte, pornind de la prezumţia că acestea sunt goale |
setrep | ./hdfs dfs –setrep [-R] [-w] <rep> <path/file> schimbă factorul de replicare al unui fişier; dacă în cale se indică un director, comanda modifică în mod recursiv factorul de replicare pentru toate fişierele aflate la calea respectivă ♦ opţiunea -R este acceptată pentru compatibilitatea cu versiunile anterioare (nu are nici un efect)♦ opţiunea -w face ca comanda să fie blocantă, aşteptând ca procesul de replicare să se termine (operaţia poate dura foarte mult timp)- întoarce 0 în caz de succes şi -1 în caz de eroare |
stat | ./hdfs dfs –stat [format] <path> … afişează statistici cu privire la fişierul/directorul aflat la calea respectivă în formatul specificat ( %b – dimensiunea fişierului în blocuri, %g – denumirea grupului din care face parte proprietarul, %n – numele fişierului, %o – dimensiunea blocului, %r – factor de replicare, %u – numele de utilizator al proprietarului, %y (%Y ) – data de modificare- întoarce 0 în caz de succes şi -1 în caz de eroare |
tail | ./hdfs dfs –tail [-f] <file> afişează ultimul kilo-octet al fişierului la stdout ♦ opţiunea -f va afişa şi datele adăugate, pe măsură ce creşte fişierul (ca în Unix)- întoarce 0 în caz de succes şi -1 în caz de eroare |
test | ./hdfs dfs –test –[defsz] <path> realizează verificări asupra fişierului indicat în cale ♦ opţiunea -d testează dacă calea este către un director♦ opţiunea -e testează existenţa fişierului♦ opţiunea -f testează dacă calea este către un fişier♦ opţiunea -s testează dacă dimensiunea fişierului este mai mare decât 0 octeţi♦ opţiunea -z testează dacă fişierul este gol- întoarce 0 în caz că este verificată condiţia, 1 în caz că aceasta nu este îndeplinită şi -1 în caz de eroare |
text | ./hdfs dfs –text [-ignoreCrc] <src> … primeşte ca parametru un fişier sursă (în format .zip , TextRecordInputStream sau Avro ) al cărui conţinut îl afişează în format text |
touchz | ./hdfs dfs –touchz <path> … creează un fişier având dimensiunea 0 - întoarce 0 în caz de succes şi -1 în caz de eroare (există un fişier la calea indicată care are dimensiunea nenulă) |
Comanda fsck
verifică inconsistenţele de la nivelul sistemului distribuit de fişiere, în special în privinţa blocurilor pierdute sau a blocurilor al căror număr de replici este mai mic decât factorul de replicare precizat pentru fişierul din care fac parte.
./hdfs fsck /
fsck
nu corectează în mod automat problemele pe care le raportează, acest proces fiind realizat implicit de nodul de nume.
Întrucât datele nu sunt distribuite în mod uniform între nodurile de date ale clusterelor HDFS (nodurile de date noi conţin o perioadă de timp informaţii mai puţine, localizarea blocurilor noi se face pe baza topologiei nodurilor de date), există necesitatea ca acestea să fie echilibrate, căci cluster-ul nu declanşează acest proces în mod automat. În acest sens, există un utilitar administrativ care analizează modul în care sunt plasate blocurile în cluster-ul HDFS, re-echilibrând încărcarea nodurilor de date:
./hdfs balancer
De asemenea, sunt puse la dispoziţie o serie de comenzi administrative (disponibile numai administratorului HDFS) prin care poate fi gestionat clusterul în cauză, acestea având forma:
./hdfs dfsadmin -<command> [args]
O listă a tuturor comenzilor de administrare este redată mai jos:
report | ./hdfs dfsadmin -report afişează informaţii de bază şi statistici cu privire la sistemul distribuit de fişiere HDFS; unele dintre aceste date sunt disponibile şi în interfaţa web |
safemode | ./hdfs dfsadmin –safemode <enter|leave|get|wait> comandă referitoare la operaţii de întreţinere folosind modul de siguranţă (în care se poate intra sau se poate ieşi); aceasta reprezintă starea în care nodul de nume nu acceptă schimbări referitoare la spaţiul de nume, nu realizează replicări şi nu şterge blocuri; la pornirea sistemului distribuit de fişiere, se intră automat în această stare, fiind părăsită atunci când este îndeplinit pragul minim de replicare; dacă se intră manual în modul de siguranţă, se va putea ieşi în acelaşi mod |
saveNamespace | ./hdfs dfsadmin saveNamespace salvarea spaţiului de nume în directoarele de stocare ( FsImage ) şi resetarea jurnalelor de tranzacţii (EditLog ); poate fi realizată numai de către un superutilizator şi doar în modul de siguranţă |
rollEdits | ./hdfs dfsadmin rollEdits execută modificările existente în jurnalul de tranzacţii ( EditLog ); poate fi realizată doar de către un superutilizator |
restoreFailedStorage | ./hdfs dfsadmin -restoreFailedStorage încearcă restaurarea replicilor aflate în spaţii de stocare care nu au mai trimis rapoarte, pe măsură ce devin disponibile; poate fi realizată doar de către un superutilizator |
refreshNodes | ./hdfs dfsadmin -refreshNodes actualizează nodul de nume cu un set de noduri de date care au permisiunea să se conecteze la acesta, fiind specificate de proprietatea dfs.hosts , în timp ce nodurile din dfs.hosts.exclude sunt dezafectate, imediat ce replicile pe care le stocau sunt replicate pe alte noduri de date (nodurile care sunt dezafectate nu sunt închise imediat, nemaifiind alese pentru stocarea de noi replici) |
finalizeUpgrade | ./hdfs dfsadmin –finalizeUpgrade încheie procesul de actualizare al HDFS, în care nodurile de date îşi şterg directoarele de lucru anterioare după care acelaşi lucru este realizat şi de nodul de nume |
metasave | ./hdfs dfsadmin –metasave <filename> stochează structurile de date primare ale nodului de nume în fişierul dat ca parametru (aflat în directorul specificat de proprietatea hadoop.log.dir ), acesta fiind suprascris în caz că există; în cadrul acestui fişier, vor fi reţinute nodurile de date care trimit rapoarte nodului de nume, blocurile care aşteaptă să fie replicate, blocurile replicate la momentul de timp respectiv şi blocurile care aşteaptă să fie şterse |
setQuota | ./hdfs dfsadmin –setQuota <quota> <dirname> … stabileşte o anumită cotă pentru fiecare dintre directoarele incluse în lista de parametrii; cota este un întreg care impune o limită în privinţa numărului de denumiri din cadrul ierarhiei de directoare; încercarea de a stabili cota va eşua în cazul când valoarea indicată pentru cotă nu este un întreg pozitiv, utilizatorul nu este un administrator sau directorul nu există (sau este un fişier); cota 1 forţează ca directorul să rămână gol |
clrQuota | ./hdfs dfsadmin –clrQuota <dirname> … şterge cota existentă pentru fiecare dintre directoarele incluse în lista de parametrii; operaţia va eşua dacă directorul nu există sau este un fişier sau dacă utilizatorul nu este un administrator; în cazul în care directorul nu are o cotă asociată, nu se va genera o eroare |
setSpaceQuota | ./hdfs dfsadmin –setSpaceQuota <quota> <dirname> … stabileşte o anumită cotă de stocare pentru fiecare dintre directoarele incluse în lista de parametrii; cota este un întreg ce impune o limită în privinţa spaţiului total ocupat de toate fişierele din ierarhia de directoare, incluzând şi spaţiul ocupat pentru stocarea replicilor; pot fi folosite caracterele m , t , g sau p spre a indica mega-octeţi, giga-octeţi, tera-octeţi respectiv peta-octeţi; încercarea de a stabili cota va eşua în cazul când valoarea indicată pentru cotă nu este un întreg pozitiv, utilizatorul nu este un administrator sau directorul nu există (sau este un fişier) |
clrSpaceQuota | ./hdfs dfsadmin –clrSpaceQuota <dirname> şterge cota de stocare existentă pentru fiecare dintre directoarele incluse în lista de parametrii; operaţia va eşua dacă directorul nu există sau este un fişier sau dacă utilizatorul nu este un administrator; în cazul în care directorul nu are o cotă asociată, nu se va genera o eroare |
refreshServiceAcl | ./hdfs dfsadmin -refreshServiceAcl reîncarcă fişierul ce conţine politica de autorizare la nivel de servicii care va fi folosită ulterior de nodul de nume |
refreshUserToGroupsMappings | ./hdfs dfsadmin –refreshUserToGroupsMappings actualizează asocierile dintre utilizatori şi grupuri |
refreshSuperUserGroupsConfiguration | ./hdfs dfsadmin -refreshSuperUserGroupsConfiguration actualizează asocierile grupurilor delegate (eng. proxy) asociate superutilizatorului |
printTopology | ./hdfs dfsadmin -printTopology afişează un arbore conţinând rastelurile şi nodurile lor în funcţie de rapoartele primite de nodul de nume |
refreshNameNodes | ./hdfs dfsadmin –refreshNameNodes <datanodehost:port> reîncarcă fişierele de configurare pentru nodul de date indicat ca parametru, încetând să deservească federaţiile de blocuri eliminate şi deservind noile federaţii de blocuri |
deleteBlockPool | ./hdfs dfsadmin –deleteBlockPool <datanodehost:port> <blockpoolId> [force] se încearcă ştergerea directorului corespunzător federaţiei de blocuri dată de identificatorul indicat ca parametru pentru nodul de date în cauză; operaţia va reuşi numai în cazul în care directorul este gol sau se specifică opţiunea force, caz în care întregul conţinut al acestuia va fi şters; operaţia nu va reuşi dacă nodul de date deserveşte federaţia de blocuri |
setBalancerBandwidth | ./hdfs dfsadmin –setBalancerBandwidth <bandwidth> stabileşte lăţimea de bandă care va fi folosită de fiecare nod de date în timpul operaţiei de reechilibrare a blocurilor; lăţimea de bandă (indicată ca parametru) reprezintă numărul de octeţi per secundă care vor putea fi tansmişi de fiecare nod de date; valoarea suprascrie proprietatea dfs.balance.bandwidthPerSec însă nu este persistentă în cadrul nodului de date |
fetchImage | ./hdfs dfsadmin –fetchImage <localDir> descarcă cea mai recentă versiune a fişierului FsImage din cadrul nodului de nume, stocând-o în directorul local specificat ca parametru |
allowSnapshot | ./hdfs dfsadmin –allowSnapshot <snapshotDir> permite să fie realizate instantanee pe directorul indicat ca parametru |
disallowSnapshot | ./hdfs dfsadmin –disallowSnapshot <snapshotDir> nu mai permite să fie realizate instantanee pe directorul indicat ca parametru |