たごもりすメモ

コードとかその他の話とか。

GradleプロジェクトでArtifactoryに依存ライブラリを置くときのKotlin DSLでの記述

なんかちょっとハマってたのでメモ。要するに公式ドキュメントのをどう書くか、だけなんだけど。

Gradle Artifactory Plugin - JFrog - JFrog Documentation

結果的にはこのissue commentを読んでやった。

// build.gradle.kts
plugins {
  // ... others
  id("com.jfrog.artifactory").version("4.17.2")
}

repositories {
    mavenCentral()
    maven {
        url = uri("https://mycompany.jfrog.io/mycompany/libs-release/")
        credentials {
            username = System.getenv("MY_ARTIFACTORY_USERNAME")
            password = System.getenv("MY_ARTIFACTORY_PASSWORD")
        }
    }
}

// snip

上記Issue commentにあった認証方式としてのBasic認証の明示は結果的には必要ないっぽい。
あと関係ないけど、上記URLの "mycompany" の部分、ふたつめを "artifactory" (設定サンプルにある)から変え損ねててずっと404になって悩んでた。

コロナ禍の最中にグランツーリスモSPORTで10kg痩せた話

TL;DR

  • 2019年11月末 73.9kg → 2020年8月末現在 64.2kg になるまで痩せた
  • 原因がグランツーリスモSPORT*1しか思い付かない
  • 食事制限などは一切なし、普段からそんなに食生活が偏ってはいないと思う、が、毎晩ビールは飲んでるぞ
  • (追記) プレイ中の心拍数が100〜140くらいで、これはいい運動になってそう

経緯

身長171cmの自分も、自転車をだいぶ強烈にやっていた頃*2には58〜60kgの体脂肪率ひと桁とかだったが、9年経った2019年年始には68kgくらいまで増量していてこれはいかんと思っていたところ、2019年1月にスキーで骨折し全く動かない生活をしばらく過ごしていたら73kgぐらいまで一気に太った。これはやばい。

とはいうものの、ライフイベントがあれこれ*3あったりもして、あまり気にすることなく危機感のない生活を送っていたら2019年のうちは体重が全然変わらなかった。んで2019年11月末に体重を計ってから体重計にも近付かずふらふら暮らしていた*4ところ、3月末の時点で気付いたらズボンがぜんぶユルくて歩いてるとずり落ちてくる。全部2019年12月末に買ったもの。おかしいなと思いつつこのときにズボンをまた買い足したんだけど、そのズボンが今現在(2020年8月)ではもうウエストが余ってベルト無しにはまったく履けない。

そうなって初めてこれはもしや痩せてるのでは、と思って自宅の体重計に乗ってみたら、いきなりものすごく痩せた数字が出てきた。びびった。65.7kg (7月上旬)。その後も特に特異値というわけではなくて、継続して体重は低下し、現在では64.2kgを記録している。

原因の考察

さて何をしたかというと、何もしていない……。もちろんコロナ禍のまっただ中なので、外に出掛けたりはほとんどしていない。運動も(自転車の新車を買ったのもあって)自宅の近所を巡ったりはたまにするが、強度が低くて話にならないのは自分で分かっている。これで痩せるなら全人類にダイエットは必要ない。

と思ったのだが、唯一思い付いたものがある。グランツーリスモSPORTだ。この2017年10月発売のゲーム、PSVRの体験のためにすぐ買ってある程度やっていたもののしばらく放置していたのを、2020年2月から再開したのだった。

www.gran-turismo.com

これ、以前にやっていたものの積み重ねから、今となってはまあまあ真剣に・そこそこのレベルで競えるようになってきた。特にコロナで出掛けられなくなってからのストレス解消に毎日1〜2時間*5修練を続け、オフラインでできる範囲のものをやり終えたからしょうがなくオンライン(スポーツモード)のレースをやりはじめたのが3月20日からであった。

もちろん、これだと思ったのには理由がある。単純に、毎回プレイするたびにめちゃくちゃ汗をかく。

f:id:tagomoris:20200826135656j:plain
ハンドルコントローラのセットアップ

こんな感じのハンドルコントローラ環境でやってるんだけど、冬のうちから、とにかく汗をかく。椅子に布がかぶせてあるのは、自分があまりに汗をかくんで妻が嫌がったからという理由による。今だと1時間レースやる*6と水を1リットルは飲む。もちろんクーラーは動かしているが。

