2013年2月4日星期一

EMRのgangliaをカスタム設定:1秒ごとに監視する


はじめに

GangliaとはHadoopクラスタのCPU、メモリなどの性能を監視するツールである。AWSのEMRを使うと、EMRのBootstrap Actionを通じて自動的にGangliaをインストール、設定できる。自分で何をしなくてもGangliaを使える。便利が便利だけど、柔軟性を犠牲にした。EMRにデフォルトで設定されたGangliaはほとんどのニーズを満たせるけど、「特殊なニーズ」があればカスタムで設定できない。たとえば今回に遭った「特殊なニーズ」:実行時間が短い(1、2分間ぐらいだけ)MapReduceのタスクを監視したい。Gangliaはデフォルトで15秒ごとにサーバの性能を監視するので、1分間だけのタスクにおいて4つの記録しかなく、あまり意味がない。だからEMRのGangliaを「1秒ごとに監視する」ように設定するために、EMRのGangliaをカスタム設定する方法を調べた。この記事は「1秒ごとに監視する」の設定を例としてEMRのGangliaをカスタム設定の方法を紹介します。

EMRはGangliaを起動、設定する方法

まずEMRはGangliaを起動、設定する方法を見よう。EMRではGangliaを使用する方法はとても簡単だ。EMRのタスクを起動する時にBootstrap Actionに一つActionを添加して、スクリプトのアドレスは:s3://elasticmapreduce/bootstrap-actions/install-ganglia。Bootstrap Actionについて詳細情報はこちらへ。install-gangliaはRubyのスクリプトです。クラスタのインスタンスは起動完了してから、S3からこのスクリプトをダウンロードして実行する。このinstall-gangliaというスクリプトの内容を見よう。このアドレスからinstall-gangliaをダウンロードできる:https://s3.amazonaws.com/elasticmapreduce/bootstrap-actions/install-ganglia。内容は簡単だ。Hadoopのバージョンによって、もう一つのスクリプトをダウンロード、そして実行する。

executor.run("hadoop fs -copyToLocal s3://#{BUCKET_NAME}/bootstrap-actions/ganglia/#{version_num}/ganglia-installer .")

Hadoopのバージョンは0.20.205の場合、このスクリプトのアドレスは:https://s3.amazonaws.com/elasticmapreduce/bootstrap-actions/ganglia/2.0/ganglia-installer。このスクリプトはgangliaをインストールと設定する。中身を見よう。
まず、Gangliaをダウンロード、解凍する:

def download_and_unzip_ganglia
    run("mkdir -p ~/source")
    run("cd ~/source && wget http://#{BUCKET_NAME}.s3.amazonaws.com/bootstrap-actions/ganglia/2.0/#{GANGLIA}.tar.gz")
    run("cd ~/source && tar xvfz #{GANGLIA}.tar.gz")
  end
そして、様々な設定である。今回のタスクに関するのは二つ部分だけ。gmondの設定:

def configure_gmond  
  run("sudo ldconfig")  
  run("sudo gmond --default_config > ~/gmond.conf")  
  run("sudo mv ~/gmond.conf /etc/gmond.conf")  
  run("sudo perl -pi -e 's/name = \"unspecified\"/name = \"AMZN-EMR\"/g' /etc/gmond.conf")  
  run("sudo perl -pi -e 's/owner = \"unspecified\"/name = \"AMZN-EMR\"/g' /etc/gmond.conf")  
  run("sudo perl -pi -e 's/send_metadata_interval = 0/send_metadata_interval = 10/g' /etc/gmond.conf")  
  ......
  $e.run("sudo gmond")  
