Ответ 1
Шаги для воспроизведения сценария
1) Создал файл sample.txt
с содержимым с общим размером ~153B
cat sample.txt
This is xyz
This is my home
This is my PC
This is my room
This is ubuntu PC xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxxxxxxxxxxxxxxxxxxx
2) Добавлено свойство hdfs-site.xml
<property>
<name>dfs.namenode.fs-limits.min-block-size</name>
<value>10</value>
</property>
и загружается в HDFS с размером блока как 64B
.
hdfs dfs -Ddfs.bytes-per-checksum=16 -Ddfs.blocksize=64 -put sample.txt /
Это создало три блока размеров 64B
, 64B
и 25B
.
Содержимое в Block0
:
This is xyz
This is my home
This is my PC
This is my room
This i
Содержимое в Block1
:
s ubuntu PC xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xx
Содержимое в Block2
:
xx xxxxxxxxxxxxxxxxxxxxx
3) Простой mapper.py
#!/usr/bin/env python
import sys
for line in sys.stdin:
print line
4) Hadoop Streaming с редукторами 0
:
yarn jar hadoop-streaming-2.7.1.jar -Dmapreduce.job.reduces=0 -file mapper.py -mapper mapper.py -input /sample.txt -output /splittest
Работа выполнялась с 3-мя входными комбинациями, вызывающими 3-х карт и сгенерированными 3 выходными файлами с одним файлом, содержащим весь контент sample.txt
и остальные 0B
файлы.
hdfs dfs -ls /splittest
-rw-r--r-- 3 user supergroup 0 2017-03-22 11:13 /splittest/_SUCCESS
-rw-r--r-- 3 user supergroup 168 2017-03-22 11:13 /splittest/part-00000
-rw-r--r-- 3 user supergroup 0 2017-03-22 11:13 /splittest/part-00001
-rw-r--r-- 3 user supergroup 0 2017-03-22 11:13 /splittest/part-00002
Файл sample.txt
разбит на 3 разбиения, и эти расщепления назначаются каждому преобразователю как
mapper1: start=0, length=64B
mapper2: start=64, length=64B
mapper3: start=128, length=25B
Это определяет, какая часть файла должна быть прочитана преобразователем, не обязательно, чтобы она была точной. Фактическое содержимое, которое считывает преобразователь, определяется FileInputFormat и его границами здесь TextFileInputFormat
.
Используется LineRecordReader
для чтения содержимого из каждого разлома и использует \n
как разделитель (граница строки). Для файла, который не сжимается, строки считываются каждым преобразователем, как описано ниже.
Для устройства отображения, начальным индексом которого является 0, чтение строки начинается с начала разделения. Если раздвоение заканчивается на \n
, отсчет заканчивается на границе разделения иначе он ищет первый \n
пост длины назначенного разделения (здесь 64B
). Таким образом, это не приводит к обработке частичной линии.
Для всех других картографов (start index!= 0) он проверяет, является ли предыдущий символ из его начального индекса (start - 1
) \n
, если да, он считывает содержимое с начала разделения, иначе он пропускает содержимое, которое присутствует между его начальным индексом и первым символом \n
, встречающимся в этом расколе (так как это содержимое обрабатывается другим преобразователем) и начинает читать с первого \n
.
Здесь mapper1
(начальный индекс равен 0) начинается с Block0
, разбиение которого заканчивается в середине строки. Таким образом, он продолжает читать строку, которая потребляет весь Block1
, и поскольку Block1
не имеет символа \n
, mapper1
продолжает читать, пока не найдет \n
, который заканчивается потреблением целых Block2
. Таким образом, весь контент sample.txt
оказался в одиночном выводе картографа.
mapper2
(start index!= 0), один символ, предшествующий его начальному индексу, не является \n
, поэтому пропускает строку и заканчивается без содержимого. Пустой вывод карты. mapper3
имеет идентичный сценарий как mapper2
.
Попробуйте изменить содержимое
sample.txt
, как это, чтобы увидеть разные результаты
This is xyz
This is my home
This is my PC
This is my room
This is ubuntu PC xxxx xxxx xxxx xxxx
xxxx xxxx xxxx xxxx xxxx xxxx xxxx
xxxxxxxxxxxxxxxxxxxxx