使っているのはロジクールG29。そこまで高級なモデルでもないが、フォースフィードバックがちゃんとかかり、路面の状態もわかる(と思う)。

gaming.logicool.co.jp

やっているモードにもよると思う。オンラインでのレースやっているときの疲れかた(と汗のかきかた)は、一人でタイムアタックしてるときに較べて圧倒的に激しい。周囲のクルマの動きに気を配らないといけないし、僅かなブレーキミスが衝突に繋がるし、などなどで緊張感がぜんぜん違うからだと思う。自分のDR*7が上がったことで周囲も上級者になってきて、全体としてミスの少ないレースを強いられているのもあるはず。

というやつを、最近ではほぼ休みなく毎日1時間はやっている。これではないか。というかこれ以外に思いつかない。まあ休みなくペダル踏みつけハンドル回してるからなあ。

追記: プレイ中の心拍数を計ってみた

お昼の直後ということもあるので、他の時間帯よりも心拍数は上がりにくい状態でこのくらい、だと思う。この強度の運動が着替え・機材の準備なしにできて、かつ天候も関係なしって、ダイエット用にだいぶいい運動なんじゃないのかな。すげえ。 (追記ここまで)

そのほかの生活

食生活などはほとんど変わっていない、というかそもそも痩せたのを自覚したのがだいぶ遅かったくらいだし、まったく何もしていない。

もちろんコロナな状況なので、飲み会なんかは皆無。しかし元々そんなに高頻度で飲み会に参加していた生活でもないし、今だってたまには近所の店で外食したりもする*8。自宅での夕食時にはたいていビール飲んでるし、そのあとさらに晩酌でビールや日本酒を飲んだりもする。F1のレースがある週末なんかは330ml瓶を3本空けちゃうことだってあるし、もちろんそうなるとツマミだって用意しちゃうし。

とはいえ、普段の生活から、あまり不摂生はしてなかったなとは思う。ポテチをひと袋もりもり食べるのだって月イチくらいだし*9、ラーメンも週1くらいで食べるとはいえ大盛りにしないしスープを全部飲んだりもしない*10、晩酌のツマミもそんなにハイカロリーはものはあんまり食べてないかな、くらい。

食事は朝昼晩食べている。普通にごはんもパンも食べてる。野菜を多めにしようとはしているかもしれぬ。揚げものは自宅でやるのが面倒だからあんまり食べないなー。

というわけで

みんなもグランツーリスモSPORTやってオンラインレースで楽しくカロリー消費しようぜ!

おまけ: 最近の生活環境

前にリモートワークについてのエントリを買いてから、COVID-19はそうそう簡単に収束しないなというのが見えたのと、夫婦そろってしばらくはリモートでの仕事が確定、自分の場合はCOVID-19が収まってもかなりの割合で自宅からの勤務ができそうという話が会社から出たりもして、そんなわけで自宅で仕事をする環境を整えるため、えいやで一軒家(賃貸)に引越した。GW直前から探しはじめて5月半ばにはもう決まってた、6月半ばに引越し、という感じでだいぶスピード引越し。

間取りとしては3LDKあって仕事用の書斎がひと部屋とれたので、ワイドディスプレイやオフィスチェア、電動昇降式デスクなど一式を揃えて快適に仕事ができるようになった。扉が閉まるからZoomとかやってても他への影響が小さくて良い。

f:id:tagomoris:20200824111326j:plain
書斎のワークデスク

ひとりが書斎を使うとして、もう一人も快適に仕事するためのスペースが自宅内あちこちで取れるようにしてある。特に屋上テラスと階段下ヒキコモリスペースがお気に入り。

f:id:tagomoris:20200824111327j:plain
テラスと階段下

仕事は、もちろん、だいぶやりやすくなった。自宅内を移動するだけでも気分転換にはなるし、業務中に妻との距離がある/スペースが隔離されているのは、お互いに気をつかわなくていい。あと単純にかなり広くなったので、長期間籠もっていてもストレスが溜まりにくくなったのもあると思う。

出勤頻度の激減*11を見越して駅からはちょっと歩くけど、そこまででもない、くらい。それでもまあいいお値段の家賃になったけど、これは必要経費かなあ。最初から2〜3年の様子見のあいだだけ住む、ぐらいの感覚で決めたので許容範囲ということにしている。別の場所に行くなり買うなりはその間に社会情勢を見ながら考えるつもり。 さて、どうなるんですかねー。

