歴史あるSNSで業務&システム改善を行ったので知見共有

YA8C 2016 mid. in Shinagawa

@ytnobody 

ドーモ、わいとんデス。

わいとんデス

  • [ytnobody] [検索]
  • 小さな事業会社の開発部の部長(社歴1年)
  • MySQL Casual Advend Calendar 2015 でopenark-kit(OAK)のエントリ書いたら伸びたので、それで知ってる人もいるかもしれないですね
  • 基本的にPerlの人ですが、GoもRubyもjavascriptもbashもdevopsとやらも一応やります。

今日話すこと

  • join当初の状況について
  • 可視化と夜間対応:あるいはインフラチームの成り立ち
  • 最高にハイなコードとの付き合い方
  • MySQLの気持ちに近づくには
  • こうやって開発部を強くした
  • こうやって経営層と対話した
  • その他技術的な話

今日話さないこと

  • サービスの宣伝
  • キラキラした話

全般的に泥臭い話が多くなります

background colorはwindows95オマージュです。

join当初の状況

サービス環境

サービス自体がオープンされてから14年ほど経過しているらしい。技術的には非常にレガシーだが、なぜかPSGI化だけされていた。サーバは全部オンプレで4ラックにぎっしり詰め込まれており、そこにKVMゲストが4ノードずつ収められている。プロビジョニングはされていない。会員600万人オーバー。

  • Ubuntu server 14.04 LTS
  • perl-5.14.2
  • httpd-2.0.x
  • nginx-1.0.x
  • mysql-5.5.x
  • Sledge + Sledge-Dispatcher-PSGI
  • BIG-IPなどの各種ネットワーク・アプライアンス
  • 稼働しているホスト数はおよそ270。

運用環境

外部に業務委託。最低限運用に必要なものが揃っているが、各種レポートはマジックナンバーの嵐。属人化が激しい。一応ドキュメントはあるものの、Redmine wikiに雑多にメモされているのみ。各種指標について、定量観測の仕組みがない。 しかも、業務委託先の会社が契約更新をしない方針というのを、入社して4日目くらいに知らされる。

  • zabbix
  • MRTG
  • 定期バッチによる各種監視(何か問題があったらメール。ただしマジックナンバーだらけ。)

社内環境

創業社長によるワンマン。それ自体、僕自身にとって特に抵抗感はなかったが、チームの一部ではすでにMP切れが発生していた。特に、業務委託先の運用会社が契約更新をしない方針、ということがダメージとなっていた模様。

開発チーム

モバイルアプリエンジニア(外注)含めて7名。Ops経験のあるエンジニアの不在がネックとなっていた。

可視化と夜間対応

またはインフラチームの成り立ち

運用環境の改善

実質上Ops経験のある人間が自分一人しかいなかったので、まず人事にコンタクト。

人事氏「2ヶ月くらいかかるよ」

_人人人人人人人人人人_

> 2ヶ月くらいかかるよ <

 ̄^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄

ですよねー

人材採用への協力

  • とりあえず時間はかかってもいいので、インフラエンジニアを採用してもらうよう言質を取った。

  • 面接には必ず自分自身で参加して、スキルや志向や人間性を見極めるようにした。

結果的に、手練のインフラエンジニアが2名joinしてくれた。

既存の人材の再評価

  • ある時、とある若手社員が出向から転属され、企画部に配属された。
  • ところが、彼の本来の希望職種はエンジニア。
  • 聞くところによると、実力不足が仇となり、転属となった模様。
  • 情報に対するアンテナは高いらしいが、若干天狗な面も。

こいつをインフラエンジニアにしてやろうか

(CV:デーモン小◯)

若者(Mくん)の話を聞いてみる

  • 社内での評価が芳しくないらしい(事実、周りの評判もあまり良くない)。
  • node.jsに興味があって、個人的にwebappを書いている。
  • コードは比較的まともそう。
  • サービス維持の観点で危険と思われる事象の察知が素早く、的確。
  • 承認欲求をこじらせているだけに見える。

M君をインフラエンジニアにしてみた結果

  • 既存の仕組みでできる範囲の障害対応を任せたところ、夜間でも的確に対応してくれた。
  • モニタリング結果から、あらかじめ問題を察知してくれた。
  • BIG-IPのオペレーションを自分で学び、障害発生時に該当appサーバを切り離すところまでやってくれた。

未経験なのに2ヶ月くらいでできるようになってた

ポイント

  • あえて未経験分野のインフラに投入することで、ステップアップを実感してもらった(承認欲求の充足)。
  • サービスの要とも言えるBIG-IPを知ることにより、実践的な能力を最短で獲得してもらった(得意分野を作ることによる実力不足の解消)。
  • もともと危険察知能力が高いことを生かして、短期的・中期的なリスクの洗い出しをしてもらうことにより、経営層への存在感をアピールできた。
  • 失敗自体が致命的となるインフラを任せることで(実際に失敗したこともある)、自分の能力・身の丈にあった態度へと改めることができた。
  • ただ一人で仕事を任せるだけではなく、熟練インフラエンジニアとバッテリーを組ませて実戦に差し向けることで、熟練の技を盗むチャンスを与えることができた。

