È il contrario. Il numero di mappatori viene deciso in base al numero di suddivisioni. In realtà è il lavoro di InputFormat
, che stai usando, per creare le divisioni. Non hai idea del numero di mappatori fino a quando non è stato deciso il numero di suddivisioni. Inoltre, non è sempre possibile creare divisioni basate sulla dimensione del blocco HDFS. Dipende totalmente dalla logica all'interno del metodo getSplits()
del tuo InputFormat.
Per comprendere meglio questo, si supponga di elaborare i dati memorizzati in MySQL utilizzando MR. Poiché in questo caso non vi è alcun concetto di blocco, la teoria che divide si crea sempre in base al blocco HDFS non riesce. Destra? Che dire quindi della creazione di spaccature?Una possibilità è quella di creare divisioni basate su intervalli di righe nella tabella MySQL (e questo è ciò che fa DBInputFormat
, un formato di input per leggere i dati da un database relazionale). Supponiamo di avere 100 righe. Quindi potresti avere 5 split di 20 righe ciascuno.
È solo per gli InputFormats basati su FileInputFormat
(un InputFormat per la gestione dei dati memorizzati nei file) che le suddivisioni vengono create in base alla dimensione totale, in byte, dei file di input. Tuttavia, il blocco di FileSystem dei file di input viene considerato come limite superiore per le suddivisioni di input. Se hai un file più piccolo della dimensione del blocco HDFS, avrai solo 1 mapper per quel file. Se si desidera avere un comportamento diverso, è possibile utilizzare mapred.min.split.size. Ma dipende di nuovo esclusivamente da getSplits() del tuo InputFormat.
C'è una differenza fondamentale tra MR split
e HDFS block
e la gente spesso viene confusa da questo. Un blocco è un dato fisico mentre una divisione è solo un pezzo logico che verrà inviato a un mappatore. Una divisione non contiene i dati di input, è solo un riferimento ai dati. Allora cos'è una scissione? Una divisione ha fondamentalmente 2 elementi: uno length in bytes
e un set di storage locations
, che sono solo stringhe di nome host.
Tornando alla tua domanda. Hadoop consente molto più di 200 mapper. Detto questo, non ha molto senso avere 200 mapper per soli 500 MB di dati. Ricorda sempre che quando parli di Hadoop, hai a che fare con dati enormi. L'invio di soli 2,5 MB di dati a ciascun mappatore sarebbe eccessivo. E sì, se non ci sono slot liberi per la CPU, alcuni mapper possono essere eseguiti dopo il completamento degli attuali mapper. Ma il framework MR è molto intelligente e fa del suo meglio per evitare questo tipo di situazione. Se la macchina in cui sono presenti i dati da elaborare, non dispone di slot CPU liberi, i dati verranno spostati in un nodo vicino, dove sono disponibili slot liberi e elaborati.
HTH
Inoltre, tutti i mappatori vengono eseguiti contemporaneamente o alcuni di essi potrebbero essere eseguiti in serie? - Se ci sono abbastanza slot della mappa, tutte le attività della mappa verrebbero lanciate insieme. Se si dispone di più attività sulla mappa rispetto agli slot disponibili, le attività extra della mappa attenderanno il completamento dei mapping. –
Nota anche che ho considerato che stai utilizzando vecchie API mappate poiché il mio codice è basato su quello. Ecco la firma di getSplits di FileInputFormat e ha numSplits come parametro. public InputSplit [] getSplits (lavoro JobConf, int numSplits) –
è l'alternativa – Tagar