*1:フォースフィードバックのあるハンドルコントローラ使用

*2:毎日夜に自宅で1.5〜2.5時間くらい自転車用のトレーニングマシンに乗っていたり、ヒルクライムレースに年5,6レースくらい出ていた

*3:結婚とか……

*4:元々コロナ前ではしょっちゅう各地の温泉施設とかに行ってそこの体重計に乗ってたので自宅の体重計に乗る習慣がなかった

*5:がっつりやるときは3時間くらい

*6:典型的には20分くらいのレースx2と10分くらいのレースx1

*7:ドライバーランク、E,D,C,B,A,A+,Sがあるなかで自分は現在B

*8:もちろん夫婦のみで、あまり密な感じの店は避けるようにしている

*9:今でもやる

*10:無料のごはんもつけない

*11:激減もなにも引越し後はまだ一度も出社してないんだけど

systemdのenvfileを普通のコマンド実行時に流用する

普段はsystemd経由で実行しているコマンドをCLIから実行したい、環境変数もsystemd経由で起動するときと同様にセットしたいのでenvfile(EnvironmentFile)をそのまま使いたいんだけどなんか微妙にやりにくくないか、と思って何度か調べたことがあるんだけど、あんまりうまい方法が検索結果に出てこない。

んだけど、あれ、これ簡単じゃん。(追記: これはごく単純なケースでしか動かなかった、後段参照)

$ env $(cat myenvfile | grep -v '^#') target-command

envfileをシェルスクリプトとして実行して追加された変数をなんとかexportすれば……みたいに考えてたけどenvコマンドで一発だった。変なコメントとか入ってると厄介だけど、こんな感じでいいのでは。ということでメモ。

空白を含む値の処理

まあいいやとスルーしてたけど値が空白を含むときに上記のコマンドだと正常に動きませんね。

$ env "$(grep -v '^#' myenvfile)" target-command

こうかな。catする意味は別になかった。

空白を含む値の処理again

上の例だとぜんぜんダメだった。ファイルのほぼ全体が最初の環境変数名にセットされて終わるという悲しい結果になる。
というか色々試してるとenvコマンドが key=value ペアのparseになんか独自のルールを持っている? っぽくって、空白文字をエスケープしようと思うとぜんぜんうまくいかない。

んで同僚の@k0kubun氏とあれこれやっていたところ彼が見付けたのが set -o allexport を使うハック。それだとちょっと他への影響が出るので、サブシェル化して実行すればいい。
このときenvfileは以下のように書かれている必要がある。

VALUE_ONE=1
VALUE_TWO="value may contain spaces"

このファイルを読み込むときに set -o allexport して全てを環境変数にする。それをサブシェルの中でやって、んでコマンドを実行する。

(set -o allexport; source envfile; target-command)

できたー!

この時期、業務で低パフォーマンスを出し続ける覚悟

今この時期、もちろん弊社もCOVID-19関連の事情を鑑みてテレワーク……とはあんまり自分の回りでは言わない、リモートワーク(もっと言うとWFH: Work From Home)してる。自分が完全WFHに切り替えたのは1月半ばくらいだったかなー。もう3ヶ月ですね。

で、どうかというと、業務のパフォーマンスで見ると、自分のいまのパフォーマンスは明らかに悪い。少なくとも良くはない。それは自分でもわかってる。
でももう、これはしょうがない、と思うので、覚悟している。高パフォーマンス出せたらいいとは思うけど、同時にどう考えても無理して仕事で高パフォーマンス出すような時期でもないと思う。

だからこのエントリは、まあしょうがないよね、というのを受け入れよう、という話です。*1

なおこのエントリは業種柄、リモートワークに移行しやすい自分の話しかしていません。生活必需品や医療品関連の小売店舗や病院、窓口が必要な店舗や役所、流通関連など、その他さまざまな職種の現場でいま現在も社会を支えてくださる方々には本当に感謝しかありません。ありがとうございます。

普段の話

COVID-19以前の弊社はといえば、基本的にはオフィスに行って仕事をしましょう、というのがルールだった。うちのチームのマネージャーはユルいんでいつWFHしても全く問題ないんだけど、まあ全体的にはそう。
で、自分も性格的にオフィスで仕事する方が気持ちの切り替えができて好きなので、通常は普通にオフィスに出勤して、仕事して、帰るという感じだった。自宅でコード書くときはラップトップのディスプレイとキーボードでもまあ別にいいや、という感じ。

