Perl5.8が現役で稼働

大森貴博氏:さて、ここからレガシーの話に移っていきます。専門用語で技術的負債ですね。

その1つがPerlです。これは「Perl自体がレガシー」と言いたいわけではありません。それならまだよかったんですが。というのも、こういうことです。

実はいまだにPerl5.8という太古のバージョンのPerlを使っています。右の年表を見るとわかりますが、初版が2002年。ライブドアブログのローンチの1年前です。当時は最新版でしたが、今となってはもうやばいですね。

これを使い続けていること自体、逆に技術力高い気もしますが、意味もなく使い続けているわけではなくちゃんと事情があります。というのも、mod_perlが現役だからなんです。

mod_perlが何か簡単に説明すると、コンパイル済みのPerlプログラムをキャッシュして高速化するApacheモジュールです。確か2010年ぐらいまでは社内でも多く使われていましたが、その後、PSGIという仕組みに置き換わってゆき、今では絶滅危惧種です。

このmod_perlですが、バージョン1.3ということで相当古いんです。なぜmod_perl 1.3なのかというと、社内版Sledgeがmod_perl 1.3しか対応してないという事情があります。そのため、mod_perl 1.3が対応しているApacheも1.3までなので、古いApacheを使う必要がありました。これが完全にレガシーの連鎖を生み出しています。

さらにここからがカオスなところなんですが、実は新しいPerlも使っています。それでも少し古いんですが、バージョン5.16。これ、いいことじゃないかと思うのですが、このことが原因で新旧2つのPerlが混在する状況が生まれています。

1つのリポジトリで複数のバージョンの実行環境があるとどうなるか、想像できますか? Perlの場合、マイナーバージョンが変わるとバイナリ互換性が失われるので、新旧Perl、それぞれに対してモジュールのセットアップやアップデートをかける必要があるので、単純に管理コストが2倍になっています。

さらに、プログラムを書くときにも新旧バージョンの互換を考える必要があるので大変です。Perlはバージョンが変わっても比較的互換性が保たれる言語ですが、うっかりすると致命的なエラーが発生してサイトが落ちる可能性があるので、わりとスリリングです。

MySQL4.0によって生まれた数々の苦しみたち

このように、Perlだけでも苦しみの深いライブドアブログですが、もちろんこれだけでは終わりません。

最後の事例ですが、MySQLについてお話しさせていただきます。もちろんただのMySQLではなくて、ブログの最大にして最強のレガシー、MySQL 4.0との戦いの歴史を紹介させていただきます。

MySQLというとみなさん馴染み深いと思いますが、4.0ってどうですか? おそらく知っている方はいても、もう使っている方はいないと思います。

ライブドアブログはメインのデータベースとしていまだに4.0を使い続けているんですが、冒頭で説明した120台ある記事クラスタDB、これはすべて4.0です。右の年表を見るとわかりますが、相当な古さですね。これもライブドアブログのローンチと同じ時期。当時の最新版です。

「4.0、実際の使用感どうなの?」と思うじゃないですか。なので、ちょっと例を挙げていこうと思います。

インデックスやカラムの追加などテーブル構造の変更をするときALTER TABLEを使いますよね。これにはロックをかけずにオンラインで実行する方法はたくさんあって、Online DDL、Fast Index Creationなど、これができなくても、トリガーを使ってオンラインでスキーマ変更を行うようなツールが数多く存在します。

これがMySQL 4.0しか存在しない世界だとどうなるかというと、こうです。

4.0ではすべての機能が実装前なので、実質ALTER TABLE不可能なんです。最低条件のトリガーでも使えればよかったんですが、これは完全に詰んでます。

ただ、諦めないでください。手段はあります。MySQL 4.0でオンラインのままテーブルを変更したい場合どうするか。簡単な例として、TABLE Aに変更を加えることを考えてみます。

まずステップ1、対象のTABLE Aと同じ構造のTABLE Bを作成します。

次に、TABLE Bに対してALTER TABLEをかけて、テーブル構造を変更します。ステップ3、次、アプリケーションに手を加えて、両方のテーブルにdouble writeを行うようにします。ステップ4、さらにバッチ処理でTABLE Bに足りないレコードをコピーして、データが同期されるのを待ちます。

データの同期が終わったら、TABLE Aの書き込みを止めれば作業完了というわけです。

テーブル数やレコードの性質にもよりますが、計画から作業完了までどのぐらいかかるかというと、数ヶ月かかります。普通ならコマンド一発で終わる作業ですがこれだけ膨大な工数をかけないといけない。これは心が折れますね。

ちなみに、最初のステップ、同じ構造のテーブルを作成するところですが、今ならCREATE TABLE LIKE文で一発なんですよね。

しかし、これもまだ実装前でした。こういった地味な嫌がらせが続きます。

でも、これで目的は達成されましたね。「ああ、よかったー」と思うでしょ? それがテーブルを複製しているのでデータはもちろん倍になります。