end 
gmetaの設定:

  def configure_gmetad
    ganglia_log_dir = "/mnt/var/log/ganglia/rrds/"
    ganglia_templates_dir = "/mnt/var/log/ganglia/dwoo/"
    run("sudo cp #{GANGLIA_HOME}/gmetad/gmetad.conf /etc/")
    run("sudo mkdir -p #{ganglia_log_dir}")
    run("sudo chown -R nobody #{ganglia_log_dir}")
    run("sudo sed -i -e 's$# rrd_rootdir .*$rrd_rootdir #{ganglia_log_dir}$g' /etc/gmetad.conf")
    run("sudo mkdir -p #{ganglia_templates_dir}")
    run("sudo chown -R nobody #{ganglia_templates_dir}")
    run("sudo chmod -R 777 #{ganglia_templates_dir}")
  
    #Setup pushing rrds to S3
    parsed = JSON.parse(File.read("/etc/instance-controller/logs.json"))
    newEntry = Hash["fileGlob", "/mnt/var/log/ganglia/rrds/AMZN-EMR/(.*)/(.*)", "s3Path", "node/$instance-id/ganglia/$0/$1", "delayPush", true]
    parsed["logFileTypes"][1]["logFilePatterns"].push(newEntry)
    run("sudo mv /etc/instance-controller/logs.json /etc/instance-controller/logs.json.bak")
    File.open("/tmp/logs.json" , "w") do |fil|
    fil.puts(JSON.generate(parsed))
    end
    $e.run("sudo mv /tmp/logs.json /etc/instance-controller/")
     
  end 
このganglia-installerはlinuxのsedなどのコマンドを通じてgangliaの設定ファイル内容を変える。私たちもこの方法でEMRのgangliaをカスタム設定できる。このganglia-installerを修正して、幾つかのsedコマンドを添加する。修正したganglia-installをS3へアップロードして、EMRのタスクを起動する時は自分のganglia-installを呼び出すようにBootstrap Actionを設定すればいい。

Gangliaを「1秒ごとに監視する」ように設定

Gangliaを「1秒ごとに監視する」ように設定するのは、実はとても難しい問題です。私はこの問題を解決のために、すごく時間をかかった。しかし、この記事の焦点はEMRのgangliaをカスタム設定の方法で、gangliaの設定方法じゃないので、関係があるgangliaの設定だけ紹介する。
Gangliaはgmondとgmetaという二つ部分がある。gmondはクラスタの全員のサーバに実行されていて、サーバーのパフォーマンスのデータを他のサーバーへ送信する設定である。gmondの設定ファイルはこのように:

collection_group {
  collect_every = 20
  time_threshold = 90
  /* CPU status */
  metric {
    name = "cpu_user"
    value_threshold = "1.0"
    title = "CPU User"
  }
  metric {
    name = "cpu_system"
    value_threshold = "1.0"
    title = "CPU System"
  }
  metric {
    name = "cpu_idle"
    value_threshold = "5.0"
    title = "CPU Idle"
  }
  metric {
    name = "cpu_nice"
    value_threshold = "1.0"
    title = "CPU Nice"
  }
  metric {
    name = "cpu_aidle"
    value_threshold = "5.0"
    title = "CPU aidle"
  }
  metric {
    name = "cpu_wio"
    value_threshold = "1.0"
    title = "CPU wio"
  }
  /* The next two metrics are optional if you want more detail...
     ... since they are accounted for in cpu_system.
  metric {
    name = "cpu_intr"
    value_threshold = "1.0"
    title = "CPU intr"
  }
  metric {
    name = "cpu_sintr"
    value_threshold = "1.0"
    title = "CPU sintr"
  }
  */
}
このデフォルト設定で、gmondは20秒(collect_every)ごとにサーバーのデータを取得して、もし値はvalue_thresholdを超えたら、すぐにクラスタへ送信する。もしそうじゃないと、90秒(time_threshold)ごとに送信する。つまり、gmondを1秒ごとに送信させるために、collect_everyとtime_thresholdを1に設定すべきである。

gmetaはクラスタ全員のgmondから集めたデータを整理、保存するプログラムである。gmetaの設定ファイルgmeta.confには今回に関する部分はこれ:

