研究開発の実験に使えるホスト名の一覧をMackerelを使って素早く取得する

最近は仕事でサーバーの監視を行なうサービス開発(Mackerelチームに所属しています)の開発をしていますが、1年ほど前までは大学の研究室や企業の研究所で自然言語処理や機械学習の研究を行なっていましたid:syou6162です。研究開発における実験をするときにMackerelをこういう使い方をすると便利かも?というのがあったので、紹介します。

研究開発の実験あるある

研究では計算機をがしがし使って実験を行なうのですが、それらの計算機は当然一人で使うわけではなく、みんなで使います。他人がガンガン実験しているホストに途中からジョブを投下するのは迷惑ですし、実験によってはメモリが大きいマシンでないと実行できないなど、実験の前にあれこれ確認すべきことがあります。前職では例えばGangliaを見ながら

  • memoryが64GB以上積んでる
  • load averageが1以下

などの条件に合うホストを探して、GXPでホストを指定し、パラメータ変えて実験をぶん回すというのをよくやっていました。

しかし、実験をやる度にGangliaで計算機の混み具合を確認して…というのは率直に言って面倒でした。条件を指定したら使えるホスト名のリストを返して欲しいです。これを行なうシェルスクリプトを書いてはいましたが、サーバーの購入や撤退などによりホスト名のリストを定期的に更新する必要があるのもよくない点でした。

Mackerelを使って楽をする

Mackerelはサービスやロールといった概念でホストをまとめて監視することができます。例えば自分が所属しているグループでホストをグルーピングしたり、深層学習用のGPUのホストをまとめてみたり、といった形です。ホストにメタデータを登録、取得することができるので、それを使うのもいいかもしれません。その上でload averageが閾値以下のホストで条件付けして一覧を取得する、といったことがMackerelだと簡単にできます。サーバーのセットアップのついでにmackerel-agentも仕込んでおくようにする(ワンライナーでインストールできます)と、ロールに所属するホストの一覧などはMackerelのapiが返してくれるので、手元に一覧を持っておく必要はなくなります。これにより、実験に使えるホストをさくっと探すといったことができるようになります。

実例(Go言語による簡単なスクリプト)

例として"My-Machine"というロールに所属しているホストの中でload averageが1以下のホスト名のみを取得するというのをやってみましょう。Mackerelではコマンドラインツールや各種言語のライブラリ(下のはほんの一部)がOSSで用意されているので、それを使うと簡単です。

今回は私が最近Goに入門中なので、Goのライブラリを使ってみます。ちなみにGoのライブラリは最近のリリースで出たグラフアノテーションに対応しています:)

さて、さっそくコードです。以下のコードをgo run find_hosts_for_experiments.goといった形で動かすと条件に合うホスト名が出てくるので、あとはこれをgxpなどに投げればよいだけです。

 package main

 import (
     "fmt"
     mkr "github.com/mackerelio/mackerel-client-go"
     "os"
 )

 func main() {
     client := mkr.NewClient("YOUR_MACKEREL_API_KEY")
     // collect host names
     hostCandididates, _ := client.FindHosts(&mkr.FindHostsParam{
         Service: "My-Machine",
     })
     var hostIDs []string
     for _, h := range hostCandididates {
         hostIDs = append(hostIDs, h.ID)
     }

     // get metric values
     metricValues, err := client.FetchLatestMetricValues(hostIDs, []string{"loadavg5"})
     if err != nil {
         os.Exit(0)
     }

     // filter hosts by loadavg5
     for _, h := range hostCandididates {
         hostID := h.ID
         loadavg5, ok := metricValues[hostID]["loadavg5"]
         if !ok {
             continue
         }
         if loadavg5.Value.(float64) < 1.0 {
             fmt.Println(h.Name)
         }
     }
 }

ロールに所属するホストの一覧を取得して、そのホストのloadavg5も取得、それらが1以下なら出力するだけという簡単なものです。Rubyでも似たようなことが簡単にできると思います。

まとめ

Mackerelはサーバーの監視や状態の通知を簡単に行なうことができるので、それ自体はもちろん便利ですが、ホストの情報を使うことで研究開発を少し便利にすることができるという例を紹介しました。