Hadoopのスケジューラーを適用する

LinuxBeginner
オンラインで実践に進む

はじめに

古代エジプトでは、ファラオの宮殿が王国の力と繁栄を見事に象徴していました。しかし、きらびやかな外観の裏では危機が進行していました。ナイル川の恵みで満たされたファラオの巨大な倉庫は、整理が行き届いていませんでした。資源の分配を任された神官たちは、人々の需要に対応しきれずにいました。

そこで登場するのが、王国の資源を整える任務を担った、優秀な若き神官アメンホテプです。彼の使命は、貴重な物資を公平かつ効率的に配分し、すべての国民が正当な分け前を受け取れる仕組みを作ることでした。

アメンホテプの知性と献身に感銘を受けたファラオは、最新の技術であるHadoop YARN(Yet Another Resource Negotiator)システムを使う許可を与えました。この強力なツールを手にしたアメンホテプは、目標の達成に役立つYARNの重要な要素、Applying Schedulerの仕組みを学び始めました。

Hadoop YARNのスケジューラーを理解する

このステップでは、Hadoop YARNで利用できるスケジューリングポリシーを確認し、現在実行中のスケジューラーを調べます。

まず、Hadoopユーザーに切り替えます。この実験のすべてのコマンドは、このターミナルで実行してください。

su - hadoop

設定ディレクトリを明示的に指定します。この環境ではHadoopは/home/hadoop/hadoopにインストールされており、/etc/hadoop/confは使用しません。

export HADOOP_CONF_DIR=/home/hadoop/hadoop/etc/hadoop

Hadoop YARNでは、Fair SchedulerとCapacity Schedulerを利用できます。Fair Schedulerは時間の経過に応じてアプリケーション間でリソースを共有し、キューのウェイトによって各キューに割り当てられる相対的な割合が変わります。Capacity Schedulerは階層構造のキューに保証容量を割り当て、未使用のリソースは共有できるようにします。

Hadoop 3.3.6には、yarn schedulerサブコマンドがありません。設定ファイルが適用されたと決めつけず、ResourceManagerのREST APIに問い合わせて、実際に実行中のスケジューラーを確認します。応答は次のコマンドで保存します。

curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-initial.json

現在有効なスケジューラーの種類を表示します。

python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-initial.json') as stream:
    info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
PY

新しい実験環境での想定出力は次のとおりです。

capacityScheduler

次のステップでもこのターミナルを使用するため、開いたままにしておいてください。各スケジューラーの設定ファイルを変更した後、ResourceManagerを再起動して、選択したスケジューラーのクラスを読み込みます。

Fair Schedulerを設定する

このステップでは、citizensキューとpriestsキューの間でリソースを共有するようにFair Schedulerを設定します。

Hadoopユーザーとして、次のブロック全体を実行し、割り当てファイルを作成します。

cat > /home/hadoop/fair-scheduler.xml <<'XML'
<?xml version="1.0"?>
<allocations>
  <defaultQueueSchedulingPolicy>fair</defaultQueueSchedulingPolicy>
  <queue name="root">
    <weight>1.0</weight>
    <queue name="citizens">
      <weight>1.0</weight>
      <minResources>1024 mb, 1 vcores</minResources>
    </queue>
    <queue name="priests">
      <weight>2.0</weight>
      <minResources>2048 mb, 2 vcores</minResources>
    </queue>
  </queue>
</allocations>
XML

citizensキューのウェイトは1で、最小リソースはメモリ1024 MBと1 vcoreです。priestsキューのウェイトは2で、最小リソースはメモリ2048 MBと2 vcoresです。最小リソースは、クラスターで利用できるリソースの範囲内で目指す値です。ウェイトは、残りのリソースを共有する割合に影響します。

yarn-site.xmlでFair Schedulerを選択し、割り当てファイルの場所を指定します。次のコマンドは、既存のNodeManager設定を保持します。

python3 - <<'PY'
import os
import xml.etree.ElementTree as ET

