Ответ 1
Если у вас есть файлы без расщепления, вам лучше использовать большие размеры блоков - размером с сами файлы (или больше, это не имеет значения).
Если размер блока меньше, чем общий размер файла, тогда вы сталкиваетесь с тем, что все блоки не все находятся на одних и тех же данных node, и вы теряете локальность данных. Это не проблема с splittable файлами, поскольку задача карты будет создана для каждого блока.
Что касается верхнего предела размера блока, я знаю, что для некоторой более старой версии Hadoop предел составлял 2 ГБ (выше которого содержимое блока было недоступно) - см. https://issues.apache.org/jira/browse/HDFS-96
Нет недостатка в хранении небольших файлов с большими размерами блоков. Чтобы подчеркнуть этот момент, рассмотрите файл размером 1 МБ и 2 ГБ, каждый с размером блока 2 ГБ:
- 1 МБ - 1 блок, одна запись в имени Node, 1 МБ, физически сохраненная на каждой реплике node
- 2 ГБ - 1 блок, одна запись в имени Node, 2 ГБ, физически сохраненная на каждой реплике node
Так же, как и для требуемого физического хранилища, нет никакой нисходящей стороны в таблице блоков Name node (оба файла имеют одну запись в таблице блоков).
Единственным возможным недостатком является время, затрачиваемое на репликацию меньшего по сравнению с большим блоком, но с другой стороны, если данные из node теряются из кластера, тогда задача 2000 x 1 МБ блоков для репликации медленнее, чем блок с блоком 2 ГБ.
Обновление - обработанный пример
Увидев, что это вызывает некоторую путаницу, некоторые примеры работы:
Скажем, у нас есть система с размером блока HDFS размером 300 МБ, и для упрощения работы у нас есть кластер psuedo с только одним данным node.
Если вы хотите сохранить файл размером 1100 МБ, то HDFS разложит этот файл на не более 300 МБ блоков и сохранит данные node в файлах с индексированным индексом. Если вы хотите перейти к данным node и посмотреть, где хранятся индексированные файлы блоков на физическом диске, вы можете увидеть что-то вроде этого:
/local/path/to/datanode/storage/0/blk_000000000000001 300 MB
/local/path/to/datanode/storage/0/blk_000000000000002 300 MB
/local/path/to/datanode/storage/0/blk_000000000000003 300 MB
/local/path/to/datanode/storage/0/blk_000000000000004 200 MB
Обратите внимание, что файл не точно делится на 300 МБ, поэтому последний блок файла имеет размер по модулю файла по размеру блока.
Теперь, если мы повторим одно и то же упражнение с файлом, меньшим размера блока, скажем 1 МБ, и посмотрим, как он будет храниться в данных node:
/local/path/to/datanode/storage/0/blk_000000000000005 1 MB
Снова обратите внимание, что фактический файл, хранящийся в данных node, составляет 1 МБ, НЕ 200 МБ файл с 299 МБ нулевого заполнения (что, по моему мнению, является причиной путаницы).
Теперь, когда размер блока играет роль в эффективности, это имя node. Для приведенных выше двух примеров имя node должно содержать карту имен файлов, блокировать имена и данные node местоположения (а также общий размер файла и размер блока):
filename index datanode
-------------------------------------------
fileA.txt blk_01 datanode1
fileA.txt blk_02 datanode1
fileA.txt blk_03 datanode1
fileA.txt blk_04 datanode1
-------------------------------------------
fileB.txt blk_05 datanode1
Вы можете видеть, что если бы вы использовали размер блока 1 МБ для файла file.txt, вам понадобилось бы 1100 записей на приведенной выше карте, а не 4 (для чего потребуется больше памяти в имени node). Кроме того, откат всех блоков будет дороже, поскольку вы делаете 1100 RPC-вызовов для datanode1, а не 4.