読者です 読者をやめる 読者になる 読者になる

Viibar Advent Calender 2015

はじめに

こいつは Viibar Advent Calender 24日目の記事です。

自己紹介

Viibarではリードエンジニアをやらせてもらってます。
エンジニアとしては10年オーバーですが、若手に前線を譲って便利な器用貧乏にはならないぞ!が合言葉で頑張ってます。

技術的にかっこいいこと書こうとも思ったのですが、ちょっとエモい話をしようかと思います。

リードエンジニアとして気をつけていること 

GithubでPRを出してもらいレビューでOKがでたらmasterへマージしてリリースしてOKという、シンプルなルールで運用しています。

ところがどうしてもゾーンに入ってしまったり、自分の仕事で手一杯でPRを見る余裕がなかったりして、なかなかレビューされない、みたいなことがあるんですよね。

打開策として16:00から1時間をレビュータイムにして積極的に見る時間を設けたりはしていますが、とはいえそれでも漏れたり、急ぎのPRとかもあったりはするので、積極的に拾っています。

「誰かのレビュー待ちでこの機能をリリースできない」というのは機会損失以外の何物でもないので、そうならないように心がけています。

またそれをなるべく実践できるように「そこは自分ではレビューできない」という領域を作らないように、フロントも含めて、すべてのPRは目を通すようにしています。

もちろん現実すべてのPRにコメントをつけることは無理で、マージ後に見ることもありますが、コミットログを見るのが趣味な自分的には、楽しいです。

全体設計の方向性を示す

複数人で開発をしていると個別最適化がされて全体としての最適化がおざなりになることがありがちです。

Railsで言えば適切に concern 化したりする必要がありますし、サービス全体にかかわるコアなモデルをどう扱うかだったりは、どうしても1機能開発だけを考えると「とりあえず」を繰り返してしまいます。

特にエンジニアの人数が増えて1サービスで5人を超えたあたりからこの傾向は顕著になると思ってます。

個別最適化は、それはそれで大事なのですが、「ここの設計はこうするべきだ」という道筋を決めるのは大事です。

ただ全体設計の方向性というのは、時に変化するものですし、プロダクトがピボットすると0から考えなおす場合もあります。なので大きな転換や整理をする場合はgithub issueで話し合ったり、ログに残すことを意識しながら行っています。

 

あと意識的に「これって今は流れでこうやってますけど、本来はもうちょっと考えたいですよね」的な波風を現場が混乱しない程度にPRにコメントすることはあります。

過去の流れでよくない設計になっていて、それは絶対正しくないんだけど、今負債を返すタイミングじゃないし、みたいな時はあえて直さないという選択を取るんですが、それをやりすぎると「本来はどうあるべきか」みたいな思考を持たずにどんどん追加して行って傷口が広がる場合があるので、それの防止ですね。

特に最初からいるメンバーならそういった小さな傷もわかっているのですが、後から入ったメンバーはわからなかったり、逆に「え?これなんでこうなっているの?」みたいな不満にもつながるので、レビューを通して共有できるようにしていますし、「え?これなんでこうなっているの?」って思った人が直す時に手を上げやすくするという意味もあります。

 

それはやりたくないとは言わない

いわゆるスタートアップなので、いろんなものが降ってきます。

サービスのドメインSSLを自分で取ることもあるし、
情シス的な仕事もあるし、
社内要望をまとめてexcel管理しなければならないこともあるし、
インフラも当然見るし、
CSSやJSも必要ならば修正するし、
営業が使っているCRMをさわることもあります。

最近はメンバーも増えたので、いろいろ楽にはなりましたが!

ただ最後の砦じゃないですが、誰もやりたくないってなったらやるよという覚悟はあります。

「開発においてCSSからAWSまで」

はモットーです。

開発において誰よりも怠惰であろうとする

やっぱやりたいことがたくさんあります。全部やっていたらきりがないし、リソースは限られているので、「それは自分たちで作るんじゃなくて、外部サービスでできないか」とか、「楽に手間なくする方法は他にないのか」みたいなことは常に考えるようにします。