path = os.path.join(os.environ['HADOOP_CONF_DIR'], 'yarn-site.xml')
tree = ET.parse(path)
root = tree.getroot()
settings = {
    'yarn.resourcemanager.scheduler.class':
        'org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler',
    'yarn.scheduler.fair.allocation.file': '/home/hadoop/fair-scheduler.xml',
}
for name, value in settings.items():
    prop = next((p for p in root.findall('property') if p.findtext('name') == name), None)
    if prop is None:
        prop = ET.SubElement(root, 'property')
        ET.SubElement(prop, 'name').text = name
        ET.SubElement(prop, 'value')
    prop.find('value').text = value
tree.write(path, encoding='UTF-8', xml_declaration=True)
PY

スケジューラーのクラスを変更した場合、ResourceManagerの再起動が必要です。この実習用クラスターでは、実行中のアプリケーションはありません。ResourceManagerだけを停止してから起動します。

yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager

実行中のスケジューラーをもう一度確認します。ResourceManagerの起動を待つために再試行オプションを指定しています。起動中に一時的な接続エラーが発生することがあります。

curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-fair.json
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-fair.json') as stream:
    info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
for queue in info['rootQueue']['childQueues']['queue']:
    if queue['queueName'] in ('root.citizens', 'root.priests'):
        resources = queue['minResources']
        print(queue['queueName'], resources['memory'], resources['vCores'])
PY

想定出力は次のとおりです(キューの表示順は異なる場合があります)。

fairScheduler
root.citizens 1024 1
root.priests 2048 2

ステップ3でスケジューラーを切り替える前に、このステップの確認を完了してください。

Capacity Schedulerを設定する

このステップでは、Capacity Schedulerに切り替え、各キューにクラスター容量の50%を割り当てます。

Hadoopユーザーとして、capacity-scheduler.xmlをHadoopの設定ディレクトリに直接書き込みます。/home/hadoopにファイルを置くだけでは、このスケジューラーによって読み込まれません。

cat > /home/hadoop/hadoop/etc/hadoop/capacity-scheduler.xml <<'XML'
<?xml version="1.0"?>
<configuration>
  <property>
    <name>yarn.scheduler.capacity.root.queues</name>
    <value>citizens,priests</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.citizens.capacity</name>
    <value>50</value>
  </property>
  <property>
    <name>yarn.scheduler.capacity.root.priests.capacity</name>
    <value>50</value>
  </property>
</configuration>
XML

子キューの容量の合計は100%になります。yarn-site.xmlでCapacity Schedulerを選択します。

sed -i 's/org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler/org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler/' /home/hadoop/hadoop/etc/hadoop/yarn-site.xml

新しいスケジューラークラスとキュー設定を読み込むため、ResourceManagerを再起動します。

yarn --daemon stop resourcemanager
yarn --daemon start resourcemanager

有効なスケジューラーとキューを確認します。

curl -fsS --retry 15 --retry-connrefused --retry-delay 1 http://localhost:8088/ws/v1/cluster/scheduler -o /home/hadoop/scheduler-capacity.json
python3 - <<'PY'
import json
with open('/home/hadoop/scheduler-capacity.json') as stream:
    info = json.load(stream)['scheduler']['schedulerInfo']
print(info['type'])
for queue in info['queues']['queue']:
    print(queue['queueName'], queue['capacity'])
PY

想定出力は次のとおりです(キューの表示順は異なる場合があります)。

capacityScheduler
citizens 50.0
priests 50.0

両方のキューがリソースを必要とする場合、各キューに保証される容量は50%です。未使用の容量は共有できます。そのため、これらの値を設定しても、使われていないリソースが未使用のままになるわけではありません。

まとめ

この実験では、Hadoop YARNで異なるスケジューリングポリシーを設定して適用し、リソースを効率よく割り当てる方法を学びました。Fair SchedulerとCapacity Schedulerを使いこなせば、アメンホテプは王国の国民にリソースを公平に配分し、神官が行う重要な作業を優先できます。

実際に手を動かすことで、複雑な環境でリソースを管理するHadoop YARNの強力な機能について、理解を深めました。この実験で得た知識を活用すれば、組織のニーズに合わせた、効率的で公平なリソース管理システムを構築できます。