Cloud Build で呼び出した Python 内から subprocess でも仮想環境を使う

解決したい問題

from subprocess import run

run(["python", "-m", "hoge.fuga"])
# hoge/fuga.py
import numpy as np

を Cloud Build上で実行しようとすると

ModuleNotFoundError: No module named 'numpy'

などと言われてしまう

解決方法

こうする

import sys
from subprocess import run

run([sys.executable, "-m", "hoge.fuga"])

解説

sys.executablePython インタプリタの実行ファイルの絶対パスを示す文字列となっている https://docs.python.org/ja/3/library/sys.html#sys.executable

リンク

Cloud Functions については、 https://stackoverflow.com/questions/54938099/how-to-run-a-subprocess-inside-google-cloud-function-in-python の回答がまさにそれ。python3を使うという手もあるらしいが、現時点(2024年3月)ではうまくいかなかった

ゆっくり仕事をするインセンティブ

はじめに

早々に仕事を終わらせられるような能力があったとしても、合理的な判断をした結果、あえてゆっくり仕事をすることがあります。ここでは、労働者の立場になってみて、仕事をゆっくり行うかどうかの判断基準を検討してみましょう。

仕事を遅く行うメリット

重要な仕事だと思ってもらえる

具体的にどんなことをやったのか、どんな成果が得られたのかを知らない状態で、有能そうな人に「この仕事、意外と難しくて二徹くらいかかっちゃいました」などと言われると、とても大きな仕事を成し遂げたかのように見えます。そこに寝不足みたいな雰囲気が付いていると、なおさら苦労してやってくれたかのような感謝の気持ちが芽生えます。

これを逆手に取って、実際には簡単だった仕事の報告を遅らせることで仕事の成果を盛ることができます。ゆっくり仕事をすることで、この仕事は難しく、複雑で、重要なものなんだということを印象付けましょう。ただし、既に貴方が無能であることがバレている場合や、報告相手がその業務内容をよく理解している場合は逆効果なのでやめておきましょう。

残業代が貰える

続きを読む

airflow で CPU が100パーセントに張り付いてしまうときに見直したい設定

結論

Apache Airflow の起動時に CPU が 100% に張り付いてしまう際には、 AIRFLOW__CORE__MIN_SERIALIZED_DAG_UPDATE_INTERVAL などの設定値を変更することで改善される可能性があります:

AIRFLOW__CORE__MIN_SERIALIZED_DAG_UPDATE_INTERVAL=600
AIRFLOW__CORE__MIN_SERIALIZED_DAG_FETCH_INTERVAL=300
AIRFLOW__SCHEDULER__MIN_FILE_PROCESS_INTERVAL=600
AIRFLOW__SCHEDULER__SCHEDULER_IDLE_SLEEP_TIME=5
AIRFLOW__SCHEDULER__PARSING_PROCESSES=1

背景

極力リソースを割かずに検証を進めていた*1ため、 Apache Airflow の DB バックエンドはデフォルトの SQLite のままになっていました。 ところが、この方法は公開環境では推奨されない設定であり、

  • ジョブの並列実行ができないため、今後のデータ基盤のスケーラビリティが悪い
  • リリースのたびに過去の実行ログが消えるため、過去のジョブの動向の把握が困難になる可能性がある

という問題を抱えています。

実際、airflow web server を起動してアクセスするとこれらの設定を見直すことを促す警告が現れます。

そこで、 DB バックエンドを MySQL にするように、起動時の環境変数として以下の変更を加えました。

設定名 変更前 変更後
AIRFLOW__CORE__EXECUTOR SequentialExecutor LocalExecutor
AIRFLOW__CORE__PARALLELISM (not set) 1
AIRFLOW__DATABASE__SQL_ALCHEMY_CONN (not set) mysql+pymysql://(自前のMySQL環境への接続情報)

すると、具体的なジョブが実行されていない状態で(=scheduler の起動だけで)使用中のインスタンスの CPU がほぼ 100 パーセント使われてしまうようになっていました わかりにくい画像ですが縦軸の下端は 99.5% であり、常にほぼ 100%に張り付いていることがわかります

※この変更の導入前では、何もしない時間帯にはほぼ0で推移していました

対処したこと

https://github.com/apache/airflow/issues/13637#issuecomment-892768703 のコメントを参考にして、設定値を見直しました。 具体的には以下の設定を環境変数として追加しています*2

AIRFLOW__CORE__MIN_SERIALIZED_DAG_UPDATE_INTERVAL=600
AIRFLOW__CORE__MIN_SERIALIZED_DAG_FETCH_INTERVAL=300
AIRFLOW__SCHEDULER__MIN_FILE_PROCESS_INTERVAL=600
AIRFLOW__SCHEDULER__SCHEDULER_IDLE_SLEEP_TIME=5
AIRFLOW__SCHEDULER__PARSING_PROCESSES=1

それぞれの値の意味は https://airflow.apache.org/docs/apache-airflow/stable/configurations-ref.html を参照してください。これらの設定値を反映させることにより、100%に張り付かなくはなりました

おそらくDBアクセスに関係する AIRFLOW__CORE__MIN_SERIALIZED_DAG_UPDATE_INTERVAL あたりが功を奏したのだと思います。どの設定が最も効いたかは気になるところですが、 scheduler の設定値見直しもパフォーマンスに寄与しているはずなので、この際全ての設定を反映させたままにしておきます。