時に、エンジニアとして話し合うより、作るのが簡単な場面はあります。ただそれは単なる自己満足でしかないですし、作らずに目的を達成できたら万々歳ですよね。

 HRT を大切にする

Team Geek で紹介されている
Humility(謙遜)、Respect(尊敬)、Trust(信頼)

ですね。

特にSlackなどのチャットサービス上での会話やレビューにおいてはどうしても残るものなので、丁寧には心がけていて、なんかどうしてもカッとなったらまだ口頭で話したほうがこじれないかなと思います。

エンジニアリングに置いてのコミュニケーションはもちろんですが、開発者以外に対してのコミュニケーションにおいても大事にしています。スタートアップなんて狭い人間関係の中で仕事をしていますし、「あいつと合わないから」なんて理由で違う部署に異動とかも無理ですし、あいつとあいつが喧嘩しているなんてもうわかちゃうんだもん。

 

もちろん単なる仲良しこよしをしても意味はないので、HRTは大切にした上で言うべきことは言います。

 

もちろん聖人ではないのでテンションが落ちている時や飲み屋で愚痴ることはありますけどね!!!

 

その他

リードエンジニアの役割は会社によって様々で、個人的には

d.hatena.ne.jp


を参考にしています。

マネージメント的な役割やもっとビジネスサイドを踏まえた戦略に関しては弊社には歴戦の経験を積んだCTOとか 

www.wantedly.com


、他にも開発マネージャーもいるので、テックリード的な役割に集中できるので色々楽です。


 最後に

明日の 最後の締めは Viibar CEO にとってもらいます!

 

 

#isucon4 予選で惨敗してきた

記事かかないせいで、予選で惨敗してきたブログになりつつあります。

今までどおり、 @iszk, @froncool のチームで。

 

仕事でつかっているアカウントの ec2 のinstanceが運悪くほぼ全部これにあたり、前日どたばたしていて、全然なにも準備できないまま当日をむかえました。

Amazon Web Services ブログ: EC2メンテナンスアップデートに関して

 

いや暇だからって準備万端かっていうとそうでもなかったとおもいます。

当日9:20

よし、準備万端、あるいていける場所でやる予定だったので、余裕あるしご飯とかおやつとかかってむかおう!っておもって鞄の中身を最終チェックしていて

「お、おい、macbookの充電ケーブル会社やないかーい!」

と気がつき大慌てで会社に向かいました。私が代表者扱いになっていたので、いろいろ今日の件について運営からメールが来ていたんで、電車内でみんなに共有しながら。

せめて遅れる代わりにとレギュレーションを熟読しながら会場に向かいました。

 

10:20

遅ればせながらついたので、AWSに関して @froncoolに共有しながら作戦をねる。

 

10:50

ログをだしつつ、これ、ミドルウェア周りはやるけど、結局内部の実装すくないし、こっからmysqlの処理の最適化しても、最終的に全部メモリにのせちゃうって結論になりそうだし、ってことでそっちを対応することに

12:30

memcachedにlog系を全部のせる方式に一旦実装。ただちょっと動きが微妙でreportエラーのせいでscoreも送信されない状態がつづく。仮ででているscoreはそれなりにあがっていたので、期待は膨らむも「これデバックどうしよう」という焦りのなかでわりと解決しない。

 

13:30

わりとケアレスなことが多かったことが判明し、泣く。

14:00

一旦休憩。ご飯を食べながら午後の作戦を考える。

14:30

完全にはまったので、書いた本人がデバックしてもたぶんこれ見つかるの時間がかかるよねってことで、@iszkにコードみてもらいながら問題点を横で口頭でいってもらいながら修正

16:00

私のほうでも手直しをしつつ@iszkの方でもいろいろ手直しをして若干安定するが、report結果がずれてscoreが送信されない件が解消されない。デバックは@iszkにまかせて、別ブランチでログインユーザ2万人くらいメモリにもっちまえの実装変更に手をつける

16:30

ログインユーザの件の実装は別ブランチでわりと問題なく完了。

「これはバグなおしてからいれようぜ」ってことで既存のreport結果ずれる件を再度みる