一方ミーティングとかは、同僚がそもそも世界中に広がってることもあって常にZoomだったので、そこは基本的に変わってない。オフィス内でも同僚と会話するけど、それは運良くその仕事に関わっている同僚が同じオフィスにいればであって、いなければZoomで話すことになる。
いっしょのタスクをやっている同僚がバンクーバー在住の人になることが多かったので、そういう人達とは定期的にZoomで話す時間を作ったりしていた。

自宅の仕事環境の話

元々オフィスで仕事する前提でいたから、自宅に腰を落ち着けて仕事する環境がなにもない。外部ディスプレイや外付けキーボードすらなかった*2。場所もいまはダイニングテーブルを主に使ってるけど、自宅がそもそも生活のことだけ考えてたから個室がなくて、家族の生活とモロに筒抜け状態になってたりする。
なんでそんな環境なのと言われると、単に自宅にその必要を感じてなかったから、以外には何も理由がない。

で、これはもちろん効率が悪い。コードを書くときに集中するのも難しいし、Zoomで会議やるにも家族への配慮がいるし、雑談したいからZoom繋ぎっぱなし、みたいなのもほとんど不可能*3。お昼ごはんのたびにディスプレイやラップトップをどかしたりするのも地味にめんどい。
そもそもZoomで繋ぐこと自体が自宅全体へのストレスになる*4というのはちょっと発見だった。これ、同僚と常に話してるみたいなマネージャー陣は大変だろうな。

社会環境の話

もちろん、COVID-19まわりの情報も気になる。Twitterのタイムラインは荒れ気味だし、Facebookでもあれこれ声高に言う人もいるし*5、TVは……まあほとんど点けないけど。ゲームとかNetflixにしか使ってないな。
で、そういうあれこれに気が散る。政治の話もあるし、海外の状況も(特に同僚が多くいる国や地域の話は)気になる。あれこれ。これも集中を失わせる大きな要因になっている。

生活習慣の話

普段自分は休日にわりと外での活動でストレス発散することが多い。サイクリング、ドライブ、キャンプ、スキー、本屋めぐり、美術館や博物館、あれやこれや。全部できなくなった。
最近はだから自宅でゲームやって、あとは電子書籍やらAmazon経由で買った本やらを読むんだけど、もちろん普段のストレス発散方法がとれないのは大きい。平日の活動にも影響を与えていると思う。

最近の意識的な活動の話

とにかく休憩を頻繁に取ろうとする、昼休憩をだいぶ長めにとる、ようにはしている。夕方も、とにかく早目に仕事を切り上げるようにはしている。
あと水分補給をすぐ忘れるので、常に湯冷ましを手元に置くようにしている。日に1リットルくらいは飲んでるけど、もうちょっと多めにしたいなあ。難しい。

最近会社が会計年度の切り替わりをズラしたりみたいなのの副作用で手持ちの有給休暇残日数がかなりあるので、これを、意識してとろうかなと思っている。今週も火曜は意味もなく休みにしてのんびりしてた。これも馬鹿にならない効果があるなと思ったところ。継続的に週の真ん中の休みを入れていこうかなと思っている。

仕事以外にやっていた活動はほぼ全滅気味。やばい。関係者の方にはマジで申し訳もない、が、今のところどうしようもない。生活ペースをもうちょっとちゃんと組み立てられればなんとかなるかもしれないが、ならないかもしれない。

結論

というわけで、短い時間を集中しにくい環境で働いていて、パフォーマンスがいいわけがない。これはもうしょうがないな、と受け入れることにした。

会社側の評価どうなるとかいう話もなくはないだろう*6けど、それとは関係なく「低パフォーマンスしか出せない自分へのストレス」みたいなものがあって、これを直視できないうちは、そのストレスが雪だるま式にふくれてる気がした。2月〜3月中旬くらい、だいぶそういうストレスを感じていた気がする。

これはたぶん本質的に危険で、どうにかしたほうがいい。とはいえストレス解消のためのアクティビティも軒並み封じられているから、何か方法を考える必要がある。
自分はそのストレスを、直視して、無視することにした。無視するといっても心の中で思っているだけだと徹底できない部分もあるから、こうやって文章にして明示することにしてみた、というのがこのエントリでした。