当たり前のようにデータ肥大化、ディスクの圧迫が始まり、アラートが鳴り出します。

「あれ、でも古いテーブルを消せば解決じゃね?」と思いますよね。それは正しい判断です。しかし、見てください。

悲しいことに、innodb_file_per_tableも実装前なんです。

どういう事かというと、テーブル単位にデータファイルを分割できないという意味なので、不要なテーブルを削除したとしても、一度肥大化したファイルは小さくなりません。つまり、ディスクは圧迫しっぱなし、アラートも鳴りっぱなしになるということです。こうなると、MySQLサーバ自体を一度作り直すしかありません。これはつらいですね。

さらに言うと、データの圧縮オプションもまだ実装前なので、データの増加自体を抑えることも難しくなります。

とまあ、ここまでの事例も氷山の一角で、まだまだMySQL 4.0で苦しむことが可能なんですがこれ以上は誰も得しないので、このあたりで終わりにします。

MySQL4.0移転大作戦

そしてもちろん、こんな状況なので、当然思うわけですよ。「なぜ我々はこんな壮大な縛りプレイをしているのか?」「さすがにバージョン上げなきゃまずいよね」と。その時、ちょうどサーバ移転プロジェクトが立ち上がったのでバージョンアップの検討に入ります。

理想としてはこんな感じに、サーバ移転と同時にMySQLのバージョンアップもしたい。これは当然ですね。しかし、ブログの特殊な事情と時間的制約があったので、バージョンアップ計画は断念しました。

「仕方ない。それなら4.0のまま移転すればいいよね」という話になります。これは一見すると楽勝っぽいんですが、ここで新たな問題が発覚します。

LINEではデータベースは基本的に共通のDB基盤の上で管理しているんですが、MySQL 4.0について調べた結果、社内のDB基盤でホスティング可能なバージョンではないことが発覚しました。つまり、通常のDBサーバと同じ方法で移転することができないということです。今どき4.0を使っているサービスなんて想定していないので仕方ないですが。

でも、ここで諦めることはできません。我々は考えました。「MySQL 4.0をDB基盤に載せることができないのであれば、これはもうDBサーバではない。アプリケーションサーバとして移転すれば問題ないんじゃね?」ということで、アプリケーションサーバにMySQL 4.0を独自でセットアップして独自に管理することで、無事MySQL 4.0のサーバ移転を完了することができました。

いや、これは本当に長かったですね。

DB内部のキャラクタセットの混在が生んだ闇

これで一安心ではありますが、先ほどお話ししなかったブログの特殊な事情という部分、そこにも闇があるので説明したいと思います。

これです。

ライブドアブログの中でもとりわけ攻めた実装の1つ、DB内部のキャラクタセットの混在が大きく関わっています。

2003年のリリース当初、ブログのキャラクタセットはEUC-JPだけでした。その後、2008年頃にUTF-8のサポートも開始しました。その結果、この図のように1つのテーブルの中にEUCとUTF、別のキャラクタセットを持つレコードが混在する状況を作り出しています。

これが原因で、正攻法でのバージョンアップができない状況に陥りました。

正攻法というのは、スライドのように1つ上のバージョンにレプリケーションを張りながらどんどんMySQLをバージョンアップしていくという手法ですが、最初のステップ、4.0から次に移すところで文字化けしてどうしようもなくなってしまったので、いったん保留となりました。

「でも、移転完了したししばらくは問題ないだろう」。自分もそう思っていたんですよ、つい最近まで。でも、そんなに甘くなかった。どういうことかというと、実はもう新しめのMySQL clientからMySQL4.0のサーバに接続できないんです。

正確にはMySQL client 5.75以降ですが、こうなると後がありません。つまり、もう次のプロジェクトは始まっているということです。

ということで、ライブドアブログのロードマップを見てみたいと思います。

これが現在のロードマップです。上から、進行中のサーバ移転・HTTPS対応は来年前半に完了予定です。mod_perlや古いPerl関連は、バージョン混在問題とあわせて同時期に完了予定。キャラクタセットが混在している問題もUTF-8化計画というものがあります。あと、MySQLのアップデートもそのあとに続いて、すべて終わるのが2021年前半という感じです。

LINE BLOG誕生秘話、実はライブドアブログの…

さて、ここまで「ライブドアブログ」について話してきましたが、ここからはもう1つのブログサービス「LINE BLOG」について話していこうと思います。

LINE BLOGは名前のとおり、LINEのファミリーサービスと呼ばれるものの1つです。ライブドアブログとの違いは、LINEアカウントがあれば誰でも使えるなど、LINEとの連携が強いところです。冒頭でも紹介しましたが、2014年ローンチの比較的新しいサービスです。

ではさっそく、リリースから現在までの歴史を振り返ってみたいと思います。

サービス開始は2014年11月。最初は芸能人など一部の特別なユーザー限定のブランドとしてリリースされました。そして、そのちょうど2年後、2016年の11月にリニューアルを行いました。ここではじめて一般公開となり、LINEアカウントを持っているユーザーであれば誰でも使えるサービスになりました。このとき同時に専用アプリもリリースされて、現在のかたちになっています。

