<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Spot VM on Marketechlabo</title><link>https://www.marketechlabo.com/tags/spot-vm/</link><description>Recent content in Spot VM on Marketechlabo</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><lastBuildDate>Thu, 13 Jun 2019 00:00:00 +0900</lastBuildDate><atom:link href="https://www.marketechlabo.com/tags/spot-vm/index.xml" rel="self" type="application/rss+xml"/><item><title>格安に使えるGCEのプリエンプティブインスタンスの勝手に停止対策</title><link>https://www.marketechlabo.com/server-infrastructure/gce-preemptible-instance/</link><pubDate>Thu, 13 Jun 2019 00:00:00 +0900</pubDate><guid>https://www.marketechlabo.com/server-infrastructure/gce-preemptible-instance/</guid><description>
&lt;p&gt;格安で使えるGCEのSpot VM（旧プリエンプティブインスタンス）。問答無用でシャットダウンされるというクセが困りものだが、使いようによってはハイスペックのインスタンスを安く効果的に使うことができる。ここではそのシャットダウン対策と最大限活用するためのヒントを紹介する。
機械学習用途ではVertex AI TrainingやGKE Autopilotなどマネージドサービスが充実しており、GCE直接利用は減少傾向にあるが、GPU/TPUを利用した機械学習ワークロードでコストを抑えたい場合などにSpot VMは有効である。&lt;/p&gt;
&lt;h2 id="spot-vm旧プリエンプティブインスタンスとは"&gt;Spot VM（旧プリエンプティブインスタンス）とは&lt;/h2&gt;
&lt;p&gt;Google Compute EngineのSpot VMは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最大24時間の制限は撤廃されているが、勝手に停止される（停止することをプリエンプト＝preemptするという）&lt;/li&gt;
&lt;li&gt;安い（同スペックの通常インスタンスの半額以下、1/3程度）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という特徴がある。ミッションクリティカルな用途には向かないが、何よりも安いのでCPUやメモリを大量に使う機械学習の処理をするには向いている。ただし停止された場合には最初からやり直しとなる。処理をプリエンプトされないうちに終わらせるのがいい（GCEの余剰リソースを使うインスタンスであるため、CPUを数多く使うほどプリエンプトされやすくはなる）&lt;/p&gt;
&lt;h2 id="インスタンスがプリエンプトされたときに通知"&gt;インスタンスがプリエンプトされたときに通知&lt;/h2&gt;
&lt;p&gt;インスタンスがプリエンプト状態になると&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1分後に強制停止される&lt;/li&gt;
&lt;li&gt;シャットダウンスクリプトが実行される&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり停止1分前にスクリプトを実行できる。1分間の間に終了処理を入れることができる。
猶予は1分しかないので、大きなファイル（学習結果のスナップショットなど）の保存などはできない。
停止したことを通知し、必要に応じてインスタンスを再起動して再学習開始するなど、何らかの対応をできるようにするのがいいだろう。
ここではSlackに通知する方法を紹介する。&lt;/p&gt;
&lt;h3 id="slackにメッセージ送信"&gt;Slackにメッセージ送信&lt;/h3&gt;
&lt;p&gt;シャットダウンスクリプトで&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;preempted&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;curl -Ss http://metadata.google.internal/computeMetadata/v1/instance/preempted -H &lt;span style="color:#e6db74"&gt;&amp;#34;Metadata-Flavor: Google&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$preempted&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;TRUE&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; project_id&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;curl -Ss http://169.254.169.254/computeMetadata/v1/project/project-id -H &lt;span style="color:#e6db74"&gt;&amp;#34;Metadata-Flavor: Google&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; instance_name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;curl -Ss http://169.254.169.254/computeMetadata/v1/instance/name -H &lt;span style="color:#e6db74"&gt;&amp;#34;Metadata-Flavor: Google&amp;#34;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timestamp&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;date +&lt;span style="color:#e6db74"&gt;&amp;#39;%Y-%m-%d %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cat &lt;span style="color:#e6db74"&gt;&amp;lt;&amp;lt;EOF | curl -Ss -X POST &amp;#34;https://hooks.slack.com/services/xxxxxxxx/yyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzz&amp;#34; -d @- -o /dev/null
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;payload={&amp;#34;username&amp;#34;: &amp;#34;system monitor&amp;#34;, &amp;#34;text&amp;#34;: &amp;#34;$project_id / $instance_name is being preempted (${timestamp})&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="なるべく無停止状態で起動させておく"&gt;なるべく無停止状態で起動させておく&lt;/h2&gt;
&lt;p&gt;プロセスがストップされるのは仕方ないが、サーバ自体は常時（に近く）稼働させておきたいケース。
&lt;code&gt;gcloud compute instances start&lt;/code&gt;コマンドを使うとインスタンスを起動できるが、すでに起動している場合は無視される。そこで
他のとりあえずgcloudコマンドだけ実行できればいいマシン&lt;/p&gt;</description></item></channel></rss>