うん、大変だけど、とにかく健康は大事。ウィルスのせいで肉体的な健康も危険だが、とはいえ、いやだからこそ、メンタルの健康も大事だと思う。大事にしていきたい。

*1:なおうちのチームのマネージャーは、常に健康第一、休憩をもっと頻繁に長くとれ、パフォーマンスとかよりそっちの方がはるかに優先だ、と毎週の1on1で常に言ってます

*2:これは最近オフィスのを送ってもらったが、特定の置き場所がないので使うたびに上げたり下げたりしている。めんどい。

*3:Zoom飲み会も、だからちょっと配慮というか心構えが必要になってしまう

*4:安心して生活音を立てられる、という状況がちょっとでも失われるのはストレスなんだなあ、と今回初めて実感した

*5:今回の情勢でこれはちょっとという人のフォローを外したりもした

*6:自分は弊社について、この状況下でのパフォーマンスを理由に理不尽なことをしないだろうと信頼しているけれど、まあそれはそれ

TokyuRuby会議13に行ってLTやって飯王を(また)とった

今年もまた行われたTokyuRuby会議に、先日のRubyKaigiでLTやったMaccroのネタをまた持って参加してきた。

TokyuRuby会議13 - Regional RubyKaigi

が、Maccroは進捗があまりなく、どっちかというと今回もサントリーさんのスポンサーによるビール飲み放題があるので、それにあわせてガッと食べられる食べ物を持っていったのが結果的にメインになってしまった感。
なんにせよ大変楽しいイベントでした。運営のみなさん、会場提供のSpeeeさん、ビール飲み放題のサントリーさん、ありがとうございました。

食べ物のはなし

去年は渾身の一品で狙いに狙って飯王をゲットしたのもあって、今年は少し前まではまあ頑張らなくていいかなーと正直思っていたんだけど、いろいろあって結構な額のふるさとアレをアレした結果、最近慢性的に冷凍庫が肉等で溢れる事態となっていた。
これがマジで困るので、しょうがないからそのキロ単位の肉塊をいくつか投入しておいしくして持っていけばいいのでは? というアイデアが降臨する。しかもAsakusa.rbの花見を切っ掛けにイノベーションのアイデアが降臨したのでそれも投入。結果として、単品飯王をぶっちぎりでいただき、かつ(他の2品もあって)合算飯王までゲットしてしまった。完全勝利だ。




特に焼売は超ウケがよくて、ほかほかと湯気を上げてサーブしていたらサントリーさんのスタッフの方が「おなかがすいてきたんですが……」といらしたので、人数ぶん持っていってもらったりしてた。いつも座ってたらビールが運ばれてくるのだが、これで多少でもお返しができただろうか。

焼売はもちろん現地で蒸し上げたわけではなくて、実際には自宅で蒸したあと現地では蒸すことでほかほかに加熱する、というくらい。ただそれで十分おいしいくらいに温かくなった、はず、というかいま気付いたが俺は当日現地でひとつも食べていない!!!!!!!!!!!!!!!!!!!!!!!!

会場で電源を使わず*1に食べ物を温める方法に関しての今回のイノベーション携帯おかん器だ。これはAsakusa.rbの花見で野外・火気禁止の公園においていかに日本酒を温めるかという議論の中で発見されたもので、実際に花見で役立ったんだけど、そのときに「これは食品も温められるのでは?」と思い付いてからはTokyuまでは黙ってたw
さすがに直接的な火力がそこまでないのでどう使うかな、という方向からそれに向く料理として焼売を選択したのが実際のところで、あとは冷凍庫に大量にあった鶏肉を見て鶏肉焼売にすることにした、という感じ。おいしくできてよかったよかった。

ほかに豚しゃぶ肉が3kgあったのでそのうち2kgを雑に豚しゃぶにした。冷凍庫が空いて助かりました。
あと手羽先は当日朝に存在に冷凍庫内の存在に気付き、これくらいで美味くなるやろ、という感じの適当な調味料といっしょに圧力鍋で煮込んだ。割とおいしくできてて本当によかったよ……。

しゃべった

まあなんかしゃべりましたね。おわり。

*1:みんな使いはじめると会場の電力供給が保たないから禁じ手

高負荷システムでNVMeデバイス使用時のfstrimとdiscard mount optionの話