今回は Database Backend を SQLite から MySQL に変更したタイミングでパフォーマンスの限界に対面することになりましたが、データ基盤の規模やアーキテクチャに応じて、今後もこまめに設定値を見直す必要があると感じました。

*1:フルマネージドサービスである MWAA や Cloud Composer はスモールスタートには不向きと判断していました

*2:公開環境/ステージング環境で異なる設定値をデプロイ時に代入することを意図して、設定は全て環境変数に寄せています。airflow.cfg に設定する場合は、適宜読み替えてください

AHC027(マラソンマッチ)の参加者の使用言語の分布を調べてみた

競技プログラミングコンテストサイトである AtCoder のマラソン部門のコンテストが開催されていました atcoder.jp 本記事では、コンテスト参加者の使用しているプログラミング言語はどういうものがあるのかを順位から調査してみました。

本記事は、前回の調査から約二年半程度経過したということで、上位層の使用するプログラミング言語に大きな変化があったかを検討します wakabame.hatenablog.com

続きを読む

よく使うコマンドをまとめる(自分用メモ)

Linux(shellコマンド)

ファイル検索

dir/ 配下の.py または .ipynb ファイルで hogehoge を含むものを検索したい
grep -r --include='*.py' --include='*.ipynb' "hogehoge" dir/
dir/ 配下の特定の文字列を含むファイルを一括で置換したい

例えば、 calender のタイポを一括で修正したい場合

find dir/* \( -name "*.py" -o -name "*.ipynb" \)  | xargs sed -e 's/calender/calendar/g' -i
  • mac OS の場合, POSIX sed が標準で入っているので上書きしてしまってから実行するとよい
brew install gnu-sed --with-default-names

git

複数に分かれたコミットをまとめたい

すでに作成したコミットに対して、些細な修正を加えた場合など

git add hoge.py
git commit -m "Add important method"
git add hoge.py
git commit -m "些細な fix"

git rebase -i HEAD~~
# "些細な fix" のコミットを `pick` から `f` (`fixup`) に変更することで、直前のコミットにまとめられる
git push -f origin feature/branch_name

git rebase を行うとそれ以後のハッシュ値が変更されてしまうので、main ブランチを marge した後は行わないのが無難

terraform

tfstate ファイルから hoge.tf に含まれるリソースを一括で削除する
grep "resource" hoge.tf | sed -e "s/resource //g" -e "s/\" \"/\./g" -e "s/\"//g" -e "s/ {//g" | xargs -I arg terraform 
state rm arg

count や for_each で作成したリソースがどうなるかは検証していません

tfstate ファイルに稼働中のリソースを紐づける

事前に resource "aws_subnet" "example".tf ファイルに記載しておく

terraform import aws_subnet.example subnet-01234567890123456

コンソールから手作業で作ったリソースを紐づけるときに便利

tfstate ファイルに紐づいたリソースの状態を見る
terraform state show aws_subnet.example

ここから適当にコピペして .tf ファイルに転記すると手作業で作ったリソースを削除せずにIaCができるが、以下に注意

  • 他のリソースの値がリテラルで入る( instance_id = i-hogehoge などとされてしまう)ので、aws_instance.example.id などで書き換える
  • idarn などの自動的に決まるべき値も出力されるため、適宜削除する必要がある
  • セキュリティーグループルールなど、忘れがちなリソースがあるので、検証環境で横着せずいったん削除してから作り直しておくと安心
tfstate ファイルの内容を全件見る
terraform show -json | jq . | tee current_tfstate.json

パスワードなどの機微情報も見えてしまうので、作業したらファイルを消すこと、パブリックな環境では実行しないこと

AWS

SSMを使って踏み台サーバーを経由せずにSSHトンネリングを実現する
aws ssm start-session \
    --target i-hogehoge --document-name AWS-StartPortForwardingSession \
    --parameters "portNumber=80, localPortNumber=56789" \
    --region ap-northeast-1 --profile profile_name```

この状態で localhost:56789 にアクセスするとトラフィックi-hogehoge の 80番ポートにリダイレクトされる

windows(command prompt)

AWS

SSMを使って踏み台サーバーを経由せずにSSHトンネリングを実現する
aws ssm start-session --target i-hogehoge --document-name AWS-StartPortForwardingSession --parameters "portNumber=3389, localPortNumber=13389" --region ap-northeast-1 --profile profile_name

この状態で「リモートデスクトップ接続」から localhost:13389 に接続すると i-hogehoge にRDP接続することができる。

  • i-hogehoge は Windowsマシンであること
  • ログイン時に求められるユーザー名は Administrator, パスワードはEC2のコンソール画面から取得する
  • ちなみに、Windows マシンは Linux マシンに比べて(同一スペックの場合)割高です

離散カントロビッチ問題のエントロピー正則化とその双対問題

離散カントロビッチ問題とは?

次のような問題を考えます

商品を  n 個の工場から,  m 個のお店に輸送することを考えます.
商品の輸送に掛かる労力が「重量」と「始点と終点の距離」の積で決まっているとき,
トータルの労力が最小になるような運び方はどんなものでしょうか?

続きを読む

Python で mod. p での二項係数 (nCk mod. p) の求め方

過去記事, Python で mod の下での逆元を計算するテーブルを作成する - わかばめにっき では, modの下での階乗の逆元を求めました.

本記事では, 以下の記事を参考にして二項係数  {}_nC_k を前処理  O(N), 実行  O(1) で行うアルゴリズムを紹介します.
drken1215.hatenablog.com

続きを読む