積読を消化しようというテーマの、読書感想文連載 の2冊目です。
導入
『自分たちは、クラウドネイティブじゃなくてマネージドネイティブなんだよ…』
TIGの原木です。
最近、冒頭のような開発者の嘆きを人づてに聞く機会があり、今も脳裏に残り続けています。
昨今のITシステムにおいて、クラウドサービスは欠かせないものとなっています。しかしユーザー、そして開発者として大きな利便性を享受する裏で、クラウドサービスによって巧妙に隠蔽された裏のソフトウェアを意識する機会は減り続けているのではないでしょうか?
Webサービスにおいて、Redisやmemcachedに代表されるキャッシュサーバーもそのようなソフトウェアの1つです。
キャッシュサーバーは、Webアプリケーションなどデータの読み込みや保存を効率化するために欠かせない存在ですが、同じデータストアであるRDBMSなどと比較していま一歩隠れた存在だと思います。
RDBMSならDBAやテーブル設計のスペシャリストが割り当てられるようなことがあっても、キャッシュサーバーなら他の専門職が兼任することは少なくありません。
「実践Redis入門」は、そのような現状に対する問題提起のきっかけとなりました。
実践Redis入門とは?
「実践Redis入門」は、2023年現在AWSのAmazon EMR開発チーム、システム開発エンジニアとして働いている林 昌吾さんという方が書かれた『Redisの基礎から、実践、運用や調査に役立つ仕様などの詳細について解説した入門書です。』
入門書とありますが、単なる機能紹介にとどまらず、筆者が実際にRedisを運用して培った知見が450ページにわたってこれでもかと詰め込まれており、Redisを扱う上で末長くお付き合いするであろう本だと思います。
本書は下記の通り三部構成になっています。
- 基本
- 第1章~第4章
- Redisの概要、基本的なデータ型やコマンド、アプリケーションの構築事例について説明しています
- 実践・運用
- 第5章~第10章
- Redisの運用で必要となるパフォーマンスチューニングや耐障害対応、Redisを支えるメモリー管理制御、Amazon ElastiCache for Redisについて説明しています
- 発展
- 第11章
- Redisの開発という側面から、運用時に必要な知見について説明しています
このブログでは、「実践Redis入門」を自分の愛読書に絡めてご紹介したいと思います。
本書の中身や構成を正確に知りたい方は、技術評論社の 書籍案内をご覧ください。
「E.G.コンバット」に学ぶ
「実践Redis入門」って「E.G.コンバット」に出てきそうだな…というのが初見の印象でした。
「E.G.コンバット」を知らない方に説明すると、原著は秋山瑞人という方が25年前に執筆、電撃文庫より出版されたSF小説です。あらすじに軽く触れると、戦場から左遷された歴戦の英雄が月の訓練校教官として劣等生ばかりの訓練生を任されて、七転八倒するという話になります。1
なぜ、そんな小説と本書を結び付けたかというと、背景にはクラウドサービスが当たり前のように存在し、AIが開発現場で使われるようになった昨今の状況が小説の舞台とよく似ていたからです。
- 現在: クラウドサービスが浸透したことでインフラエンジニアの仕事は、従来の調達、構築、設定といった定型的な業務から非機能要件のチェックや運用費の見積もりという、より正解のない業務へ変わりつつあります。
- 小説: 自分の役割や生き残るための方法という正解のない問いが数多く出てきます。
- 現在: ChatGPT、Prometheusが組み込まれたBingやGitHub Copilotが、プロンプトやコメントに従ってプログラムを自動生成するのを見て、コーディングいらねーじゃん…と自虐的なぼやきを聞くようになりました。
- 小説: 流体脊髄と呼ばれる支援AI3が当たり前になった世界で同様の疑問が出てきます。
現状の変化は少なからず、自分たちITエンジニアのマインドにも影響を与えています。そんな中で、小説の中で描写されたメッセージが「実践Redis入門」に、そして25年後の現代2にも強く通じると思います。
それはいったいどんなメッセージでしょうか?
まずは「E.G.コンバット」からトピックを取り上げたいと思います。
「E.G.コンバット」の見どころ: その1
「E.G.コンバット」の第1巻では、教官は訓練生らに対して、双脚砲台と呼ばれる自立型兵器を支援AIのアシスト無しで、手動で起動するように求められる姿が描かれます。
当初やり方も知らなかった彼女らが最初からうまくいくはずがありません。当然のように失敗を繰り返し、トライアンドエラーを積み重ねます。延々と繰り返される訓練はやがて苛立ちとなり、教官に不満が爆発しました。
「こっちが聞きたいね! 何のためのシミュレーションだよ? 流体脊髄凍結させて訓練してるのなんてうちらだけだぞ! GARP(注: 支援AIの愛称)の支援を受けないことに何の意味があるんだよ!?」
教官は冷静に受け止めました。
「では聞く」ルノアは一度、全員の顔を見渡してから、静かに口を開いた。
「それではなぜ、最初から最後までGARPにやらせなかった? 少なくとも今の段階では、GARPはお前ら全員を合わせたよりもずっとましな操機をする。GARPに全部任せてしまえば、フラグを五つも取りこぼさずにすんだはずだし、味方を三度も誤射せずにすんだはずだ」
全員が言葉に詰まった。しかし、現実には──ルノアのとどめは冷酷だった。
「なぜ、お前らはここにいる?」
この場面、辛辣な言葉ではありますが、教官も疑問に答えて直接回答をしているわけではありません。
訓練生が聞きたいのは、どうすれば双脚砲台を手動で起動できるのか、手順や機能の抽象的な説明ではなく、それらの機能の知識がどのような開発/運用状況で生きるのかという訓練目的です。
教官は教官で、戦場上がり故に『実戦で(目的を)説明されなければできないようではだめだ』とコミュニケーションに不足している節があり、両者の不幸なすれ違いは今しばらく続くことになります。
そもそも、高度にシステムが自動化された世界で、あえて手動による兵器運用という訓練をなぜ教官は行っているのでしょうか…?
その真意について解き明かす前に「実践Redis入門」の推しポイントについて説明したいと思います。
「実践Redis入門」の良いところ: 機能説明と開発/運用の関連
往々にして、一般的な入門書にもこの教官のように真意に直接答えないわかりづらさがあります。
一見、具体的でいて抽象的な機能説明が続き、その目的について迷子になることも珍しくありません。
しかし、「実践Redis入門」は機能説明を詳細に行いつつも
- Redisを利用してWebアプリケーションを構築したい開発者
- Redisを使ったシステムを安定的に稼働したい運用者
というどちらの対象者の目的も違えぬ素晴らしい本でした。
たとえば、「実践Redis入門」第6章「トラブルシューティング」では、章題の通り、Redisで問題が発生した時にどのように問題を切り分ければよいか、解消のヒントがどのようなメトリクス情報に隠されているかを解説した、筆者肝いりの内容となっています。
パフォーマンスチューニングが、開発者、運用者と立場を問わず重要なことは言うまでもありません。
しかし、開発者目線で実際に INFO
コマンドの内容を見てくださいと言われたら、13個のセクションにわたって出力された内容は辛うじて Memory
は追えるものの、どれを見ればボトルネックが解決できるのか、宇宙猫となること間違いないでしょう。
INFOコマンドによるメモリー使用量の内訳の様子 |
これって、日常的にキャッシュサーバーの運用をしている方にはどう見えているのでしょうか...
本書を読めば、そのうちどの辺を最低限抑えればいいのかという指標について解説されているのでスコープを決めることができます。「6.2. レイテンシーの調査」「6.3. メモリー問題」で必要とする別のコマンド ( SLOWLOG
や MEMORY STATS
等)と合わせて苦しみながら頭に入ってきます。
個人的にはメモリのフラグメンテーションに関して、放置するとパフォーマンス低下~ページング~メモリ不足に至るガンみたいなやつだと雑な理解にとどまっていたのですが、メトリクスの見方やスペシャリストの肌感覚が掲載されており、勉強になりました。
(カンファレンスなど機会があったら、この辺AWSのGameDayっぽく実演されている姿も正直拝見したいです)
このように煩雑になりがちな「機能の説明」も、「開発/運用でどのように生かされるのか?」というプロセスを踏むことで筆者の実戦経験をもとに関連付けて覚えられるので、Redisの運用の素人である私にも理解が進みました。
個人的に印象に残ったのは、第5章「Redisの運用管理」のコラムであるRDBファイルのフォーマットに関する話です。
RDBファイルとは、Redisがメモリー上に蓄えたデータをスナップショットとして永続ストレージに出力するときに使うファイルの形式です。本書ではスナップショットを取得するときの手順はもちろんのこと、RDBファイルのバイナリー形式のフォーマットの仕様についても踏み込んで解説されています。
「運用者がダンプファイルのデータ形式なんて知る必要あるのか?」と思われた方がいるかもしれません。ですが、その理由について、本書では次の通り順序だててフォローされています。
- RDBファイルのAUXフィールドと言われる領域に
redis-ver
というバージョンに関するメタ情報が埋め込まれていること - RDBのバージョンはRedisのバージョンに連動すること
- RDBのバージョン互換性を吸収する機能があるので、マスタとレプリカのエンジンのバージョン差異を気にせずに、同じバージョンのRDBをレプリケーションできること
- 古いバージョンのRedis(3.2.1以前)だとRDBのバージョン互換性がないので、上記機能は使えないこと
- 古いバージョンのまま放置し続けてしまったキャッシュノードに対してレプリケーションできるかというときにこのバージョン情報が判断材料になること
- 逆にそれより新しいバージョンのRedisであれば、現行バージョンのレプリケーションを組んでおくことで、 Redisのバージョンアップ時にダウンタイムを小さくできること
ソフトウェアのバージョンアップという運用負荷が特に高い作業において、RDBのバイナリから読み取ったバージョン情報を頭にいれておくことで、結果として手続きが楽になるんですね。
rdbファイルの中身 |
さて、また「E.G.コンバット」の話に戻りたいと思います。
「E.G.コンバット」の見どころ: その2
1巻目でなんやかんやとあったあとも、教官と訓練生らの日常は変わりません。いつまでもチームはへっぽこのまま。教官の多忙な一日は終わるところを知りません。
その状況を見かねて、別のチームの訓練生が教官に対して自分のチームの先生になってほしいと直談判します。
自分たちのほうが優秀だという自尊心から、お願いはいつの間にかヒートアップし、訓練生は抑えが効かなくなります。
『あんな連中、だれが指導してもどうせ…』
昂った感情のまま、思わず口走った言葉は教官の逆鱗に触れました。
教官は返す刀で訓練生に質問します。
双脚砲台が攻撃を受けてAIが瞬断した。システム制御の支援を受けられない状況下でどのように機体のリカバリーを行えば良いか?5
口ごもりながら必死に手順を考える訓練生。そこへ、さらに浴びせられた教官の「攻撃」に、訓練生は「戦死」したことを自覚しました。
教官が想定した状況はすべて、へっぽこチームが毎日訓練で行っていた内容でした。
どうしてその訓練を行っていたのか、ここで真意が初めて明かされます。
今の地球の工業生産力って、百年前と比べたら百分の一がいいとこでしょ? 損傷箇所の部品の補給が受けられないことなんてしょっちゅうだったもの。そのくせ、兵器は強い分だけぐちゃぐちゃに電子化されててめちゃくちゃに複雑で、機能の半分でも理解してる奴が部隊にひとりもいないなんて当ったり前でさ。>
でも、それじゃだめなんだってわかった。
なぜトリガーを引けば弾が出るのか、姿勢制御系はどんな理屈で機を水平に保つのか、たったひとつの操作で双脚砲台が起動するとき、流体脊髄(注釈: AIのこと)は何をどうやって関節をアクティブにするのか。それがわかってないと、大丈夫じゃなかった百回目がきたとき、なにもできないもの。
さっきの「バイパス回路接続とその間の回避運動」っていうのもさ、確かに普通は流体脊髄がオペレートするプロセスだし、その方が手動でやるより何倍も早いし、だからオルドリンのカリキュラムは、「自動制御」のひと言で流しちゃうけどさ。
でも、もしそのメカニズムが正常に作動しなかったら、そのときがあなたの戦死するときかもしれないのよ。だからわたしは、あんなやり方であの五人を訓練してるの。
…(中略)…
だから、多分、わたしは連中が卒業するまでこのやり方を変えないと思う。なにも、実戦でも流体脊髄のアシストを受けるなって言ってるんじゃないけど、GARPの──流体脊髄のアシストを受けなくても実戦をこなせるくらい、双脚砲台について知り尽くしていないと、転んだときに誰も絆創膏を貼ってくれない地球では、生き残れないから。
99回素振りして問題なかったシステムが、100回目にトラブルを起こす。あるいは、傍目には問題なくても微細なトラブルを日常的に訴えていたシステムが、ある日突然障害を顕在化して大問題につながる。いわゆるハインリッヒの法則として知られているそれは、ITシステムの運用の場面でもよくあります。
この問題に対処するためには、もちろん普段から予防を手掛けるというのが大原則ではありますが、いざ起こったときに火消しに奔走するのは運用管理者であり、必要とされる背景知識は多岐にわたります。
どんな知識が必要か? その示唆が、このシーンだと自分は思います。
小説の中の話に戻りますが、何も制約がない戦場であれば、AIという補助システムを最大限に活用した方が当然活躍します。つまりオペレーターとしての技量に熟達して、AIにうまい指示出しを下した方が、人間が手動で操作するよりも何倍もうまく兵器を運用できるでしょう。
しかし、小説の中の世界は決してそううまくはいきません。兵器に対して十分なメンテナンスが行われないことなど日常茶飯事ですし、CRM(クルーリソースマネジメント)は軽視され、人員不足も深刻です。
その中で教え子たちが生き残るためには何が必要か?
教官がたどり着いた答え──それは、通常ならAIによってうまく隠されている領域について手動操作を敢えて行い、兵器そのものへの造詣を深めることでした。
クラウドやAIを利用するということは、決して中身を理解しなくていいということにはつながらない
現実世界ではこんなに極端ではありませんが、2025年の壁が警鐘を鳴らすようにITのプロフェッショナル人材は慢性的に不足しています。また、プロジェクトは流動的であり、いつも同じメンバー、同じプロセスで業務を行えるとは限りません。
クラウド全盛期の現在、マネージドサービスがあるがゆえにビジネスドメインへの理解があれば、構築だけならだいたいなんとかなってしまうし、動かせてしまいます。
しかし、運用というフェーズに移行した瞬間、何となくでなおざりにしていたところが性能のボトルネックとして牙をむき、魔法使いのようなスーパーエンジニアが召喚されることが稀によくあります。
今まで助けていただいた方は皆、要求に耐えうる深い知識を持ってました。
どうしてそんなことを知っていらっしゃるのか? お話を伺う中で知ったのは、それらの知識は、マネージドサービスの皮をはぎ取り、裏で動いているソフトウェアを構築し、動かしてみて得られた気づきをさらに積み重ねて得られたものだということでした。
「実践Redis入門」の解説を読む中で、筆者もまたその一人なのだと深く感じました。
「実践Redis入門」の良いところ: 実践に裏打ちされた濃厚な説明欄
Redisの運用者はまだしも、Redisを利用する立場にある開発者にとって、その中身は理解から遠いところだと思います。
しかし、「実践Redis入門」にしたがって、
- 第4章のアプリケーション実装例(PHP, Ruby, Pythonの例があります)で感じを掴んで、Webアプリケーションを実装し、
- 第5章のアーキテクチャパターンに従ってキャッシュ戦略を把握し、
- 第8章のRedisクラスターの導入方法にしたがってDocker上で動かせば、
なんも考えずにHash型で行ったキー設計4、あるいはなんも考えずにKEYSコマンドを利用してデータ参照を行った実装7が、回りまわってメトリクスとして火を噴くところまでなにが起きていたのか把握できるでしょう(自省)。
もちろん、その辺は既に通った道である開発者にも本書が通じるのは言うまでもありません。
自分が良いなと思ったのは、エフェメラルスクリプトのコマンドの説明です。6
Redisコマンドの中にはオプションとしてTTL──指定したキーの有効期間のこと。期限切れのセッション情報を追い出すために欠かせない存在です──を設定できないものがあり、別途キーに対して EXPIRE
を投げる必要があります。
しかし、要するにそれはRedisに2回コマンドを投げるため、無駄な帯域使用だったり、2つのコマンドがセットで確実に送信&実行されたかというアトミック性8が保証されません。
それを防ぐために、シェルスクリプトのヒアドキュメント風にキャッシュサーバー側に2回のコマンドを1つのスクリプトとして送り、実行する EVAL
や EVALSHA
があります。
…と、ここまでならちょっとでもTTLを意識したら目にすると思うし、公式ドキュメントもあるので迷いにくいところだと思います。
本書の深いなぁと思うのはここからで、
- コマンド実行時にスクリプトを随時送る
EVAL
とスクリプトを1回あらかじめプリロードすれば送らなくていいEVALSHA
のうち、EVALSHA
の方が適していると単純に考えがちだが、戦略として あえてEVAL
もありだというユースケースとその解説 - ロールバック機能は課題も多くまだ実装されていないため、 厳密なアトミック性は保証されていないこと。途中でスクリプトがエラーにより処理が終わるケースもありえるため、アプリ側でそれを念頭に避けるべく開発したほうがよい忠告
EVALSHA
のようにコマンドを腹持ちさせるなかで、それがRedisサーバーに何かしらの影響を与えているのでは…? という疑問への回答と改善した方がいいエッジケースSCRIPT FLUSH
コマンドによるスクリプトキャッシュの削除方法EVALSHA
コマンドは事前にSCRIPT LOAD
コマンドでロード処理を実行する必要があるが、それらのコマンド間で再起動が行われてないか(それによりスクリプトが飛んでないか)、チェックする方法
という風に、様々な角度で解説されています。
これだけのことが450ページの中の数ページに詰まってます。ぜひ直接、書籍を手に取って該当箇所をご一読ください。
まとめ
以上、「実践Redis入門」の所感でした。9
ところで、EGFマダー?
次は大村さんのスモールデータ解析と機械学習 を読んだ感想です。
- 1.「プラネリアム」という、人類と敵対する知的生命体に地球が侵略されている舞台設定があるのですが、第1巻ではそのプラネリアムはほとんど登場しません。マブラヴのUNLIMITED編でもBETAは空気ですがあれと同じです。 ↩
- 2.令和5年に突如秋山瑞人著「E.G.コンバット」が電子書籍化されました。瑞っ子(秋山瑞人氏の熱烈なフォロワーの自称)は久々に見つかったオアシスに狂喜乱舞し、Amazonのジャンル別ベストセラー一位を獲得するに至りました。 ↩
- 3.正確には流体脊髄と呼ばれる 生き物 です。"彼ら流体脊髄ユニットを「コンピュータ」と呼ぶことは差別表現にあたるという。差別かどうかはともかくとしても、人間の脳がコンピュータでないとするなら、彼らもコンピュータではない。彼らは、ある種の遺伝子改造された菌類の織り成す大規模神経繊維集積──生体素子の集合した「思考する物体」であり、まごうまごうかたなき「生き物」である。" 秋山瑞人.E.G.コンバット(電撃文庫)(p.75).株式会社KADOKAWA.Kindle版. ↩
- 4.第4章「コラム: データ型を適切に選ぶ」P193 ↩
- 5."「脚部損傷、電圧異常時のバイパス回路接続とその間の回避運動。やることを最初から順に言ってみて」ルノア教官が怒っている。自分がいつ、どこで地雷を踏んでしまったのかわからない。カデナはただただ狼狽する。「──そ、そんな制御、VOGUSが、流体脊髄がオペレートする……」「脚部損傷、って言ったでしょ。姿勢制御系まで過電圧でやられてたら? 流体脊髄だって、データが入ってこなかったら何もできないよ。手動でやるには?」瞬間、カデナは頭が真っ白になった。絡み合っている知識を必死になって解きほぐし、懸命になって回路構造を思い浮かべる。「え、ええと、まず──電源、そう、損傷箇所の電源遮断、三軸の機体傾斜角確認、地表傾斜角確認、そ、それから──」言葉に詰まる。その次、次は、母線からの脚関節への電力分配? 違う……そう、関節の状態確認だ、多分。でも、どうやって──!? 頭の中の時計の秒針がひと回りしたのを確認して、ルノアは言った。「はい、戦死」" 秋山瑞人.E.G.コンバット2nd(電撃文庫)(pp.74-75).株式会社KADOKAWA.Kindle版. ↩
- 6.第3章「3.2 Lua」P126~P145 ↩
- 7.第2章「2.7.6. データ型を問わず利用できるコマンド/汎用的なコマンド-押さえておきたいコマンドの動作の詳細」P117~P119 ↩
- 8.アトミック性: コンピュータ上のプログラムの動作で、密接に関連する複数の処理が外部から1つの操作に見え、途中の状態を観測したり介入できない性質 https://e-words.jp/w/原子性.html ↩
- 9.おさまりが悪かったので注釈ではありますが、「実践Redis入門」を読んでて気になったことをこちらに記します。自分が本書を読んでいだいたイメージは、全能の技術者が傍にいて関連する機能や活用事例や懸念事項を1アクションごとにずっと喋ってもらうような感じです。具体的なユースケースや障害発生時など目的をもって質問したいとき、そのような包括的な知識は大いに励みとなります。反対に、正直、本書はさくっとコマンドを調べたい用途には向いていません。Bing先生やChatGPT先生にRedisドキュメントのリンクを出して説明してもらう方が早いです。ただ、ある程度責務を持って実装する中で、コマンドの字引としてドキュメント以上に詳細な説明を知りたいといったケースも当然あるとおもいます。そのような時は索引でページをひっかけたあと、そのページの章/節の頭から丁寧に読んだ方がいいと思います。関連するコマンドが検討材料になるからです。たとえば、「キーを削除したい」=>「雰囲気的に
DEL
やな」 => 「DEL
コマンドとよく似たUNLINK
というコマンドがあるぞ?」 => 「DEL
による同期削除処理は性能問題になるケースがあるのか」 => 「非同期削除処理であるUNLINK
で済ませられないか設計の再検討をしてみよう」 => 「Lazy Freeingちょっと理解した!」 => 「lazyfreee_pending_objects
メトリクスもちょっと理解した!」 という風に連鎖的に理解が進みます。また、コマンドによっては文面に説明が埋め込まれており、それがすべてのケースもあります。スナップショットを取得するコマンドであるSAVE
/BGSAVE
コマンドがP197に記載されていますが、このページだけだと取得方法がわからず、自分はググりました。。。もちろんこれらは本書の魅力を損なうものでは決してありませんが、その辺を意識して読むとより活用できると思います。 ↩