世界を動かす技術を、日本語で。

なぜ「BEAM Book」を書いたのか

概要

The BEAM Book の執筆背景、出版までの試行錯誤、そして BEAM VM に関する知見をまとめた経緯を解説。 大規模Erlang/Elixirシステム運用者向けの 実践的な内容。 公開リポジトリによる コミュニティの力 と継続のモチベーション。 執筆を通して得た 教訓 と「完成」の定義。 書籍の入手方法や 貢献の呼びかけ も案内。

ポストモーテム、コーヒー、そして10年の粘り強い好奇心

  • Klarna の基幹システムを10年間支えた経験に基づく執筆動機

    • BEAM での15ミリ秒の停止が、数百万件の決済遅延やCEOからの深夜コールを招く現実
    • 次世代エンジニアが素早く問題解決できるようにとの思い
  • 執筆開始の経緯

    • 2012年10月12日、DocBookファイルでプロジェクト開始
    • 2週間後も構造や見出しの調整が中心、実質的な内容はごくわずか
    • 11月にはAsciiDocへ移行、自作ビルドスクリプト導入、「半年で完成」と楽観
  • 出版までの紆余曲折

    • 2013年、O’Reilly出版へ話が進むも、Atlasシステムの不具合で進捗停滞
      • ファイル消失や上書き、Git履歴がフラストレーションの記録に
      • 2015年3月、「章を強引にセクション化」してビルド維持
      • 2ヶ月後に静かに契約終了、安堵と恥ずかしさが混在
    • Pragmatic Bookshelfへ移籍も進捗は鈍化、最終的にこちらもキャンセル
    • 2017年1月、新リポジトリへ大規模コミットし再出発も停滞
    • 2017年3月、AsciidoctorとGitHubで再スタート、必要部分のみコピペ
      • 4月7日、Chalmersでの講義直前にリポジトリを公開
      • 24時間以内に外部から修正・図追加・CC BY-4.0ライセンス導入

続けられた理由

  • BEAMの本質的理解 へのこだわり
    • 表面的な説明ではなく、実際のロジックを追求
  • コミュニティのフィードバック
    • 公開直後から修正・例・改良案が届く
    • GitHubのスター数や「Issue #113 – ‘Please continue being awesome.’」など、モチベーション維持
    • Erlang/BEAMカンファレンスでの引用や、Twitterでの言及も励みに
  • 自分自身が信頼できるリファレンス作成 への思い
    • 問題発生時に役立つVMの詳細解説書を目指す

書籍の内容と対象読者

  • 大規模Erlangシステム運用で必要だった知識 を体系化
    • スケジューラとプロセス管理 :BEAMのプロセス調停・優先順位付け・バランス
    • プロセスとメモリ :ヒープ・スタック・メッセージ・バイナリ管理
    • ガーベジコレクションとメモリ :プロセス単位・全体のGC、バイナリ参照、メモリリーク
    • タグ付けスキームとデータ表現 :整数・浮動小数・タプル・バイナリ・参照の内部表現
    • コンパイラとVM :命令生成、コンパイラの役割、エミュレータの実行方式
    • トレースとデバッグ :dbg、erlang:trace等による実践的な追跡・ボトルネック特定
    • パフォーマンスチューニング :プロファイリング、リダクション理解、レイテンシ分析
    • システムアーキテクチャ :ERTS・BEAM VM・各サブシステムの連携
  • Erlang/Elixirの運用・開発者、特に大規模運用・高負荷対応者向け
    • 散在するドキュメントやメーリングリストを探し回る手間の削減

