sql >> Database teknologi >  >> NoSQL >> HBase

Problemet med små filer

Små filer er et stort problem i Hadoop - eller i det mindste er de det, hvis antallet af spørgsmål på brugerlisten om dette emne er noget at gå efter. I dette indlæg vil jeg se på problemet og undersøge nogle almindelige løsninger.

Problemer med små filer og HDFS

En lille fil er en, der er væsentligt mindre end HDFS-blokstørrelsen (standard 64MB). Hvis du gemmer små filer, så har du sandsynligvis masser af dem (ellers ville du ikke henvende dig til Hadoop), og problemet er, at HDFS ikke kan håndtere mange filer.

Hver fil, mappe og blok i HDFS er repræsenteret som et objekt i navnenodens hukommelse, som hver især optager 150 bytes, som en tommelfingerregel. Så 10 millioner filer, der hver bruger en blok, ville bruge omkring 3 gigabyte hukommelse. Opskalering meget ud over dette niveau er et problem med nuværende hardware. En milliard filer er bestemt ikke mulig.

Desuden er HDFS ikke gearet til effektivt at få adgang til små filer:det er primært designet til streaming af store filer. Gennemlæsning af små filer forårsager normalt mange søgninger og masser af hop fra datanode til datanode for at hente hver lille fil, hvilket alt sammen er et ineffektivt dataadgangsmønster.

Problemer med små filer og MapReduce

Kortopgaver behandler normalt en blok af input ad gangen (ved at bruge standard FileInputFormat ). Hvis filen er meget lille, og der er mange af dem, behandler hver kortopgave meget lidt input, og der er mange flere kortopgaver, som hver især medfører ekstra bogføringsomkostninger. Sammenlign en 1GB fil opdelt i 16 64MB blokke og 10.000 eller deromkring 100KB filer. De 10.000 filer bruger et kort hver, og jobtiden kan være titusinder eller hundredvis af gange langsommere end den tilsvarende med en enkelt inputfil.

Der er et par funktioner, der hjælper med at lette bogføringsomkostningerne:genbrug af opgave JVM til at køre flere kortopgaver i én JVM, hvorved man undgår nogle JVM opstartsomkostninger (se mapred.job.reuse.jvm.num.tasks kode> egenskab), og MultiFileInputSplit som kan køre mere end én opdeling pr. kort.

Hvorfor produceres der små filer?

Der er mindst to tilfælde

  1. Filerne er stykker af en større logisk fil. Da HDFS først for nylig har understøttet tilføjelser, er et meget almindeligt mønster for at gemme ubundne filer (f.eks. logfiler) at skrive dem i bidder i HDFS.
  2. Filerne er i sagens natur små. Forestil dig et stort korpus af billeder. Hvert billede er en særskilt fil, og der er ingen naturlig måde at kombinere dem til en større fil.

Disse to sager kræver forskellige løsninger. I det første tilfælde, hvor filen består af poster, kan problemet undgås ved at kalde HDFS's sync() metode  hver så ofte til kontinuerligt at skrive store filer. Alternativt er det muligt at skrive et program til at sammenkæde de små filer.

For det andet tilfælde er en form for container nødvendig for at gruppere filerne på en eller anden måde. Hadoop tilbyder et par muligheder her.

HAR-filer

Hadoop Archives (HAR-filer) blev introduceret til HDFS i 0.18.0 for at afhjælpe problemet med masser af filer, der lægger pres på navnenodens hukommelse. HAR-filer fungerer ved at bygge et lagdelt filsystem oven på HDFS. En HAR-fil oprettes ved hjælp af hadoop archive kommando, som kører et MapReduce-job for at pakke filerne, der arkiveres, i et lille antal HDFS-filer. For en klient, der bruger HAR-filsystemet, er intet ændret:alle de originale filer er synlige og tilgængelige (omend ved hjælp af en har:// URL). Dog er antallet af filer i HDFS blevet reduceret.

Gennemlæsning af filer i en HAR er ikke mere effektiv end gennemlæsning af filer i HDFS, og det kan faktisk være langsommere, da hver HAR-filadgang kræver to indeksfillæsninger samt datafilen, der læses (se diagram). Og selvom HAR-filer kan bruges som input til MapReduce, er der ingen speciel magi, der gør det muligt for kort at fungere over alle filerne i HAR co-resident på en HDFS-blok. Det burde være muligt at bygge et inputformat, der kan drage fordel af den forbedrede placering af filer i HAR'er, men det eksisterer ikke endnu. Bemærk, at MultiFileInputSplit, selv med forbedringerne i HADOOP-4565 for at vælge filer i en opdeling, som er nodelokale, vil kræve en søgning pr. lille fil. Det ville være interessant at se ydelsen af ​​dette sammenlignet med en SequenceFile, siger. På nuværende tidspunkt er HAR'er sandsynligvis bedst brugt udelukkende til arkivformål.

Sekvensfiler

Det sædvanlige svar på spørgsmål om "problemet med små filer" er:brug en SequenceFile. Ideen her er, at du bruger filnavnet som nøglen og filens indhold som værdien. Dette fungerer meget godt i praksis. Går du tilbage til de 10.000 100KB-filer, kan du skrive et program til at sætte dem i en enkelt SequenceFile, og derefter kan du behandle dem på en streaming-måde (direkte eller ved hjælp af MapReduce), der opererer på SequenceFile. Der er også et par bonusser. SequenceFiles kan opdeles, så MapReduce kan opdele dem i bidder og operere på hver chunk uafhængigt. De understøtter også kompression i modsætning til HAR'er. Blokkomprimering er den bedste mulighed i de fleste tilfælde, da den komprimerer blokke med flere poster (i stedet for pr. post).

Det kan være langsomt at konvertere eksisterende data til SequenceFiles. Det er dog udmærket muligt at oprette en samling af SequenceFiles parallelt. (Stuart Sierra har skrevet et meget nyttigt indlæg om at konvertere en tar-fil til en SequenceFile - værktøjer som dette er meget nyttige, og det ville være godt at se flere af dem). Fremover er det bedst at designe din datapipeline til at skrive dataene ved kilden direkte ind i en SequenceFile, hvis det er muligt, i stedet for at skrive til små filer som et mellemtrin.

I modsætning til HAR-filer er der ingen måde at liste alle nøglerne i en SequenceFile, undtagen at læse hele filen igennem. (MapFiles, som er ligesom SequenceFiles med sorterede nøgler, opretholder et delvist indeks, så de kan heller ikke liste alle deres nøgler - se diagram.)

SequenceFile er temmelig Java-centreret. TFile er designet til at være på tværs af platforme og være en erstatning for SequenceFile, men den er ikke tilgængelig endnu.

HBase

Hvis du producerer mange små filer, kan en anden type lagring være mere passende, afhængigt af adgangsmønsteret. HBase gemmer data i MapFiles (indekserede SequenceFiles), og er et godt valg, hvis du skal lave MapReduce-stil streaming-analyser med lejlighedsvis tilfældigt opslag. Hvis ventetid er et problem, så er der masser af andre valg - se Richard Jones' fremragende undersøgelse af nøgleværdibutikker.


  1. MongoDB bind_ip virker ikke, medmindre den er sat til 0.0.0.0

  2. Selvsigneret SSL-forbindelse ved hjælp af PyMongo

  3. Aggregate $lookup returnerer ikke elementernes oprindelige array-rækkefølge

  4. Kører MongoDB med Ops Manager