エンジニアの成長
こんにちは、シニアソフトウェアエンジニアのriddleです。
こんにちは、ミドルソフトウェアエンジニアのひびのです。
このポッドキャストでは、僕たち2人がIT業界でのキャリア、普段の困りごとなどに関する様々な話をして、IT業界のリアルを届けようという趣旨の番組です。
今日のテーマはですね、ソフトウェアエンジニアは自分のケツを自分で拭いて一人前になる話。
イエーイ!
イエーイ!拭いてるかい?
拭いて、拭いていきましょう。いやこれ、そもそもの始まりが僕の持論なんですけど、
僕、師卒でweb業界に入って、それこそ、特に最初のキャリアがサーバーエンジニアだったので、本番で色々なシステムを扱うわけですよ。
そうですね。
はい。で、何回かやらかしをしたなと。
やらかした?
やらかしました。やらかしアドベントカレンダーにかけるようなことは何回かありましたね。
やらかしたアドベントカレンダーね。あれいいよね。今度紹介する予定です。
本当ですか。いや、あれやっぱり何というか、そもそも職場でもポストモーティブみたいな仕組みがあって、
それ自体がすごく学びになると思うんですけど、やっぱり色々な人の失敗談っていうのは、
じゃあこういうことがあったからうちでも気をつけようみたいな意気を汲んでいきますよね。
そうですね。ちなみにポストモーティブって何ですか?
ポストモーティブは厳密な定義。僕もはっきりとは言えないが、あれですよね。
インシデントが起こった時にどういう状況で起こったか、何が原因で起こったかみたいなのをみんなで振り返って対策につなげるっていう、
ドキュメントだったり会議だったりの総称だと自分は理解してます。
かっこよく振り返りを言ったやつ。
そうですね。振り返りを表す言葉、レトロスペクティブとかもあって、
いちいちそんな使い分けなくてもいいのにっていう感じですよね。
やめてほしい。
失敗を振り返るというのはすごく大事だ。
僕も話を戻すと、新卒の頃、本番でやらかしをして、最初はそれこそ新卒エンジニアの頃は、
先輩の助けを借りてどうにか進化したりとかしてたんですけど、
ある程度自分一人でシステムの全容を把握して、
自分でやらかした時に自分で対処できるようになったタイミングがあったんですよね。
ついに自分で。
自分で対処するって言っても、やらかしてしまった。
そして取り急ぎ企画の人に報告。
そしてこうすれば治るだろうみたいなことを考えて、やりますって宣言してやる。
では最後に影響を受けたユーザーへの終わりのメッセージを送るみたいなところまで、
手を動かすところは一通り自分でできるくらいのところまでは行けました。
一人前になりますね。
そうなんですよ。
僕その時に初めてエンジニアとして一人前になれたなと感じて、
これ特にエンジニアの人全員通る道なんじゃないかなと思ってるんですよ。
実体験を通じた教訓
それは何かミスをして頑張った後で埋め合わせをするって話ですか?
はい、そうですそうです。
自分でその埋め合わせができる幅が広がっていく。
そうですかね。リドルさんそういう経験ありますか?
それは全然今になってもありますね。やべえミスった直さないとみたいな。
よくありますね。
まあそうですよね。それこそでも本当にリドルさんであっても、
新人の頃はインシデントが起こったでどうすればいいだろうってオロオロして、
先輩の力を借りてどうにか喧嘩するみたいなタイミングがあったと思うんですよ。
お客さんのサーバーを落としちゃったよね。
それはやばいですね。
今となってはたぶんリドルさんクラスなら復旧まで自力でできますよね。
まあ。
それくらいシステムを把握してからチャレンジするみたいなところも身についてると思うんですよ。
だから大事だねと思ってこれは。
そうですね、大事ですね。
ちなみにどういうやらかしたかというと、僕がやらかした中で一番やばかったのが、
大丈夫か?大丈夫か?
たぶん大丈夫だと思います。
というのも、その時所属していた部署のサービスが基本的にはAWSのインフラに乗っかっていました。
ある時にお客さんにプロモーションの試作を打ちたいということで、
結構多め、ほぼ全員くらいのユーザーにメッセージを送信することになりました。
プッシュ通知ってことですか?
そうですね、プッシュ通知プラス僕たちが独自で構成していたメッセージの仕組み。
きらたく言うとデータベースにメッセージを登録して、
それをお客さんのフロントエンドで見られるみたいなものと、
プッシュ通知をセットで送る仕組みがあったんですけど、
それで自分、キャンペーンのプロモーション送信やりますって手を挙げて、
いざと取り掛かったわけですよ。
メッセージ送信スクリプト自体はこれまで送信実績のあるものがあったので、
自分としてはプロモーションごとに振られたレコードを新しく作成して、
それをメッセージに紐付けて、
メッセージの内容、企画の人からもらったものを反映して、
あとは送信くらいだったんですけど、
ちょっとこれ早めに送りたいなみたいな話が直前にあって、
早めに送ったら喜ばれるのかなと思ったんですよ。
思って、さっきも話したように、ユーザー全体だとめちゃめちゃ数が大きくて、
送信に時間がかかることは分かってたんですよ。
なので、僕がやったことは、最初そのメッセージ送信スクリプトを平たく言えば、
並列で動かしたら早く送れるんじゃないかなと思って。
間違ってなさそうですよね。
そうですね。最初、僕がこれは完全に想像で8分割くらいできるんじゃないかなって思ったんですよ。
急に想像入ってきたな。
これは本当に検証すべきなんですけど、8分割すれば早く終わりそうだなと思って、
早く終わりそうかつ現実的に安全だろうと踏んで、
最初8分の1を送るスクリプトを本番で動かし始めたんですよ。
8分の1を送り始めて、これ全然Metrix見ても問題なさそうだなと思って、
その後、残りの7つ一気に動かしたんですよ。
なんで8分になったんだよ。
いや、むしろあれですよ。並列で動かしたら早く終わるだろうなのを考える。
なんですけど、8個動かしたら何が起こったかというと、
その時使ってたサービスのデータベースが一つマスターDBがあって、
複数のリードレプリカがあるっていう構成だったんですよ。
お客さんに見せてる情報の中にはリードレプリカからセレクトした情報ももちろん含まれてる。
その中で、マスターDBに大量の書き込みを行っているわけなので、
レプリケーション期限っていうのがたまに発生するわけですよ。
そうですよね。
マスターDBからリードレプリカへのデータ転送にラグが発生する。
それはデータの書き込み量が多いと、数秒くらいは毎回発生してしまうものなんですけど、
動かしすぎて大体で確か2分くらいリードレプリカへの書き込みを遅延させてしまって、
サービスの中でも結構読み込んだ情報を書き込むみたいなところでも
本当に稀にリードレプリカの情報からセレクトしている箇所があってしまったがゆえ、
多くのお客さんにご迷惑をかけてしまったという思い出があります。
ユーザーへの謝罪
急にサラス飛んだんだけど。
具体的にどこが遅延してたからどこの書き込みに失敗してたかとかは
サービスの性質がバレてしまうので、それは省略させてください。
ちなみにアプリなのかサービスなのか分かんないですけど、どういう状態なのですか。
使えなくなったみたいな感じですか。
例えば平たく言うと、ユーザーがこの商品を、
ECサイトではないんですけど、それは厳密には。
この商品を購入したいみたいな商品一覧がユーザーのフロントエンドに見えるわけじゃないですか。
ユーザーがそれをクリックしたら購入できるとします。
そのときにユーザーに見せる情報がリードレプリカからセレクトされた情報を
ユーザーがクリックっていうアクションを起こすと、
マスターディビューにその情報を書き込みに行こうとしますよね。
つまりユーザーの手元では、まだこの商品があると見えていても
クリックしたらもうすでにその商品がなくなっているみたいな状況が
各お客さんのフロントエンドで起こってしまったわけですね。
なるほど。何分くらい続いたんですか。
結局リードレプリカへの反映の2分くらいのラグで
2分間起きたみたいな感じなんですかね。
遅延が2分で、遅延が2分起こって
その遅延がどれくらい続いたかというと
正確な定数は覚えてないけど30分くらい続いたはず。
そうなんだ。
なぜなら8並列を30分間動かし続けたので。
途中で止めたりしなかったの?
途中で止めるっていう選択肢もあったはあったんですけど
ちょっとその時どうすればいいかわからなかった。
報告が遅れてしまったっていうやらかしがあって。
起きてからすぐ報告しなかったじゃないですか。
あとそれについては
僕も正直アラートが上がってくるまで気づかなかったんですよ。
そうですよね。
アラートが上がってきた時ですでに十数分経ってたはずなので。
ここからが今回のテーマ
自分の血を自分で拭くっていう話なんですけど
僕はその時ミドルの入り口に入りたてくらいの
それなりに動けるエンジニアにはなってたので
急いで影響を受けたであろうユーザーIDのリストを作成して
その人たちにお詫びメッセージを送りたいですって言って
メッセージを送ったという記憶があります。
それでまた地震が起きたんですか。
それはもう
予定30分くらいで
実際にさっき言ったような
失敗と成長
ユーザーがフロントエンドからリクエストしたけど
データベースへの書き込みに失敗したみたいなのは
全部ログに出てたので
そのログは去って
でもそんなに大した量ではなかったはず
大したユーザー数ではなかったはず
ユーザーベース全体に比べたら
I understand.
一番自分の記憶に深く残っている出来事ですね。
個人的にもその時初めて
自分との手を借りずむというか
他のエンジニアに頼らず
全部自分で引き継いできたなっていう感覚は
成長してる。すごい。
でもこういう経験は本当に大事だなと思います。
そういう経験をすると
特に自分ができるようになってきた状態だと
身が引き締まるというか
そうなんですよね。
かなり落ち込みますよね正直。
そうですね。
でも人間そういう辛い経験を乗り越えて
成長していくものだと思うので。
寝たら忘れてるよ。
ストレスマネジメントもね。
スピードが上がったんですか?
僕も一晩寝たら
そんなこと言ってないで頑張るしかないな
みたいな気持ちになってた気がしますね。
再発防止としてはどうしたんですか?
再発防止としては
ポストモーテム
その時は
その時ポストモーテムやったかな?
ちょっとそれは記憶にないが
これは安心してほしいんですけど
その時使ってたのが
AWSのRDS
で今そのサービスは
AWSのAURORAに移行されてて
リードレプリカがないはずなので
もう起きないはずです。
でもさ、大量にライトをすることによって
単純にディスクのIoとか枯渇して
ユーザーも
それはありえますね。
どう再発防止すればいいんだろうな。
なんかスパナーとかだったら
優先度っていう概念があるんですよ。
DBへのリクエストに対して。
で、その通常のリクエストは結構高いんだけど
それ以外の明示的に負荷を
与えないように低くするみたいな
書き込みとかもあって
名前ちょっと忘れた
ステイルリードだったかな。
わかんないですけど
そういうのがあって
それ使えば
影響を与えない範囲で
勝手に制御してくれるというか
特にそういうバッジ書き込みみたいなことを
するときは
そういうオプションを使うといいってことですね。
そうですね。
賢いですね。
だからなんか似たようなものを
マスクしたらあるかもしれないですね。
そうですね。
エンジン化をとか。
大量にデータを書き込むときは
そういう施策は必要そう。
わかる。
でも難しいですよね。
送る人数がもっと増えたりとかしたら
それこそね
いっぱい時間を買っちゃうだろうし
ちょっと図しか送らなかったら。
そうですよね。
あとなんか個人的に思うのが
これまでいくつかのサービス見てきたんですけど
メッセージングって設計難しくないですか?
どの辺の話ですか?メッセージング。
例えばアプリ内に
運営からユーザーに対するメッセージ機能を付けたいとか
あとはユーザーからユーザー
ユーザーユーザー間でのメッセージ
送信機能を作りたいとか。
なんか基本的にそういうのって
内製することが多いんじゃないかなと思ってて
何か別のセンスに乗っかるとかじゃなく
かつサービスの性質に合わせて
オーダーメイドしなきゃいけないことが
多くないですか。
例えばユーザーがこういう時に
こういう目的で送るから
データベースのカラーウェイに
あらかじめこういうものが必要だろうとか
こういう構成をとっておかないと
後でデータの量がやばいことになりそうだとか
あるなと思います。
そういう管理者がみんなに送るみたいなやつは
全員にレコードを追加するってのは結構
しんどいと思っていて
100万人いたら100万レコード一気に増える話になるんじゃないですか。
そうですね。
であればマスターデータじゃないですけど
そのシステムメッセージのテーブルを1個用意しといて
そこに単純に送りたいメッセージを書いておいて
ユーザーにはログインしたタイミングなのか
アプリを開くタイミングなのかに
今新しい魅力のシステムメッセージあるかどうかだけ
APIに返してあげて
それの読んだか読んでないかだけの履歴を
ユーザーごとに持つみたいな設計の方が
まあいいかなと思います。
そうですね。おっしゃる通り。
あと僕今年メッセージ
運営からユーザーへのメッセージング機能を設計したんですけど
今リドルさんがいった設計そのまんま自分もやってて
ちょっと安心しました。
これでも起きない。
起きないはず。
その時もかなり複雑な仕様だったんですけど
でも基本…
そうですね。ユーザー単位のメッセージボックスへの書き込みしましたね。
そう考えるとなんか根本原因は
設計がそもそも悪い。
そうですね。それは確かにある気はするんですが
ただとはいえ
そのサービスのユーザーの単位自体がまあまあ複雑で
失敗からの学び
ってみたらそのユーザー
同じユーザー大元のユーザーテーブルにいるアカウントたちを
2つのカテゴリーに分けなきゃいけなかったんですよ。
でその片方のカテゴリー
まあこれもかなり大量なんですけど
そっちにだけ送らなきゃいけないっていう経緯があったっていうのはありましたね。
男性と女性がいて男性だけに送れるみたいな
平たく言うとこんな感じですね。
でもこの失敗をベースに自分の血を拭くことによって
一段成長したと
そうですね。なのでちょっと僕からちょうどいい時間だと思うので示させていただきたいんですが
特に新人エンジニアの方失敗することもたくさんあると思います。
でも失敗を乗り越えて自分の血を拭けるようになって
エンジニアは成長していくものだと思うので
逃げずに頑張ってください。
あとあれかな。マネージャーの人は失敗してもリカバリができるような環境を作ってあげてください。
これはシステム的にもフル等的にも
エデュレスですね。
論争、野争、大事。
このポッドキャストはハッシュタグUITで皆様からの感想やコメント募集しております。
またチャンネルの概要欄にGoogleフォームのリンクもありますのでそちらからのご投稿も大歓迎です。
ありがとうございました。
ありがとうございました。