18:00

そろそろ時間がないけどfinishまでどうもっていくかを話しながら作業

18:30

もうこれは運を天に任しひたすらベンチまわしながらworkloadどうするー?とか相談してた。もう残念会をどこでやるかが一番ホットな話題に。

19:00

結局reportをまともに送信できない状態でfinish

19:30

残念会は↓。野崎酒店と同じ系列といえば酒好きならクオリティがわかるかとおもいます。だいぶよかった。


米心 (マイシン) - 渋谷/居酒屋 [食べログ]

 

まとめ

バグの原因とかは翌日、翌々日に「は!!!」ってわかったけど、時既におそし。だいぶしょーもなかった。

ただ前回、前々回にくらべたら進歩はしているかな。。。今までミドルウェアの限界までまわせないことが多かったのですが、一応そこは到達した。。。。書いてないけど @froncool が nginxとかサーバ設定周りをなんだかんだとがんがんなおしてくれてていたので。。。。。

 

もし実装に問題がなければscoreは4万とかいってたので、

敗因はもう私の実力不足としか。次回、次回こそは!

 

米心が素晴らしいってことが伝われば十分です。

 

あ、転職して Rubyist に戻りました。

 

 

#isucon3予選で惨敗してきた

前回と同じメンバー(@froncool,@iszk) でリベンジ!のはずが、リベンジならず。

なにか神がかった奇跡が起きて、自分たちより全員失格で決勝進出をはたすわけもなく、今年のisuconが終わったので、次回に向けてブログに残します。

前日

  • 土曜日に出場するので、前日は金曜日。お互い飲んでもいいけど翌日残らない程度でね!と。集合は9:30だよ!と約束をする。
  • bitbucketでグループと非公開のリポジトリ作ったりして準備
  • AWSを使ったことがあるのが私がAWS係に任命されたので、久しぶりで忘れていないか確認しようとして事件が。 個人で使っていたAWSがクレジットカードの更新を忘れて止まっていました!支払いはするも、アカウントは回復せず。。。サポイートにメールして翌日には使えていることを祈り眠りにつきます。

当日

6:30

  • ドキドキとワクワクで起きてしまう。遠足か!
  • 家の猫に「なんでこの時間に起きてるの?」と不思議そうな目で見られる。

9:30

  • 集合場所に到着。しかし誰もいない!
  • とりあえずAWSのアカウントが回復しているか確認してみるも、どうやら回復していない。しかたがないので新たに別のクレジットカードでアカウントを作成。9:50ぐらいになんとかインスタンスをたてられるとこまでいって、一安心。

10:00

  • 他のメンバー1名到着。もう1名がもうちょいでくるという状態。
  • AWSのインスタンスをたてようとおもうが、指定された、AMIが見つからない。regionをTokyoにしないといけないことに気がつくまで数分焦る。

10:30

  • なんとかAWSたてて、ログインも確認でき、メンバーも全員そろったーということで、コードをみながら作戦会議
  • Perlにしぼる。なぜかはこの日記の最後に書いてます。@froncoolにはインフラ側をお願いする

11:00

  • とりあえず私がPlack::Middleware::Profiler::NYTProfを仕込む。
  • プロファイラーを仕込みながら、過去の経験からmarkdownを変換するのはどうやっても大変なのでどうキャッシュするか検討しだす。@iszkが「redisにhashとって結果ぶちこんじゃえばいいじゃん」とナイス悪知恵をだしたので、その実装をお願いする。

12:00

  • NYTProfの結果をみるも「うーん、DBが遅いのはわかるけどいまいちどこが悪いのかわからない」状態に陥り、使い慣れていないものは使うべきじゃないといまさら悟る。

13:00

  • @froncoolがとりあえずnginxを前にたててくれて静的ファイルをnginxから返すようにしたらちょっとスコアがあがる。
  • @iszkのmarkdownまわりの実装がおわって、試したら「これだいぶヒットするじゃん」ということがわかり一気にスコアがあがる。まだプロファイラがはいっていたので、とったらもっとあがるじゃん!と一気にテンションがあがる。

