Ansibleを最大で25倍高速化するMitogenについて調べてみた

大規模環境になると、Ansibleの実行速度が課題になります。
`Pipelining`や`ControlMaster`を設定することで、デフォルト設定の2倍程度は速くなりますが、それでも、まだ遅い、、、!! 遅すぎる、、、!!

もっと速くする方法はないのかと調べていると [Mitogen for Ansible](https://networkgenomics.com/ansible/) というソフトウェアが、**『環境によっては、最大で25倍になるよ!!』**と謳っているではありませんか!!

わかります。怪しい、怪しいですよね、急にそんな倍率出されるとびっくりしちゃいますよね。私もです。

ですので、本記事では、**Ansibleの実行が2倍から5倍速くなり、一部の環境では25倍速くなる**と謳う [Mitogen for Ansible](https://networkgenomics.com/ansible/)について個人的に調べてみました。


（Ansibleの公式ドキュメントの「Other Tools And Programs」の[Other Tools](https://docs.ansible.com/ansible/latest/community/other_tools_and_programs.html#other-tools)には、記載されているため、Ansibleコミュニティでは知名度のあるソフトウェアなのかもしれません。バリバリ使用しているよという方がいれば情報求む、、、）

## Mitogenとは

早速 Mitogenの実態に迫るため、 `mitogen`で、Google検索してみます。

<img width="1290" alt="mitogen.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363620/0e0b946a-c8d1-67d9-2353-bc535ced8c3f.jpeg">

あー、`分裂促進因子活性化タンパク質キナーゼ` ね、わかる。超わかるわ。毎日使ってるわ〜。



。。。まって、待ってください!! まだ閉じないで!! ふざけているわけではないのです。
気を取り直して、`ansible mitogen`で検索して見つけた、以下の[公式ドキュメント トップ](https://mitogen.networkgenomics.com/)を見てください。

<img width="1001" alt="Mitogen_Documentation.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363620/6320070c-6833-d011-117b-983d75f02a51.jpeg">

さっき見た図と似てませんか?

> Mitogen is a Python library for writing distributed self-replicating programs.
(Mitogenは、分散自己複製プログラムを作成するためのPythonライブラリです。)

とのことで、なるほど、ソフトウェアが分裂促進因子的な動きなんだなとわかります。（なにそれかっこいい。）
ドキュメントの概要を読みすすめた内容を抜粋すると以下です。

>・the remote machine need not even have free disk space or a writeable filesystem
　（リモートマシンには、空きディスクスペースや書き込み可能なファイルシステムが不要）
・the goal is to provide a robust and efficient low-level API on which tools like Salt, Ansible, or Fabric can be built
　(目標は、Salt、Ansible、Fabricなどのツールを構築できる堅牢で効率的な低レベルAPIを提供すること)
・The focus is to centralize and perfect the intricate dance required to run Python code safely and efficiently on a remote machine, while avoiding temporary files or large chunks of error-prone shell scripts, and supporting common privilege escalation techniques like sudo
　（一時ファイルやエラーが発生しやすいシェルスクリプトの大きなチャンクを回避し、sudoなどの一般的な権限昇格技術をサポートしながら、リモートマシンでPythonコードを安全かつ効率的に実行するために必要な複雑な処理を一元化して完成させることに焦点をあてている）


上記から Mitogenは、**Ansibleのようなリモート実行ツールを作成するためのもので、
Pythonコードを安全かつ効率的に実行するための複雑な処理を一元化することに注力しており、
それらを実現するために、分散自己複製プログラムを利用している**と理解できます。

以上より、このライブラリの概要はわかりました。

さらに、Mitogenについて、知りたい方は、[How Mitogen Works](https://mitogen.networkgenomics.com/howitworks.html)を参照すると良いでしょう。
ただし、冒頭から、以下のような記述があります。（Google翻訳）

> リモートマシンにソフトウェアをインストールせずに、リモートPythonプロセスをブートストラップするという一見魔法のような偉業を達成するには、ある程度の努力が必要です。関係する手順は、カジュアルな読者にはすぐに明らかになることはまずありません。また、発見するためにいくつかの反復が必要なので、以下で徹底的に文書化します。

徹底的に記載されたドキュメントを読んだのですが、恥ずかしながらカジュアルな読者の私には完全に理解することができませんでした。

ふわっとした理解のまま、唇を噛み締めて、本題の[Mitogen for Ansible](https://mitogen.networkgenomics.com/ansible_detailed.html)のページを確認していきます。

## Mitogen for Ansible とは

[公式ドキュメント](https://mitogen.networkgenomics.com/ansible_detailed.html)によると、Mitogen for Ansibleは、AnsibleのUNIXコネクション層とモジュールランタイムを再設計したもののようです。

ドキュメントの冒頭で、

> 実行対象ホストの変更なく、最小限の設定だけで、シェル中心で低速なAnsibleの実装から、SSH経由でトンネリングされた永続的なインタープリターへのリモートプロシージャコール実行に切り替えることで、純粋なPython実行に相当するほど非常に効率的になります。

と説明されており、察しの良い方であれは、この時点で速くなることが理解できるかと思います。

ここで、Ansibleの低速といわれる処理を確認しておきましょう。
以下の流れでAnsibleはリモートホストに対して、構成変更を実施します。

1. SSHセッションを開く
2. シェルにログイン
3. ネットワーク経由でPythonコードをコピー
4. コピーしたコードを使用してリモートホストに一時ファイルを作成
5. Pythonインタープリターで一時ファイルを実行

デフォルト設定で、上記は1タスクごとに実行されます。

冒頭に申し上げた`Pipelining`を有効にすることで、実行元ホストから、SSHを介して直接実行するようになるため、ファイル転送のオーバヘッドがなくなり、高速化されます。

Mitogenにおいても、Pipelining同様に、実行元からSSHトンネリングしてリモート実行するため、デフォルト設定よりも高速化されることがわかります。

では、Pipeliningと変わらないのではないかという疑問が湧きますが、[こちらの記事](https://www.toptechskills.com/ansible-tutorials-courses/speed-up-ansible-playbooks-pipelining-mitogen/)のベンチマークを確認すると、Pipeliningよりも、Mitogenのほうが早いことがわかります。


### なぜ、Mitogenのほうが早いのか

Mitogen for Ansibleの[Overview](https://mitogen.networkgenomics.com/ansible_detailed.html#overview)に記載されています。以下に翻訳した内容を記載します。

>・ユーザーアカウントごとに1つのsudo呼び出しおよびターゲットごとに1つのコネクションを利用します。
ステップ（タスク）間で重要な状態をRAMで維持でき、認証イベントを繰り返すことがないため、システムログにスパム送信されません。そのため、SSHマルチプレキシング と pipeliningを利用した場合よりも優れています。
（補足： SSHマルチプレキシングについては、[こちら](https://qiita.com/c0tt0n-candy/items/83dfbb158f4520bba7e2#ssh%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%AC%E3%82%AD%E3%82%B7%E3%83%B3%E3%82%B0)の記事で詳しく記載されています。）

>・単一のネットワークラウンドトリップを使用して、ターゲットのRAMに既に存在しているステップを実行します
多重化されたSSHチャネルの作成をなくすことにより、プレイブックの各ステップで1 msのネットワーク遅延ごとに4 msのランタイムが節約されます。

>・プロセスは積極的に再利用され、Pythonを呼び出してインポートを再コンパイルするコストを回避し、プレイブックの各ステップで300〜800ミリ秒を節約します。

>・コードは一時的にRAMにキャッシュされるため、SSHパイプライン処理と比較して帯域幅の使用量が1桁少なくなり、通常の実行でネットワークを通過するフレームが約5倍少なくなります。

>・ターゲットファイルシステムへの書き込みが少なくなります。
典型的な構成では、Ansibleは繰り返しZIPファイルを書き換えて、ターゲット上の複数の一時ディレクトリに抽出します。クロスアカウントでの一時ファイルに関連するセキュリティ問題は完全に回避されます。


> 上記の効果は、多くの短命アクションを実行するPlaybookで最も強力です。Ansible実行のオーバヘッドの大半は、単純なコマンドを実行したりファイルを書き込んだりするようなwith_itemsループの操作が占めます。

とのことで、SSHマルチプレキシングおよびPipeliningを利用する場合よりも、高速化される理由が以下であるとわかりました。

**・1つのSSHコネクションで処理を実行し、処理をキャッシュしている
・上記のキャッシュにより、実行元<->実行対象間のトラフィックも少ない
・ターゲット上での一時ファイル書き込みが少ない**


以上から、Mitogenを利用することでより高速化される環境というのは、単純な処理が多い（キャッシュが利用できる）場合や、レイテンシが大きい場合（帯域が狭い、伝送距離が長いなど）だと考えられます。

実際に[こちらの記事](https://www.toptechskills.com/ansible-tutorials-courses/speed-up-ansible-playbooks-pipelining-mitogen/)では、伝送距離が長い部分では大きな効果がでています。
たしかに、一部の環境では、25倍という数字を叩き出す可能性もあるのではないかと思われます。

## まとめ

以下に、簡単にまとめます。

・Mitogenは、PipeliningとSSHマルチプレキシングを利用した場合に比べて、Ansible実行速度が速い
・それは、sshコネクションの再利用と、実行コードのキャッシュが実現している
・キャッシュによるファイル転送量の削減や、ネットワークコネクションの再利用により、環境によっては、デフォルト設定の25倍高速化されるのもありえなくない

ロジックを深く理解していないのと、バージョンがまだv0.x台なので、まずは、個人で利用してみようかと思います。

## (おまけ) インストール方法

以下に記載があるように、2stepで簡単導入できます。使ってみるぜ/使ってみたぜという勇者のご報告をお待ちしております。
https://networkgenomics.com/ansible/

また、Mitogenのリポジトリも貼っておきます。starが1.1kついてますね。結構人気です。
https://github.com/dw/mitogen/


明日は、@sudomeg の「よくあるデータ出力機能を二段階に分けて作ったら機能の汎用性がとても高くなったはなし」です。お楽しみに!!