執筆を通じて得た教訓

  • 粘り強さは完璧主義に勝る
    • 出版契約の2度の破棄より、未完のアイデアの方が問題
  • 境界設定の重要性
    • 執筆時間の確保、通知オフ、集中力の確保
    • 14:30のFika(コーヒーブレイク)は譲れない
  • 公開によるコミュニティの力
    • 修正・励まし・モチベーション維持のきっかけ
  • スコープ管理
    • Dirtyスケジューラ、新JIT、デバッガ詳細はコアから外し、必要なら付録へ
  • まずリリースし、継続的に改善
    • BEAMは毎年進化、Gitリポジトリでの継続的なアップデートが最適
    • 実際の締切(Code Beam Stockholmへの印刷)で本当に必要な内容を見極め

完成の定義

  • 印刷版を手にした瞬間に「完成」と実感
    • 断片的なコミットが「形」となり、一区切り

参加・貢献方法

  • The BEAM Book 1.0 はAmazonでペーパーバック版が入手可能
    • 購入リンク: Amazon
  • GitHubリポジトリ でのスター、フォーク、Issue投稿、プルリク歓迎
    • 貢献者は謝辞に記載
    • GitHub: theBeamBook
  • 書籍を読んだら 正直なレビュー を投稿
    • アルゴリズムは実際のフィードバックを重視
  • BEAM内部ワークショップ も実施可能
    • 実運用システム向けにカスタマイズ
    • 連絡先: happi@happihacking.com
    • Happi

Hackerたちの意見

俺もKlarnaみたいな規模のものに関わったことはないけど、15msってポストモーテムに値するイベントを引き起こすにはめっちゃ短い時間に思えるな!

その言及された事件についても気になるんだけど、ポストモーテムのリンク誰か持ってない?ネットで探しても見つからなかった。

確かに小さいように見えるけど、BEAMはマイクロ秒(μs)単位の応答時間が多いからね。それに慣れてると、何かがミリ秒に「吹き出す」とアラームが鳴るのもわかる気がする。