14:00

  • プロファイラをとったら一気にスコアが下がる。予想としてはそのぶんwebが楽になってさばけるようになったぶん、後ろがつまったんじゃないかという予想。
  • またスコアがばらつきが多いのでちょっとそのあたりを追ったところ利用したredisのライブラリに問題があってエラーが多発していた模様。とりあえず違うライブラリに差し替えたら安定するようになる。
  • @froncoolが一個ずつ丁寧にsqlのindexの見直しをしてくれて地味にちょっとずつスコアがあがる。

15:00

  • sqlを早くするために正規化を崩したりする。
  • ところがbenchmarkとると初期化されてなかったことにされてしまう。indexにしても同様。本当はsudo isucon3 benchmark --initでファイルを渡さなければならなかったことに気がつくまでと、どうやって渡すかで四苦八苦して無駄に時間をとられる。

16:00

  • memo/:id で前のページと次のページを出すクエリがアホなことをやっっていたのをみつけてとりあえずsql2回流す方法で直す。
  • もうmemo/:idごとキャッシュしようとするがエラーがでまくったのでrevertする

17:00

  • 一旦、AMI再起動して大丈夫か確認しようということでそれを行う。案の定nginxが立ち上がらなかったりしていたので、見つかってよかったねと安堵する。
  • その後、titleのために本文をsplitしてるところ別カラムにしようとか見つかりはするも、時間的にギリギリだったためそのままフィニッシュ。

まとめ

 前回は「あわわ、あわわ」している間におわったけど、今回は一応冷静にプロファイルとったりできたのは成長したかなと思いましたが、地力が足りないですね。仕込んでいたとされる罠もあんまみつけられませんでした。

アプローチ的には間違っていなかったのでちゃんとプロファイラーを使いこなせていればという悔いは残ります。

あとインスタンスはケチって1台だけたてるなんてせず、人数分、3台たてればよかった><結構誰かのベンチ待ちでまってたり、修正がかぶってとかいろいろあったので。

 

次回もあったら絶対参加したいので反省は次に活かします!

 

 

あ、freakoutに転職してました。

 

#isucon2 で惨敗してきた

先日 NHN主催の #isucon2 に「アルコールが足りない人たち」チームで参加してきました!

メンバーは 私と @iszk@froncool でして、なんと「全員アプリ側」という。

 

バランス悪!

 

当日までの流れ

 

みんな普段書いているのが ruby, perl, php という状態で、参加を決めたあとにやったのが、まず言語を決めるための宗教論争でした。

なんとなく php で勝ってもうれしくないよねという流れになり、rubyperlにしぼられました。

参加者のメンツ的にやはりperlの人が多かったので、その方面で勝てる気がしないとかいろいろ理由があり、最終的にはrubyに。

まぁ一応全員Javaかけるので、もしJavaの実装があって、サーバのメモリ的に余裕ありそうだったらJavaでもいいかもね。というのはありましたが。

 

その後、事前に使いそうなミドルウェアのrpmだったりソースをDropboxで共有して、事前準備してました。チューニングに使うような情報だったりもテキストにまとめて共有。

その当時は完璧だとおもってたんですが、実際は全然役に立たず><

まぁミドルウェアを最新にしたら倍になりました、なんて簡単なお題なはずがないわけで。。。。

いざ出陣!

そしてむかえた当日。「遅刻厳禁」なので事前に駅構内のパン屋に集合して朝ご飯を食べた上でヒカリエに。

お題とサーバを受け取ったらとりあえずhostsの設定とか、gitの設定をしつつ、お題となるアプリをざっとみる。

 

そこで衝撃の事実。

 

RubySinatraの実装。

 

まぁちょっと考えれば予想はつくはずなんですが、Sinatraの素振りをしてませんでした><

まぁまだSinatraだけならよかったんですが、テンプレートエンジンがSlimで、しばし呆然。

といっても慣れているRailsで書き直したらさらにおそくなること確実なので、覚悟を決めました。

 

ためしにJavaも動かそうとおもったんですが、Springでだいぶ最初からハンデが多そうだったのと、時間も限られているので断念。

 