こうして半年後、人材が揃った。

インフラチームの成り立ちである。

夜間対応

  • 基本的にサポートセンター(24365)からの問い合わせに対する回答および対応
  • skypeでやりとり。サイトの不具合についてもサポセンから問い合わせが来る。
  • もちろんインフラ側の対応を要するケースもある。

非常に低意識ですね!

しかし、これでうまく回っているし、利益も出ている。

よって、このままにしておく。最適化のやりすぎは良くない結果を招くという見解。

周辺ツールの整備

モニタリングをする上で周辺ツールが不足していたので、いくつかのものを導入。

当初はモニタリングに必要なものを中心に揃えていたが、次第に開発チームの要求を満たすようなものも揃えるようになっていった。

NewRelic

モニタリングデータをスマホから簡単に見ておきたかった。

Pyazo2

Gyazo互換の社内用画像共有ツール。

uzulla-san ware.

NoNoPaste

ログやソースコードを共有する仕組み。Pastebinのようなやつ。

kazeburo-san ware.

Slack

社内に通知用endpointを作っておき、雑に自動メッセージを送信できるようにしておいた。

Reactio

障害発生時に担当者を一斉電話呼び出しする仕組み。

障害そのもののナレッジベースとしても利用。

GrowthForecast

各種定量観測項目をhttpで投げ込んでおき、グラフ化する仕組み。

他にもイケテルものはあったけど(KibanaとかGrafanaとか)、手に馴染んでいるので選択。

kazeburo-san ware.

Gitbucket

どうしても社内にレポジトリが欲しいという要求があったので。

Solr

雑に全文検索できる仕組みが必要だった。

nata2

MySQL5.5までのslow query logをグラフ化する仕組み。

studio3104-san ware.

私がJoinした当初はslow query logが出まくっていて、一個一個追いかけるには人間が足りなかったので、このツールには本当に助けられました。

Docker Cloud

社内ツールの管理をするために導入。以下のようなツールがContainerとして管理されている。

  • Pyazo2
  • NoNoPaste
  • GrowthForecast
  • Gitbucket
  • Solr
  • nata2
  • storage-container(各コンテナのデータストア用)

新たに可視化するようになったものの一例

  • qmailの送受信数と滞留キュー数
  • データセンターが提供するストレージのRW速度
  • Solrのインデックス更新回数
  • TheSchwartzのキュー数
  • MySQLのSlow Query発生回数
  • モバイルアプリへのpush通知送信回数

最高にハイなコードとの付き合い方

こいつを見てくれ。

こいつをどう思う?

package MySNS::Data::Contents::Board;
use strict;
use warnings;
...
sub is_checked {
    my $self = shift;
    ...
    $self->set(status => 4);
    ...
}

野郎ぶっ○してやる

まあまあ、そのスパナを収めて。

  • 実際こういうコードばかり
  • こういうのに依存しているコードも多い
  • Perlエンジニアは実質自分を含めて3名、しかも企画推進に多忙。

コードの完全なリファクタは、まずペイしない

  • 有限リソースである労働時間を、利益を生まない活動に使うのは、専門部署がある会社のやること。
  • 小さな会社ではもっとドラスティックな対応をとったほうが総合的に利益に近い。

じゃあさっきのはどうするの?

A: コメントを書く

  • 差し支えなければcarpも。
  • 後々当該機能を分割し、別のWebAppとして実装するよう、経営層や企画部門と調整していく。
  • 分割するときには、高速化やミニマル化を重視。
  • 要件次第ではGoなどの高速な言語に乗り換えてAPI化も検討するとよい。
  • 「ここを高速化することによって○○%売り上げ増が期待できます」って言えるなら、さっさと企画を立案すべき。

よくある最高にハイなコードたち

マジックナンバー

副作用のなさそうなメソッド名なのに副作用ありまくり

8世代におよぶ長大な家系図をもつ継承まみれのクラス群

n+1問題を踏み抜くORMのトリガー

unless…else

if内の複数条件

複数の作業を押し込めて太りすぎのメソッド

受け取ったリファレンスに変化を加えるメソッド

不必要なExporter

Controllerにべったり書かれたvalidation

握りつぶされるexception

ハイなコードが生まれないようにするために

  • 定数を使う
  • is_nantoka のようなメソッド内でデータの更新をしない
  • 継承をやめる
  • Query/req をトレースする(15q/r以上の箇所は改善の余地あり、など)
  • unlessをやめる
  • if分岐の条件を1つにする
  • 一つの作業を関数・メソッドに切り出す
  • リファレンスの受け取りをやめる
  • Exporterをやめる
  • validation用の名前空間を切っておく
  • かならず$@をハンドリングする

