DLLヘルが去ってパッケージヘルがやってきた

2015/3/17作成

現代の複雑化したソフトウェア開発では、全ての機能を独力で開発するということはほとんどなくなりました。多くの機能は既存のライブラリなりを利用し、そのソフトウェアで実現したい本質部分だけを実装すればいいということになっています。

これは、開発コストも抑えられますのでとてもいいことではあります。ただ、そのために利用されるライブラリの数がどうも臨界を突破しつつあるのではないかなぁというのが昨今の状況ではないかなと思ったりもします。

あるソフトウェアを利用しようとしてインストールすると、依存するパッケージが何十と同時にインストールされます。しかも、その大半は聞いたこともないものだったりもするわけです。まあ聞いたことがないのは私の不勉強だとしても、実際のところこんなにたくさんのコマンドやライブラリが同時にインストールされても把握しきれないですよ。

そして、一台のコンピュータにソフトウェアが一つだけしか使用されないということは滅多にありませんので、他にもいくつものソフトウェアがインストールされます。当然、それらのソフトウェアもそれぞれ何十というライブラリに依存していますので一緒にインストールされます。

これだけたくさんのライブラリが使用されていますと、当然に重なって利用されているものも出てきます。重複していても問題ないのが理想なんですが、実際にはソフトウェアそれぞれで依存しているバージョンが違っていたりもする。バージョン依存はなくても、コンパイルオプションの有無で食い違いがあったりもする。こうなると、それぞれのライブラリごとにどのバージョンなら大丈夫かとか調べて解決しないといけなくなってしまう。とてもコマンド一発でインストールして使えますって状態ではありません。

そして、インストールしたソフトウェアは日々バージョンアップしますし、ライブラリも個々にバージョンアップします。ということで更新すると、またコンフリクトが起こったりして解決に時間が掛かるということになるわけですね。

かつてWindowsではDLL Hellということがありました。アプリケーションが使用しているDLLがコンフリクトを起こしてシステム管理が事実上破綻してしまっていました。現代では.Net環境であればこうした問題は起こらないようになっていますので随分と状況は改善されています。思うにですが、現代のOSSはこのDLL Hellの轍をきれいにトレースしているような状況なのではないかなぁという気がします。ていうか、自分としては既に片手間の管理の限界を超えつつあって、なんとかならないかなぁと日々思っていたりもします。

各アプリケーションが依存するのはlibcのみで、それ以外の機能は全部個々実装していた時代に今更戻りたいとは思わないのですが、みんなが使うような著名なライブラリに関しては、どこかがまとめてライブラリパッケージとして管理してくれたりすると便利なんじゃないかなぁとか思ったりもします。GNUtoolsとか、それに近しいものもあったりしますけどね。ああいうのが、もっとたくさんあるといいなぁと。

あと、もう一つ別の解決方法というか逃げ口はjails/Dockerなどのコンテナ技術ですかね。一台のホストにいろんなアプリケーションをぶち込むんではなくて、1アプリ1コンテナにしてしまえば、この問題はかなり回避できるようになります。なんか無駄な感じがしないでもないですが、運用管理はある意味単純になるので楽になる方法ではあるように思います。

(2018/4/30追記)

この記事を書いてからしばらく経って随分と状況が変わったというか改善されてきたようですので追記しておきます。状況が変わったというか、2015年時点でもある程度あった話でしょうけれど、単にその頃の私が知らなかったという面と、まだ世間的に一般的ではなかったという面もあるかと思います。

まず言えるのは、アプリに依存するライブラリ類をグローバルにインストールすることがなくなったこと。アプリごとのローカルにインストールするのが一般的になりました。同じホストで動作するアプリでも、こっちのアプリではあるライブラリの特定バージョン、別のアプリでは同じライブラリの別バージョンで動作してるということがごく普通になりました。これは、そうした管理手法を実現するライブラリ管理システムが普及したということもありますが、最大の要因はディスクがそれだけ大容量で安価になったということですよね。ある意味、物理で殴って解決したとも言えなくもない。いや、いいんです。どんな方法でも解決できれば。

そして本文でも書きましたとおり、コンテナ技術が思った以上に普及して一般化したこと。もうアプリは専用のコンテナ上で動作するのは当たり前になりました。コンテナ技術とともに構成管理ツールも進化して普及してきましたので、デプロイごとに新規のコンテナを立ち上げるのも当たり前のことです。これで古いライブラリのゴミが残っていて誤動作したなんてこととも無縁になりました。

もちろん全ての現場でこのような技術が導入できているわけではありません。まだまだ旧来の手法を駆使していて、ライブラリの依存関係の調整に苦労しているエンジニアもたくさんいらっしゃるとは思います。しかし、解決の道は見えてきているというのは随分と先行きが明るくなったのではないかと思います。