ボトルネックを探すの巻

 

私がgitの準備やボトルネック調査のためにnewrelicをいれているあいだに、@iszkがコードをざっとみて、@froncoolがサーバ周りの設定を確認という役割分担でした。

とりあえずさくっとなおせそうなところが何カ所かあったので、一番rubyになれている私がコードを修正しつつ、他に簡単になおせそうなところがないか@iszkが調査。

その間に、@froncoolがwebサーバをapacheからnginxに変更。

 

ところが、ここでがくっとスコアが落ちる。

 

なんか設定が間違っているんじゃないかと試行錯誤。あとから他のチームの話をきいてわかったのは、ほぼ静的ファイルがない状態で、nginxに切り替えても、nginxの長所を生かせずスコアがさがると。ここであわてて結構時間をロス。切り替えては戻してを何度かくりかえしてました。

 

いやここは冷静になろうとご飯を食べつつちゃんとnewrelicの結果を見る。

 

うん、/ticket がやっぱ異常に重い。

 

アプリ改修するの巻

 

ここで購入処理が重いのかviewの表示が重いのか悩んでいたら、@iszkがさくっと購入処理のロジックを直す。

 

だがスコアがあがらない。

 

やはりviewの表示なのではということになり、購入処理をしたら購入結果のテーブルを組み立ててしまえということに。

だが時間がおしせまっていて、一番さくっとできる方法がDBにいれちゃうことだったので、@iszkがまたさくっとDBにいれてくれた。

 

ここでわりとぐっとスコアがあがる

 

ところがたまにfailするので原因をさぐって修正したらまたスコアがおち、じりじりと時間だけが過ぎていく。

とりあえず安定するようになったのが終了10分前。

 

いやこれ以上さわったら、絶対failするという恐怖に負けそこで試合終了。

 

とりあえずfailせずにスコアが最後にでたけど、30万円は夢と消えました><

反省点は多すぎて、まだ引きずってます。

 

当日、懇親会がおわったあとに、1時過ぎまで居酒屋で反省会でした。

まわりの人に喧嘩しているんじゃないかと勘違いされそうなくらい、白熱した反省会で、となりの若者との温度差がすごかった。

大人なのに泣くかとおもった。

 

とはいえ、久しぶりにいろんな人とあえたし、7時間がまさに精神と時の部屋で、得るもの多くて、大満足ですわ。

 

次回こそはもうちょっと上位にはいって、いや優勝できるように日々鍛錬をつみます!

 

MacでApacheのlog解析

WindowsだとApacheLogViewerとかが有名どころで、なんか解析したいときはこれをつかってたんですが、
今は会社の開発環境がMacなのでMacでいいのがないか調べてみた。


Macなんだしgrepとかawkとかなんかそのへんでがんばるという手もなくはないが、なんかapacheのログに
そこでがんばるのも何か方向性を見失っている気がしたので。


なかなか見つからなかったんですが、丁度いいのがありました!

visitors:
http://www.hping.org/visitors/index_jp.php

ちゃんとMacでも動いたん。

Redmineからのメールがメーリングリスト宛だと届かない

最初は全然理由がわからなくて詳しい人にヘッダをみてもらってやっとわかった。


原因としては以下のヘッダが含まれているのが原因

Precedence: bulk

元々はMLからMLへおくった際にループしないように暗黙的に捨ててくれという場合のために
使うものらしい。自動応答のメールとかも応答しないようになるのでRedmineの用途を考えると
まぁついているのが正解な気はする。


とはいってもメーリングリストをユーザのメールアドレスに設定しないといけない状態になったので困った。
とりあえずmailer.rbのこのヘッダを設定しているところをコメントアウトしたらちゃんと送信されるようになった!
めでたしめでたし。

gitでsubmoduleがある際にデプロイする方法

何も考えずデプロイしたらsubmoduleが空っぽなので調べた。


deploy.rbに以下を追加すればOK。

set :git_enable_submodules, 1

やったー

この辺が参考になりました。
http://github.com/guides/deploying-with-capistrano