というようなことに気を付けながら

  • 結局最後は複数名によるコードレビューが一番効果がある。

MySQLの気持ちに近づくには

クエリ実行計画を見る

スロークエリに気づく

  • slowlogを見よう
  • 一つの方法としての nata2 によるスロークエリ閲覧

DBIx::Sunny使ってるとクエリ発行箇所の特定が簡単になる

  • クエリの中に、クエリ発行元ロジックのファイル名及び行番号までコメントとして追加してくれる。

結局のところ

地道にモニタリングするのが一番の近道。

こうして開発部を強くした

飲みニケーション

  • 仲間と一緒に7000円くらいを負担してちょっと気持ちよくなったり気持ち悪くなったりするだけでいろいろ見えてくる
  • 普段見えないボトルネック
  • インシデントの種
  • 人間性

経営層の面々と飲みに行くと見えるのが

  • 経営層のボトルネック
  • 本当の意味での経営戦略
  • 社員に求めるもの
  • 人間性

経営層と開発メンバーの橋渡しをする

  • 飲みやランチで経営層が開発メンバーをほめていたら、それを伝えてあげる。
  • 開発メンバーからの要望をそれとなく伝える。

基礎能力のレクチャー

  • 「Perlは触ったことないです」というエンジニアは実際多い。
  • そんなメンバーにも、できるだけいい感じにコミットしてもらうために、基礎をしっかりしておきたい。
  • 最高の処方箋、それが「Perl入学式」とその講義資料
  • 私もPerl入学式のサポーターです。

社外で獲得した技術的知見の共有

  • 各種地域PM
  • Perl以外の言語の勉強会
  • プロマネ系

などなど・・・

こうやって経営層と対話した

そもそもエンジニアは経営層から理解されにくい

  • 「気難しい奴が多い」
  • 「何を考えているかわからない」
  • 「お客様のことを考えていない」

一部は真かもしれないが一部は偽である

  • 気難しい→思慮深い
  • 何を考えているかわからない→自分ではわからない事を考えてくれている
  • お客様のことを考えていない→お客様に届けるものについて考えている

経営層と理解し合える必要はない

  • お互い分かり合えるわけなんかない
  • 「うちの社長はわかってない」→「うちの社長は別の視点を持っている」

重要なのは同じ最終目標を目指している事

  • 唯一合意すべきは、最終目標が同じである事
  • 定期的に最終目標の認識ずれがない事を確認する
  • 認識ずれがある場合は、経営層のほうを優先すべき。しかし、認識ずれの理由は説明しておく必要がある。
  • 「寝てるだけでチャリンチャリンお金が入ってきて、しかも楽しいのが理想ですよね」

エンジニアが働けるのは経営層のおかげ

  • つまり、経営層がweb関連の商売をできるのはエンジニアのおかげ

お互いにリスペクトすること

  • 互いをリスペクトできている間は、エンジニアと経営層はそれなりにうまくやっていける。
  • ただし、万事完全に協調しきれるというものでもない。
  • 互いに半々くらいのバランスで義理を通していくくらいで丁度良い。
  • 時間が信頼を育む。
  • 経営層のわがままを聞いてあげたら、エンジニアのわがままを聞いてもらおう。

世の中のたいていの社長さんは「新しいもの」がお好き

  • 数少ない、エンジニアとの邂逅のポイント
  • 「新しくてイケてる」技術であり、それがお金を生み出すのなら、その技術の導入は進みやすい。

そのほか技術的な話とか

新しすぎる技術の弱点

  • 新しい技術をキャッチアップしている者でなくてはメンテナンスできない。
  • 運用実績が少なく、トラブルシュートで苦戦を強いられる。

それでも新しい技術はキャッチアップしておきたい

  • いままでできなかった事ができるようになるなら・・・
  • もっと楽に運用できるようになるなら・・・

何を技術導入の目安にするか

  • それを入れる事で、2つ以上の業務・ミドルウェア・技術を省略できるようになるか。

例えばansible

  • セットアップスクリプトの省略
  • capistranoの省略

Azureの導入してたりしていて

  • Azure上への分析基盤を進めたり
  • マーケティング施策のための一時的なリソースとして利用したり

まとめ

  • 可視化にはツールが、夜間対応には人間がそれぞれ必要。
  • ハイなコードに対応するには、短期的には明確化、中長期的には機能分割によるコードのすげ替えがローカロリー
  • スロークエリの可視化とクエリ実行計画の確認が、MySQLの気持ちになる近道
  • チームを強くするには基礎能力の強化と問題意識の共有が効く
  • 経営層とエンジニアがわかりあう必要はなく、最終目的が一致していることを継続的に確認することが肝要。
  • 実直な技術で複数の課題を解決していくことが、たった一つの技術選択基準である。

ご静聴

ありがとうございました