Работа с входными расщеплениями (HADOOP)

У меня есть файл .txt следующим образом:


Это xyz

Это мой дом

Это мой компьютер

Это моя комната

Это компьютер ubuntu xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxxxxxxxxxxxxxxxxxxx


(игнорируя пустую строку после каждой записи)

Я установил размер блока как 64 байта. Я пытаюсь проверить, существует ли ситуация, когда одна запись разбита на два блока или нет.

Теперь логически, поскольку размер блока 64 байта, после загрузки файла в HDFS он должен создать 3 блока размером 64,64,27 байт соответственно, который он делает. Кроме того, поскольку размер первого блока составляет 64 байта, он должен содержать только следующие данные:


Это xyz

Это мой дом

Это мой компьютер

Это моя комната

ЧТ


Теперь я хочу посмотреть, нравится ли первый блок или нет, если я просматриваю HDFS через браузер и загружаю файл, он загружает весь файл не одним блоком.. p >

Итак, я решил запустить работу по уменьшению карты, которая будет отображать только значения записи. (Настройка reducers=0 и вывод отображения в качестве context.write(null,record_value), также изменяя разделитель по умолчанию на "")

Теперь при запуске задания счетчики заданий показывают 3 раскола, что очевидно, но после завершения, когда я проверяю выходной каталог, он показывает 3 выходных файла карты из которых 2 пустые, и первый выходной файл картографа имеет все содержимое файла, как оно есть.

Может ли кто-нибудь помочь мне с этим? Возможно ли, что новые версии hadoop автоматически обрабатывают неполные записи?

Ответ 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

Ответ 2

  • Используйте следующую команду, чтобы получить список блоков для вашего файла на HDFS

    hdfs fsck PATH -files -blocks -locations

где PATH - это полный путь HDFS, где находится ваш файл.

  1. Результат (показано ниже частично) будет примерно таким (строки строк 2, 3... игнорировать)

    Подключение к namenode через http://ec2-54-235-1-193.compute-1.amazonaws.com:50070/fsck?ugi=student6&files=1&blocks=1&locations=1&path=%2Fstudent6%2Ftest.txt FSCK начато student6 (auth: SIMPLE) из /172.31.11.124 для пути /student 6/test.txt в Ср Mar 22 15:33:17 UTC 2017 /student 6/test.txt 22 байта, 1 блок (ы): OK 0. BP-944036569-172.31.11.124-1467635392176: blk_1073755254 _14433 len = 22 repl = 1 [DatanodeInfoWithStorage [172.31.11.124: 50010, DS-4a530a72-0495-4b75-a6f9-75bdb8ce7533, ДИСК]]

  2. Скопировать выделенную часть команды вывода (исключая _14433), как показано в приведенном выше примере вывода

  3. Перейдите в файловую систему Linux в своем datanode в каталог, где хранятся блоки (на этот указатель будет указываться параметр dfs.datanode.data.dir hdfs-site.xml и поиск во всем поддереве это место для имени файла, у которого есть только что скопированная жирная строка. Это скажет вам, какой подкаталог под dfs.datanode.data.dir содержит файл с этой строкой в ​​своем имени (исключить любое имя файла с .meta suffix). расположенный таким именем файла, вы можете запустить команду cat cat Linux для этого имени файла, чтобы увидеть содержимое вашего файла.

  4. Помните, что файл является файлом HDFS, под крышкой файл фактически хранится в файловой системе Linux, и каждый блок файла HDFS является уникальным файлом Linux. Блок идентифицируется файловой системой Linux с именем, как показано в жирной строке шага 2