これ、BEAMシステムでは簡単に起こりうるよ。共有状態にアクセスしたいとするじゃん?それを守るためにgen_serverを作るんだ。gen_serverは基本的に巨大なミューテックスみたいなもん。gen_serverは普通のBEAMプロセスで、メッセージキューに送られたリクエストを処理して、返信メッセージを返す。例えば、通常20μsでリクエストを処理できるとする。そうすると、15msの遅延で750件のメッセージがメッセージキューに溜まることになる。これだけじゃ大規模な障害を引き起こすには足りないかもしれないけど、処理の過程でメッセージキューを安全じゃない方法で使ってると、問題が起こるかも。メッセージをチェックするとき、BEAMはメッセージキュー全体を検索するからね。BEAMが最適化できるパターンもあるけど(ほとんどのパターンは安全じゃないと思うし、BEAMはgen rpcスタイルのメッセージパターンだけを最適化してる)、安全じゃないパターンを使ってメッセージキューが溜まってると、システムのスループットが壊滅的になる。メッセージ処理にかかる時間はメッセージキューの長さに依存するから、メッセージ処理にかかる時間がメッセージキューの長さに影響する。しかも、gen_serverのコードに明示的なreceive文がない場合もある。ライブラリを使ってるだけで、どこかで大きなメッセージキューに対して安全じゃないreceiveを使ってると、痛い目に遭うことも。BEAMは代替のメッセージキューも追加したから、プロセスのメインメッセージキューの代わりに使えるはずだけど、まだ多くのライブラリはこれを使ってないと思う。この代替は「エイリアス」(https://www.erlang.org/doc/system/ref_man_processes.html#pro...)で、思ってたのとは少し違って、「失われた」メッセージからキューを守るためのもの。エイリアスがないと、「タイムアウト」が原因でプロセスメッセージキューが待たれていないメッセージで汚染されることがある。これが大きなメッセージキューによるスループットの低下につながることも。ただ、通常、長生きするプロセスはキュー内のメッセージを処理するループを持ってる。

BEAMみたいなVMって他にあるの?正直あんまり詳しくないけど、BEAMがすごすぎて他に必要ないのか、それとも同じクオリティのBEAMみたいなランタイムを作るのが大変すぎるからなのか、気になってる。

本当に制約のあるデバイス向けには、AtomVMっていう別の実装があるよ。他のエコシステムでBEAMやOTPみたいなものを実装しようとしたけど、無駄になった努力がたくさんあるんだ。たいていはVMじゃないけどね。

BEAMが1990年代後半に発明された頃、2000年代初頭にはかなりユニークな提案だったんだ。今では、BEAMが特有にやってることはほとんどないよ。それが他にない理由かもね。市販のコンパイル言語は、今のBEAMと同じ問題を解決できるし、他の利点もあることが多い。Erlangコミュニティには、BEAMと同じ方法で解決できないなら、必然的にBEAMより劣るって考える人がいるけど、それは間違いだよ。「違う方法でも同じ問題を解決できるか?」って聞けば、2025年には選択肢がたくさんあるけど、2000年の選択肢はずっと弱かったからね。確かに、BEAM互換性を持つのは見た目以上に難しいよ。https://github.com/ergo-services/ergoみたいなプロジェクトができるし、他の言語でもあると思う。ただ、個人的にはかなりニッチなニーズだと思う。既存のBEAMインフラに接続する必要がなければ、グリーンフィールドプロジェクトにはあまり良い解決策とは思わない。もっと現代的なツールや、選んだ開発環境によりネイティブなソリューションの方がいいよ。

現実的には、現代のKubernetesインフラはBEAMに似てるよ。少なくとも提供する機能はね。今の時代、高度にスケーラブルで自己修復するシステムをデプロイする一般的な方法だよ。それに、k8sを使えば特定の言語に縛られないし(Erlang/Elixir以外にもいくつかあるけど、人気はないね)、限られた開発者リソースや興味に悩まされることもないんだ。

一番広く使われてるのは多分Goだと思う。BEAMは「Erlangライクな言語」に合わせて作られてるし(逆かもしれないけど)。Elixirを書くと、動作の基本的な意味論のおかげでErlangにすごく似てる感じがする。Gleamも型を超えればErlangに近いしね。Goもgoroutinesやグリーンスレッド、Erlangみたいなプロセスを並列処理の基本的な要素にしてるけど、OTPが持つ同時実行アプリケーションの構造に関する「意見」は持ってないんだよね。

「Erlang Runtime Systemという用語を、特定の実装であるEricssonのErlang RunTime System(通常はERTSと呼ばれる)とは別に、一般的なErlang Runtime Systemのアイデアを指すために使うようにします。」いいね、これ。

それは…バカじゃない?

すぐに買ったよ。オンラインで無料で手に入るとしても、こうやって作者を少しでもサポートできるしね。

「BEAMをちゃんと理解したかったから続けた。表面的な説明だけじゃなく、本当のロジックを追うことには価値がある。」これ、めっちゃ共感する。そういうモチベーションが素晴らしい成果を生むんだよね。それだけの理由で買った。キャリアの中で出版社から何度かアプローチされたことがあるけど、毎回似たような流れだった。アイデアがあって、俺もアイデアがあって、共通の合意を見つけようとしたけど、結局合意点が見つからなくて契約が流れちゃった。例えば、14歳向けのJava本を書きたくなかったし、向こうもクラスローダー(その時に深く掘り下げてたニッチなテーマ)について書いてほしくなかった。人々がどうやって自分の情熱と読者の求めるものの交差点を見つけるのか、知りたいな。

出版社に依存する必要があるの?独立して本を書けないの?それとも出版社の「ブランド」やその他の特典があるから?

3冊の本を書いた経験から言うと、自己出版するか、出版社が求める本を書くかのどちらかだね。特定のタイプの本を専門にしている出版社を選ぶことも大事だよ。ある出版社は「Pythonで21分でAIを学ぶ」みたいな本を求めてるし、他の出版社は「Javaクラスローダーの深い暗い秘密」を求めてる。O'Reillyはニッチな技術系の本には最高だよ。業界のほとんどは初心者向けの本を求めてるから、そっちの方がボリュームがあるんだ。幸い、自己出版は今まで以上に簡単になってるし、いろんなサイトでオンラインでコピーを売るのも簡単だから、必ずしも無料で配る必要はないよ。でも、魔法の公式はないからね。本当にニッチなものを書きたいなら、出版社が興味を持つとは期待しない方がいいよ。自己出版して、自分で宣伝する覚悟が必要だね。

ちょっと自己宣伝になるけど、これがきっかけでクライミングのための筋力トレーニングに関する本を書いたんだ。いろんな穴に飛び込んでいった結果だよ。自己出版する準備はしてたけど、興味を持ってくれる出版社が見つかったんだ。読みやすくするためにいくつか変更しなきゃいけなかったけど、自分で出版社にアプローチしてみるのもいいかもしれないよ。

面白いことを言えれば、みんな理解する方法を見つけると思うよ。キャリアの初めに、ドン・ボックスの「Essential .Net」に出会ったことを覚えてるけど、彼は特にターゲットにしてるオーディエンスがいたわけじゃないと思う。彼はCommon Language Runtime (CLR) の裏側をそのまま見せてくれたんだ。実際に「essential .net」を理解するのには何度も読み返さなきゃいけなかったよ。

こちらがgitリポジトリのリンクだよ - https://github.com/happi/theBeamBook

数年間、遠くからErlangを見てきたよ。いつか実際に使えることを願ってる。

Elixirはかなり素晴らしい代替手段だよ。

Erlangは、他の言語でもより良いプログラマーにしてくれる言語の一つだよ。

BEAMってオープンソースの中で一番過小評価されてる技術かも。例えば、WhatsApp。なんでElixirとErlangが高い同時実行性プロジェクトであんまり人気ないのか、謎だわ。

みんな一番いい人材を雇おうとしてるけど、結局は一番低いレベルに合わせちゃうんだよね。「でも、数週間で新しい言語を学べないエンジニアを雇ったらどうするの?」みたいな感じで、ずっとその繰り返し。

これは純粋にマーケティングの問題だと思う。他の言語(Java、C#、Go)は大企業のバックアップがあって、成功させるために利害関係があるからね。Erlangの企業オーナーは、最初からそれを潰そうとしてたし、それ以降も技術リソース以外にはあまり関心を示してこなかった。Elixirみたいなものが出てくるまでは、あんまりマーケティング的な素材は見られなかったし、あれもRubyモデルに近いから、開発者向けなんだよね。2014年にElixirが登場した世界は、2004年にRailsが出た時とは全然違うし。開発者はBEAM言語の良さを納得させられることが多いけど、華やかさがないとMBAの人たちを納得させるのは難しいよ。

投資のギャップって感じかな。RustやGo、Pythonなんかは、静的解析や型チェック、開発者の使いやすさにたくさん投資してくれる大きな支援者がいるけど、Erlangのエコシステムは必ずしも同じような愛情を受けてるわけじゃないんだ。主要なユーザーたちは、だいたいBEAMの外で何かを作ったり、方向転換したりしてるね。

Erlang/OTPでBEAMを使うことを学ぶのは、去年の中で最高の経験の一つだった。Joe Armstrongの「Programming Erlang: Software for a Concurrent World」って本を使ったんだけど、初心者にも超おすすめ!「Designing for Scalability with Erlang/OTP」も良いって聞いたけど、まだ手をつけてない。でも、深さに関してはこの本に勝るものはないね。BEAMはまるで高度な文明から残された異星の技術みたいで、この本が出たタイミングも最高だった!すぐに買ったし、二回のキャンセルの後も続けてくれたDr. Erik Stenmanには感謝だね。

あ、これBEAMのことじゃなくて、https://smfr.org/robots/のことかと思った、ハハ。