先にまとめると

  • ディスクI/Oに高い負荷をかけるシステムでNVMeデバイスを使うときweekly cron jobでfstrimが走る状況になってたら停止しろ
  • じゃないとfstrimが走った瞬間にI/Oパフォーマンスが刺さって死ぬ
  • fstrimを停止するならdiscard mount optionを有効化しろ、ただしその状態でのI/O性能で問題ないかどうか測っておけ
  • discard mount optionを有効化しても大きいファイルの削除には気をつけろ、プチfstrimみたいになるぞ
  • 追記されるばかりで大きくなるファイル(そして削除されるファイル)はNVMeじゃないデバイスに置いとけ

高I/Oスループットを期待するシステムでのNVMeとfstrim

社内で小さめのインスタンスを多く並べてトラフィックを捌いてたのを色々要件があって大きめのインスタンスにまとめるようなシステムアップデートをやってたんだけど、ローカルファイルシステムに大量の小さいファイルを書く構造をとって、そこを高I/OパフォーマンスなデバイスつまりNVMeを使うことで全体の性能を上げる、みたいな構成にした。

ベンチマークをとってもだいぶ良い感じだったのであれこれ試してから万全の体制……のつもりで本番投入したところ、見事に刺さった。突然ストレージのI/Oパフォーマンスが劇的に下がって全プロセスがスタックするというトラブルが、しかも複数のAWSリージョンでなぜか同時*1に起きた。初回は混乱したままインスタンス増加や入れ替えなどを行って原因がわからねーなーと思ってたんだけど、どうも見てると毎週同じ曜日の同じ時刻に発生している。なんだこれは。

で、調べてみたらこの時刻は weekly crontab のジョブが実行されるよう /etc/crontab が設定されていて*2、 このタスクのひとつとして /etc/cron.weekly/fstrim というやつがあって、これが実行開始されたあとストレージI/Oのパフォーマンスが劇的に悪化するという現象が確認できた。

fstrimがなんなのか大雑把に言うと、SSDやNVMeはデバイス側で使用中のブロックを管理しているが、ファイルシステムは普通ファイル削除時にはファイルシステムメタデータを削除するだけなので、デバイス側の使用中ブロック情報との間で齟齬が生まれる。fstrimコマンドはこれを解消するために、使用しなくなったブロックをデバイスに通知するためのTRIM命令をまとめて発行するコマンドだ、と自分は理解している。あとは他の解説とかを読んでくれ。例えばAWSのドキュメント "インスタンスストアボリュームの TRIM のサポート"にもこのあたりのことが書いてあって、fstrimを当たり前に使え、となっている。 で、I/O負荷がそう高くない普通の*3システムであれば、ヒマなときにやっとけばいいだろうということで、日曜早朝*4に実行するというcron jobの設定が行われていたのだった。

しかし自分の手元のこのシステムにおいては、ものすごい勢いでファイルを作っては削除してを繰り返す。そのパフォーマンスを担保するためにNVMeデバイスを使ってるんだから当然とも言える。そして大量にファイルが削除されているということはTRIMされるブロックもものすごい量に及ぶため、fstrimを実行した瞬間に大量のTRIMオペレーションが実行されて該当デバイスおよびファイルシステムのI/Oレイテンシが激増、システム全体が死亡するという状況になっていた。 ステージングなどの環境で気付けなかったのは、fstrimによるパフォーマンスの低下はブロックデバイスへの書き込み量に顕著に依存する、ということによる。本番環境のようなトラフィックが無い環境ではfstrimによる影響が軽微な範囲で収まってしまい、気付くのが困難だったためだ。

f:id:tagomoris:20190624102638p:plain
fstrimが走った瞬間にloadavgが激増して死亡の図

ということで、ファイルシステムでの高スループットI/Oを期待したシステムでfstrimが起動し、その瞬間I/Oパフォーマンスが劇的に低下して無事死亡することになっていた。これ、普通に他所でも起きるんじゃないのかなあ。AWSでNVMeのあるインスタンス使う人って高いI/O性能を期待する人が多いんだろうから、ドキュメントがfstrim実行しろってのは大丈夫なのかと思うけど。

discard mount optionの有効化と次なるI/O性能低下

