Использование всех ядер на одном компьютере Hadoop
В настоящее время я работаю над загрузкой данных в граф Titan с помощью Hadoop (Titan версии 0.5.4, Hadoop версии 2.6.0). Я использую односерверный (псевдораспределенный) кластер Hadoop с целью расширения до полного кластера с большим количеством компьютеров с одинаковым оборудованием. Я пытаюсь настроить Hadoop таким образом, чтобы полностью использовать ядро. До сих пор я думал, что выполнил приличную настройку с хорошими параметрами конфигурации, но когда Hadoop выполняет и загружает данные в граф Титана, я не вижу полного использования всех ядер на моей машине.
Ситуация следующая. Используемая мной машина имеет следующие аппаратные характеристики:
- Процессор: 32 ядра
- RAM: 256 ГБ
- Память подкачки: 32 ГБ
- Диски: 8x128GB SSD, 4x2TB HDD
Данные, которые я загружаю в граф Титана с помощью Hadoop, имеют следующие спецификации:
- Общий размер: 848 МБ
- Разделить на четыре файла (487 МБ, 142 МБ, 219 МБ и 1,6 МБ), каждый из которых содержит вершины одного типа вместе со всеми свойствами вершин и исходящими ребрами.
При настройке кластера Hadoop я пытался использовать некоторые логические рассуждения для установки параметров конфигурации Hadoop на их (как я думаю, является) оптимальные настройки. Смотрите это рассуждение ниже.
- Моя машина имеет 32 ядра, поэтому теоретически я мог бы разделить входной размер на порции, размер которых достаточно велик, чтобы в итоге получить около 32 порций. Итак, для 848 МБ ввода я мог бы установить
dfs.block.size
до 32 МБ, что привело бы к (848 МБ / 32 МБ ~) 27 блоков. - Чтобы убедиться, что каждая задача карты получает один кусок, я установил значение
mapred.min.split.size
немного меньше, чем размер блока, иmapred.max.split.size
немного больше, чем размер блока (например, 30 МБ и 34 МБ соответственно). - Доступная память, необходимая для каждой задачи, немного расплывчата для меня. Например, я мог бы установить
mapred.child.java.opts
до значения-Xmx1024m
дать каждой задаче (например, каждому мапперу / редуктору) 1 ГБ памяти. Учитывая, что у моей машины всего 256 ГБ памяти - вычитая часть из нее, чтобы зарезервировать ее для других целей, оставляя мне около 200 ГБ памяти - я могу в итоге получить (200 ГБ / 1 ГБ =) 200 картографов и редукторов. Или, когда я даю каждой задаче 2 ГБ памяти, я получаю в общей сложности 100 картографов и редукторов. Думаю, объем памяти, выделяемый для каждой задачи, также зависит от размера ввода. Во всяком случае, это приводит к значениям дляmapred.tasktracker.map/reduce.tasks.maximum
около 100, что может быть уже слишком много, учитывая тот факт, что у меня есть только 32 ядра. Поэтому, возможно, установив для этого параметра значение 32 для обоихmap
а такжеreduce
может быть лучше? Как вы думаете?
После этих предположений я получаю следующую конфигурацию.
HDFS-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.block.size</name>
<value>33554432</value>
<description>Specifies the sizeof data blocks in which the input dataset is split.</description>
</property>
</configuration>
mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
<description>The runtime framework for executing MapReduce jobs. Can be one of local, classic or yarn.</description>
</property>
<property>
<name>mapred.child.java.opts</name>
<value>-Xmx2048m</value>
<description>Java opts for the task tracker child processes.</description>
</property>
<property>
<name>mapred.tasktracker.map.tasks.maximum</name>
<value>32</value>
<description>The maximum number of map tasks that will be run simultaneously by a tasktracker.</description>
</property>
<property>
<name>mapred.tasktracker.reduce.tasks.maximum</name>
<value>32</value>
<description>The maximum number of reduce tasks that will be run simultaneously by a tasktracker.</description>
</property>
<property>
<name>mapred.min.split.size</name>
<value>31457280</value>
<description>The minimum size chunk that map input should be split into.</description>
</property>
<property>
<name>mapred.max.split.size</name>
<value>35651584</value>
<description>The maximum size chunk that map input should be split into.</description>
</property>
<property>
<name>mapreduce.job.reduces</name>
<value>32</value>
<description>The default number of reducers to use.</description>
</property>
<property>
<name>mapreduce.job.maps</name>
<value>32</value>
<description>The default number of maps to use.</description>
</property>
</configuration>
Пряжа-site.xml
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
<description>The minimum allocation for every container request at the RM, in MBs.</description>
</property>
</configuration>
Выполнение Hadoop с этими настройками не позволяет полностью использовать ядро на одной машине. Не все ядра заняты на всех этапах MapReduce. Во время выполнения Hadoop я также рассмотрел пропускную способность ввода-вывода, используя iostat
команда (iostat -d -x 5 3
давая мне три отчета с 5-секундными интервалами). Пример такого отчета приведен ниже.
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.07 0.02 0.41 0.29 2.37 12.55 0.01 16.92 5.18 17.43 2.47 0.10
sdb 0.07 2.86 4.90 10.17 585.19 1375.03 260.18 0.04 2.96 23.45 8.55 1.76 2.65
sdc 0.08 2.83 4.89 10.12 585.48 1374.71 261.17 0.07 4.89 30.35 8.12 2.08 3.13
sdd 0.07 2.83 4.89 10.10 584.79 1374.46 261.34 0.04 2.78 26.83 6.71 1.94 2.91
sde 0.00 0.00 0.00 0.00 0.05 0.80 278.61 0.00 10.74 2.55 32.93 0.73 0.00
sdf 0.00 0.00 0.00 0.00 0.05 0.80 283.72 0.00 10.30 1.94 33.09 0.68 0.00
sdg 0.00 0.00 0.00 0.00 0.05 0.80 283.83 0.00 10.24 1.99 32.75 0.68 0.00
sdh 0.00 0.00 0.00 0.00 0.05 0.80 284.13 0.00 10.29 1.96 32.99 0.69 0.00
sdi 0.00 0.00 0.00 0.00 0.05 0.80 284.87 0.00 17.89 2.35 60.33 0.74 0.00
sdj 0.00 0.00 0.00 0.00 0.05 0.80 284.05 0.00 10.30 2.01 32.96 0.68 0.00
sdk 0.00 0.00 0.00 0.00 0.05 0.80 284.44 0.00 10.20 1.99 32.62 0.68 0.00
sdl 0.00 0.00 0.00 0.00 0.05 0.80 284.21 0.00 10.50 2.00 33.71 0.69 0.00
md127 0.00 0.00 0.04 0.01 0.36 6.38 279.84 0.00 0.00 0.00 0.00 0.00 0.00
md0 0.00 0.00 14.92 36.53 1755.46 4124.20 228.57 0.00 0.00 0.00 0.00 0.00 0.00
Я не специалист по использованию дисков, но могут ли эти значения означать, что я где-то привязан к IO, например, на дисках sdb, sbc или sdd?
Редактировать: возможно, лучшее указание загрузки процессора и пропускной способности ввода-вывода может быть дано с помощью sar
команда. Вот результаты для 5 отчетов, 5 секунд (sar -u 5 5
):
11:07:45 AM CPU %user %nice %system %iowait %steal %idle
11:07:50 AM all 12.77 0.01 0.91 0.31 0.00 86.00
11:07:55 AM all 15.99 0.00 1.39 0.56 0.00 82.05
11:08:00 AM all 11.43 0.00 0.58 0.04 0.00 87.95
11:08:05 AM all 8.03 0.00 0.69 0.48 0.00 90.80
11:08:10 AM all 8.58 0.00 0.59 0.03 0.00 90.80
Average: all 11.36 0.00 0.83 0.28 0.00 87.53
Заранее спасибо за любой ответ!
1 ответ
Задайте для этого параметра в yarn-site.xml количество ядер, которые есть на вашем компьютере:
<property>
<name>yarn.scheduler.maximum-allocation-vcores</name>
<value>32</value>
</property>
Затем запустите pi из jar hadoop-examples и посмотрите на веб-странице менеджера ресурсов, сколько картографов выполняется одновременно