メンテのいらないソフトウェア

ソフトウェアエンジニアとして働き始めて 20 年以上になります。 元々ソフトウェアでいろいろ作りたくて就いた職業なので、結構な数のプロダクトを開発してきました。

私がメインで開発したもので OSS として出ているものでは、

  • yrmcds: memcached クローンで、レプリケーション機能などを持つ
  • usocksd: SOCKS4/5 サーバー & ライブラリ
  • transocks: アプリのネットワーク通信を透過的に SOCKS サーバーにプロキシする透過プロキシ
  • coil v2: Kubernetes の CNI ネットワークドライバ
  • moco: MySQL を自動運用する Kubernetes オペレーター
  • accurate: Kubernetes 上で namespace ベースのソフトマルチテナンシーを実現するためのソフトウェア

などがあります。これらのソフトウェアの多くは、現役で使われています。

私の主な仕事はこれらのソフトウェアの開発・メンテナンスではありません。 過去の主要な仕事内容としては cybozu.com のローンチプロジェクトの責任者であったり、開発・運用の本部長であったり、今は新規プロダクトのアーキテクトを務めていたりします。

プロフェッショナルなソフトウェアエンジニアの心がけとして、以下のようなことが良く言われます。

コードを書くことが仕事じゃない。問題を解決できるなら、むしろコードは書かなくて済むほうがいい。

なぜなら、「コードを書くとバグがあったりメンテナンスの工数がついてまわったりする」からです。 そうだよなと思うと同時に、「いや俺、コード書きたくてソフトウェアエンジニアになったんですけど」と本音のところで思ったりしています。

で、本題。コード書きまくってソフトウェアプロダクト作りまくっても、そのバグやメンテナンスに時間を取られない方法はないのか。 あります。

冒頭にあげたソフトウェアプロダクトは、その多くが初期の 1~2 年で機能・品質的に十分な成熟を迎え、その後ほとんどメンテナンスする必要がありませんでした。 例えば yrmcds は2013年に公開後、2015年の version 1.1.5からはほぼメンテナンスフリーで、現在でも cybozu.com のセッションストレージを担っています。

このように機能・品質の成熟を早めに済ませることで、メンテナンスにかかる時間を極力ゼロにするのが、私の基本的な戦略です。 良い点は、多くのいろいろな種類のソフトウェアを開発できて幸せっていうところです。 あまり良くない点としては、コミュニティを形成してどんどん機能拡張するようなことはしないので、人気のあるソフトウェアにはなりにくいってところです。 私個人はコミュニティとか面倒なので、これでいいやと思ってはいます。

では、機能や品質をどう早めに成熟させるか。私が心がけているのは以下です。

  • 必要になる機能は最初にリストアップを済ませる。考慮しておくことで実装を後に回しても整合性がとりやすいです。
  • 品質は一切妥協しない。ドキュメントに書かれている挙動はすべて自動テストでカバーする。後からぼろぼろバグがでてくる事態が避けられます。

例えば、moco では最初のバージョンから以下の機能を提供していました。もちろんすべてテスト済みで。

  • MySQL 8 に対応 (5.7 以前はサポートしない)
  • 接続の自動切換えと負荷分散
  • 自動フェイルオーバー
  • 手動および自動のスイッチオーバー
  • Errant transaction を持つインスタンスを自動検出しクラスタから隔離
  • 既存の MySQL から非同期レプリケーションするクラスタを作成可能
  • 単体構成の MySQL との高い互換性
  • バックアップとリストア
  • バージョンアップ
  • メトリクス
  • my.cnf のカスタマイズ
  • innodb_buffer_pool_size の自動設定
  • Pod 定義のカスタマイズ
  • Service 定義のカスタマイズ
  • Slow query log
  • PodDisruptionBudget を自動設定

その他としては、設計や仕様について各種のドキュメントをしっかり作っておくと、他の人にあとをお任せしやすいです。

cf. 技術文書の書き方 · GitHub

以上、そんな考え方・やり方もあるんだなと思っていただければ。