ところでfstrimについて調べると出てくるドキュメントにはdiscardというmount optionについての記述が出てくる。これはファイルを削除したときにすぐにTRIMオペレーションをブロックデバイスに対して発行するためのもので、当然だがデバイスへの命令が増えるということは、全体のI/Oスループットはいくらか下がる。このためか、例えばRHEL8のドキュメントなどを見ると、避けられない場合を除いてはfstrimによるバッチ処理を推奨している……が、正直これもどうなんだと思う。 一般的にコンピュータシステムの性能をコントロールしやすいのは、時々やってくる高負荷のスパイクよりも、圧倒的に、普段の平均的に少し低い性能のほうだ。予測もコントロールもしやすい。しかもfstrimによる負荷はどのくらいファイルが削除されたか、という極めて変動しやすい要素に依存しているため、事前に予期するのは不可能といっていいと思うんだけど。

ということで、普通にNVMeデバイスを使用するシステムを運用するなら、discard mount optionは有効にするべきだと思う。ので、してみた。もちろんdiscard mount optionによるI/Oスループットの低下には注意する必要がある。各種メトリクスを監視しつつ、本番トラフィックからいつでも外せるようにして注意深くやってみた。 が、また変なことが起きた。全体の性能は問題ないものの、今度は毎時で小さいスパイクが発生するようになってしまった。fstrimによるほど致命的ではないが、本番トラフィックに晒しておくにはちょっとマズい感じのやつ。

f:id:tagomoris:20190624104106p:plain
毎時loadavgがちょっと上がるの図
f:id:tagomoris:20190624104133p:plain
毎時nginxのwaiting queueがちょっと伸びるの図(別時間)

これがなんなのかと悩んでみたんだけど、発生時間を手がかりに調べてたら、わかった。crontabによるhourly cronの起動時刻で、何が起きていたかというとlogrotateだった。いやー、まさかねー、って感じだったよ。

discard有効ボリュームにおけるアクセスログのrotate

まさか現代のマシンでlogrotateの負荷が問題になるか? と思ってしばらく自分も混乱していた。はるかな大昔はサーバのCPUコア数も少なく、その少ないコアがlogrotate時のgzip圧縮で持っていかれて全体のパフォーマンスが低下する、みたいなことを経験したことがある。そんなことが現代でまた起きるか? みたいな感じ。

実情として、このサーバ(で動いてるnginx)が処理してるトラフィックはそれなりにあるので、アクセスログについてはローカルストレージでの保存期間はとらず、hourlyでlogrotateにかけ、また保存世代数はゼロにしてある*5。これでも毎時40GBくらいの量にはなっている。

で、logrotateがこのアクセスログをrotateするということは、つまり、40GBぶんのブロックに対して一気にTRIMを実行する、ということだったのです。discard mount optionが有効の場合は。これに気付いたときは割とがっくりきた。discard mount optionを有効化することでBatch TRIMから逃げられたと思っていたのに、アクセスログのせいでMicro Batch TRIMとでも言うべきものが起きていたのだった。 これが即座に原因だと断定できなかったんだけど、その理由はファイル削除のタイミングとI/Oパフォーマンスの低下のタイミングが微妙にズレることがあるせいだった。これはTRIMオペレーションが実際に実行されるのは非同期化されており、ファイルの削除から少しのタイムラグがあるケースがあるためのようだった。

さてこれが分かれば結論は簡単で、アクセスログをNVMeじゃないデバイスに置いてやればいい。TRIMオペレーションが必要なければこの問題は起きない。問題のインスタンスアクセスログ用の領域を確保したEBSボリュームをアタッチして、そこにログを書くよう変更してやった。解決!*6

まとめ

NVMeデバイスは高I/Oスループットを発揮できて便利だが、安定したスループットを期待したいのならdiscard mount optionを有効にして運用しよう。またそのデバイス上での巨大なファイルの削除は避けるべきで、そのような例としてはアクセスログなどがある。気をつけよう。

*1:日曜午後3時45分過ぎ

*2:なお全インスタンスタイムゾーンUTCにセットされているため、使用中の全リージョンで同一のタイミングでこのジョブが実行されていた

*3:サーバ用途でない

*4:日本時間で15:47はサーバのローカルタイム(UTC)で6:47である

*5:余談だが、このログはFluentdで即座に読み出して外に転送・保存しているので、この運用で良いのです

*6:なお選択肢としては、NVMeデバイスアクセスログを書きつつもっと頻繁にlogrotateする、という手もなくはない。しかし結局負荷のスパイクの深刻さがファイルサイズに影響されるという状況は変わっておらず、将来的にアクセスログの成長速度がさらに増加したときにトラブルを起こすという潜在的な危険を抱えたままになるので、自分としてはその手段は避けたほうがよいと思う。