# What to monitor. The most important section of this file.
#
# The data_source tag specifies either a cluster or a grid to
# monitor. If we detect the source is a cluster, we will maintain a complete
# set of RRD databases for it, which can be used to create historical
# graphs of the metrics. If the source is a grid (it comes from another gmetad),
# we will only maintain summary RRDs for it.
#
# Format:
# data_source "my cluster" [polling interval] address1:port addreses2:port ...
#
# The keyword 'data_source' must immediately be followed by a unique
# string which identifies the source, then an optional polling interval in
# seconds. The source will be polled at this interval on average.
# If the polling interval is omitted, 15sec is asssumed.
#
# A list of machines which service the data source follows, in the
# format ip:port, or name:port. If a port is not specified then 8649
# (the default gmond port) is assumed.
# default: There is no default value
#
# data_source "my cluster" 10 localhost my.machine.edu:8649 1.2.3.5:8655
# data_source "my grid" 50 1.3.4.7:8655 grid.org:8651 grid-backup.org:8651
# data_source "another source" 1.3.4.7:8655 1.3.4.8

data_source "my cluster" localhost
デフォルトで15秒ごとに保存するので、このように修正する:

data_source "my cluster" 1 localhost
gmeta.confにはもう一つ注意すべきなところがある:

#
# Round-Robin Archives
# You can specify custom Round-Robin archives here (defaults are listed below)
#
# RRAs "RRA:AVERAGE:0.5:1:244" "RRA:AVERAGE:0.5:24:244" "RRA:AVERAGE:0.5:168:244" "RRA:AVERAGE:0.5:672:244" \
#      "RRA:AVERAGE:0.5:5760:374"
#
この部分はgmetaが違うインターバルのデータを保存する数の最大値を設定する。例えば、このデフォルトの設定で、1秒ごとのデータを最大244件だけ保存する。244件を超えたら24秒ごとに変換して保存する。24秒ごとのデータも最大244件、超えたら168秒ごとに変換する。だから、1秒ごとの最大件数をもっと大きく設定すべきだ。
まとめて、ganglia-installerをこのように修正する:
1.configure_gmondの部分に、この行を添加:

run("sudo perl -pi -e 's/collect_every *=.*/collect_every = 1/g;s/time_threshold *=.*/time_threshold = 1/g;s/value_threshold *=.*/value_threshold = 0/g' /etc/gmond.conf")
これで全部のグループを1秒ごとに設定した。
2.configure_gmetaの部分に、この行を添加:

run("sudo sed -i -e 's/data_source \"my cluster\" localhost/data_source \"my cluster\" 1 localhost/g' /etc/gmetad.conf")
3.configure_gmetaの部分に、この行を添加:

run("sudo sed -i -e's/# RRAs \"RRA:.*/RRAs \"RRA:AVERAGE:0.5:1:3600\" \"RRA:AVERAGE:0.5:24:3600\" \"RRA:AVERAGE:0.5:168:3600\" \"RRA:AVERAGE:0.5:672:3600\"/g' /etc/gmetad.conf")

自分のスクリプトでGangliaを起動

前の述べたように修正したganglia-installerをS3へアップロードする。S3のBucket名はmybucketと仮定する。そして、install-gangliaという簡単なスクリプトを修正する。まずganglia-installerを呼び出すコードの行を探す:

executor.run("hadoop fs -copyToLocal s3://#{BUCKET_NAME}/bootstrap-actions/ganglia/#{version_num}/ganglia-installer .")
このように修正する:

executor.run("hadoop fs -copyToLocal s3://mybucket/ganglia-installer .")
この修正したinstall-gangliaもS3へアップロードする。最後にEMRタスクを起動する時はBootstrap Actionを一つ添加して、スクリプトのアドレスを「s3://mybucket/install-ganglia」と設定する。ようやくカスタム設定のGangliaが起動された。

他の可能な方法

今回は「sed」コマンドと「perl  -pi -e」で設定ファイルの内容を変える方法を使った。他の方法もある。例えば、まずgmond.confを修正して、S3にアップロードしておき、ganglia-installerにはこのファイルをダウンロードする。あるいはganglia全体をダウンロードして、必要な設定をして、S3にアップロードして、ganglia-installerはこの設定して置いたgangliaをダウンロードする。試したことがないけど、同じように動かせると思う。

没有评论:

发表评论