というのは表向きの話です。では、これを裏側から見てみるとどうなるか?

裏側というかシステム側ですが、まず2014年11月リリース時点、LINE BLOGはライブドアブログのASP機能を使って立ち上げられました。

ASP機能とは何かというと、ライブドアブログのシステム上に別ブランドのブログを立ち上げることができる機能です。なので、この時点ではシステム的には完全にライブドアブログです。

その約1年半後、2016年4月にリニューアル開発がスタートして、ライブドアブログからの切り離し作業が開始されます。

そして、さらに半年後の2016年11月にリニューアルオープンが完了。ここではじめてシステム的に独立したブログサービスになりました。

もともとライブドアブログだったものを分離する作業。これ、どうやったかわかりますか? さまざまな検討を行った結果、Javaでフルスクラッチから書き直しました……と言いたいところなんですが、ライブドアブログをフォークしました。

(会場笑)

本当はやりたくなかったんですが、事情があったので仕方ない。

ライブドアブログが生んだカオスとレガシーからの脱却

でも、ちょっと待って。ライブドアブログをフォークしたってことは、つまり、察しのいい方はわかると思ういますが、こうなります。

元がカオスとレガシーの塊、ライブドアブログなので、こうなっちゃうんですよ。

でも、みなさんなにか忘れていませんか? 今日は何の日か。今日はLINEのDEV DAYなんですよ。LINEのエンジニアが本気を出すとどうなるか? こうなります。

何万行というコードを書き換えてこれらカオスとレガシーをすべて排除。今まで紹介してきた数々の問題を解決し、カオスとレガシーからの脱却を果たしました。

MySQLは5.6にアップデート。古いPerlやmod_perlはもちろん廃止。キャラセットもUTF-8に統一して、Apacheもnginxに置き換え、CI環境も整備してテストも書きやすい構成にしたことでカバレッジもかなり改善しています。さらに複雑に入り組んでいたサブシステムもほぼ全廃して、LINEの共通基盤に置き換えてあります。

もちろんこの過程ですべて新しいインフラになっているのでサーバ移転も完了。ついでにHTTPSも対応してあるので、ライブドアブログにある問題はすべて解決しています。

まだPerlのバージョンが古いという突っ込みどころはありますが、これもそのうち入れ換えようと思います。これはライブドアブログの目指す理想にだいぶ近い状態です。

そして、このLINE BLOGリニューアル開発で蓄積されたノウハウが、現在ライブドアブログの各種プロジェクトに活かされています。

時系列でいうと、LINE BLOGリニューアルが2017年以前なので、ちょうどLINE BLOGリニューアルが終わったタイミングからサーバ移転やHTTPS対応が始まったことで、それなりに情報が揃った状態からスタートできたのは大きかったと思います。これらはキャラクタセットの統一やMySQLのアップデート、この先のロードマップにあるものについても活かされていく予定です。

このように、LINE BLOGとライブドアブログはシステム分離後でも密接な関わりを持って開発されているサービスとなっています。

微粒子レベルの改善でも、放置するよりは何万倍もマシ

さて、ここまででブログに関する話題は終了です。最後に、このプレゼンテーションで伝えたかったことは、ブログがどうという話でも、技術がどうという話でもありません。

みなさん考えてみてください。自分が今担当しているサービスの10年後、15年後。そのとき関わっているメンバーがどんな思いで開発や運用をしているか。それらのメンバーが自分の作ったシステム・自分の関わったシステムで苦しんでほしいとは思ってないはずです。

現在最先端の技術を使っていても、そのまま時間が過ぎれば必ずレガシーになります。負債を残さないのは難しいと思いますが、できるだけ負債を小さくすることはできます。

コードを書いたりレビューをするとき、数年後どうなるかを想像しながら行ってみてください。なにかしら手を入れるときは、自分が触る前より少しでも良くなるように意識してください。たとえそれが微粒子レベルの改善であっても、放置するよりは何万倍もマシです。

まず小さなことから始めるのがおすすめです。例えばリファクタリングが大変なら、不要なファイルやコードを見つけたらすぐ削除していくとか、ドキュメントを書くのが面倒だったらソースコードにコメントを1行入れるだけでも大丈夫です。

バージョンアップはできなくても、定期的に棚卸ししてメンバーに共有するだけでも確実に意識は変わっていきます。また、古い機能についても、雑談レベルでいいので、議論してみると何かしら変えられるはずです。

目を瞑ると必ず風化します。風化させないことが大切です。

エンジニアはもちろん、ディレクターやプランナーなどサービス開発に関わる方なら、今すぐにでもできることはあるはずです。みなさん、なにか1つでもいいので行動してみてください。

未来のために一緒に戦いましょう。カオスとレガシーへの挑戦はすでに始まっています。

(会場拍手)