RubyKaigi 2019いってきた&LTやってきた

はい、今年のRubyKaigi 2019は福岡でしたね!

rubykaigi.org

私事でばたばたしてたんだけど、ずっと前から参加を予定してたものだしで、行ってきた。今回もいいカンファレンスだったし、福岡はいい街だしで、よかったですね!

f:id:tagomoris:20190425125930j:plainf:id:tagomoris:20190419172042j:plain

LTやってきた

元々メイントークでproposal出してたんだけど落ちちゃって、LTに出したら通った、のでやってきた。時間がなかったので細かい説明をちゃんとやるより、インパクトとネタ重視で。

内容はRuby 2.6で追加された RubyVM::AbstractSyntaxTree を使ってマクロを実現するぜ! というやつ。コードはこちら。

github.com

これ自体はもうちょっと機能追加とか機能修正したりしてから別途エントリを書くつもり。GW後かなー。あとActiveRecordプラグインとして一部機能を切り出したりしたほうが多くの人にはわかりやすいかもなあ、とも思っている。これは誰かに相談してみたい。
とはいえそれなりに使えるプロダクトを作ったと思っている。着眼点はそんなに悪くない気がするのでもうちょっとプロダクトとしてのアピールを別途してみたい。

f:id:tagomoris:20190417164146j:plainf:id:tagomoris:20190419193845j:plainf:id:tagomoris:20190421134657j:plain

LTとしては……こういうLTってだいぶ久し振りにやった気がするけど、当初時間がまったく足りないと思われていた割にちゃんと時間内に最後までしゃべれたし、ウケを狙ったところではちゃんと取れたし、よかったよかった。

f:id:tagomoris:20190419220337j:plainf:id:tagomoris:20190420010942j:plain

そのほかカンファレンス

今年はとにかくパターンマッチがアツい! あと継続してJITと型とGit移行と……あれやこれや。
あと RubyVM::AbstractSyntaxTree には何人もの人が目をつけてて、あちこちでコード解析や書き換えみたいな話があった模様。自分が聞いてた @joker1007 さんのトークとかもやってることの共通点がめちゃくちゃ多くて一人でウケてた。

f:id:tagomoris:20190417214029j:plainf:id:tagomoris:20190417215631j:plainf:id:tagomoris:20190417230420j:plainf:id:tagomoris:20190417230935j:plain

クロージングで言ってたことだけど、とにかく "We Code" に尽きるな、と思っている。また面白い/興味深いコードが書けたら、次回のRubyKaigiでもなんか話したい。

f:id:tagomoris:20190417222112j:plainf:id:tagomoris:20190417223727j:plainf:id:tagomoris:20190417224444j:plainf:id:tagomoris:20190417221319j:plain

そのほか福岡など

今年はとにかくPartyがなんか色々とおかしくて、前日はESMのPre Partyでナイトクルージング。船。イベント感がすごい。

f:id:tagomoris:20190417184115j:plainf:id:tagomoris:20190417190510j:plain

1日目のOfficial Partyは商店街の貸し切り……とはいえ通常営業の店もあったりで普通の歩行者なんかも混ざっててマジでカオス。クレイジーという言葉がぴったりだった。すごかった……。スタンディングで日本酒飲みながらダラダラしてた。

f:id:tagomoris:20190418201646j:plain

3日目はArm Treasure Data主催のAfter Party。テラスから外が開けてていい会場でしたね! ここはいろいろ見回ったり受付やってる時間もあったりで、個人的にはちょっとお仕事モードだった。まあ、まあ。今年も @tanaka_akr さんが「テンションが上がってきたのでスライド作った」というからゲリラテックトークをやってもらったのはすごくよかった。@a_matsudaさんに「録画しといてください」と事前に言われてましたがすっかり忘れてました。

あとはもつ鍋食べたり水炊き食べたりお寿司食べたり。いやー、いい福岡だった。また行きたい。

f:id:tagomoris:20190419195552j:plainf:id:tagomoris:20190419201441j:plainf:id:tagomoris:20190419204218j:plain

f:id:tagomoris:20190420122112j:plainf:id:tagomoris:20190420122906j:plainf:id:tagomoris:20190420132128j:plain

f:id:tagomoris:20190421134701j:plainf:id:tagomoris:20190421135415j:plainf:id:tagomoris:20190421141321j:plain

まとめ

来年は松本でお会いしましょう。