コネヒト開発者ブログ

コネヒト開発者ブログ

実践してみてわかった、ビジネスチームと一緒に「技術で勝つ」チームを創る3つの方法

f:id:tatsushim:20160303174817j:plain

こんにちは

CTOの島田(@tatsushim)です。 今回はビジネスチームのメンバーと一緒に「技術で勝つ」チームをどう創るかという点についてご紹介させていただければと思います。

勝ちたい!

突然ですが、Webサービスを創るからにはそのサービスをNo.1のサービスにしたいと思っています。しかし数の勝負では大企業に勝てません。
日本の3人に1人のママが利用するmamari事業を支えているのはたった11名の社員です(2016年3月4日現在)。 少数精鋭で戦うために、弊社ではビジネスチームにも積極的に技術を使ってもらっています。 技術を使ってもらうメリットには以下のようなものがあります。

  • エンジニアとコミュニケーションしやすくなる
  • ビジネスissueからの要求でエンジニアのリソースを取ることが減る
  • 全員が「技術」で解決しようという思考になる

以下、実際に私達が今実践している3つの工夫について、解説していきます。

「技術で勝つ」チームを創る3つの方法

1.タスクリスト(issue)はGitHubで一元管理する

実は弊社は開発だけでなく営業のようなビジネスissueもGitHub上で管理しています。
具体的には

リポジトリ名 用途
Sales 営業系の案件管理や情報共有
Review 行った施策の振り返り
Direction サービス全体のディレクションや組織運営に関わること

というリポジトリが存在しています。 それらをGitHubにすることで以下のような恩恵がありました。

  • GitHub管理下なので、関連する開発issueにメンション(ref.)を飛ばしやすい
  • Assigneeを利用することで「誰がボールを持っているのか」を視覚化することができる
  • チャット(Slack)上で流れてしまっていたログをGitHubに記録として残すことができる

2.GitHubとSlackとの連携を密にする

GitHubに統一すると上記のようなメリットがある一方、人によっては少し慣れない部分もあると思います。 弊社ではHubotを通してGitHubへのアクセスをSlackベースにすることでそのハードルを下げています。

f:id:tatsushim:20160303175640p:plain

上記の例はcreate issue [リポジトリ名] issueのタイトルというコマンドでissueを作成し、そのissueに対してSlack経由でコメントしています。

3.SQLリストを作って共有する

f:id:tatsushim:20160304150645p:plain

メンバー全員にDBのリード権限を与えてデータを自由に見てもらっています。 そして一度「この集計データがみたい」というリクエストをもらったらそのSQLをエンジニアが書いて、それを用途別にGoogleSpreadSheet等にまとめています。 それらを参照しつつ、コピペして実行するだけでも「こんなデータが見れるんだ!」という体験がSQLへの関心を高めてくれています。

その結果今では自分でSQLを書き、Google BigQueryからデータを取り出して、エンジニアの手を借りず仮説検証を一人で回すメンバーも出てきました。

以上をやってみて、感じた変化

f:id:tatsushim:20160304161554j:plain

弊社のKPT MTG*1はフルタイムのメンバー全員で行っているのですが、 技術の話題を出してもスムーズに良いディスカッションができています。 その結果、問題点に対してエンジニアの枠内で最適化するのではなく、会社全体の問題として捉え解決に向けて取り組むことができていると思います。

おわりに

最後まで読んでいただき有難うございました。 今回触れたトピックについてより良い方法やご意見がある方は、はてぶコメントやTwitter等でいただけますと嬉しいです。

*1:KPTとはKeep/Problem/Tryの頭文字をとった、振り返りの為のフレームワークです

webpackを運用中のサービスに素早く導入する

f:id:dachi023:20160218152829j:plain

はじめまして!

2月から入社したエンジニアの安達(@ry0_adachi)です。

私からはwebpackを導入する際に行ったことをご紹介していきます。
webpackに乗り換えることのメリットって何だろう?という方や、運用中のサービスがGruntやgulp、browserifyで近いうちにwebpackに乗り換えたいなぁ、と考えている方の参考になれば幸いです。

webpackとは?

ざっくり言うと「コード間の依存を解決するためのツール及びビルドツール」です。
AはBに依存している、といった状態の時にAの書かれているファイルに対してBのファイルを結合して参照できるようにするのがwebpackの仕事です。

なぜwebpackなのか

なぜ私がwebpackを導入しようと思ったか、についてですが2つ大きな理由があります。

モジュールロードシステムの導入

ファイルを跨いだモジュールの呼び出しを行うための仕組みは他の言語では初めから当たり前のように実装されている機能ですが、残念なことにJavascriptに追加されたのは最近になってからのことです。
ES2015からはimport/exportが使えるようになっていますが、現在Connehitoで運用しているサービスのコードはES5で実装されています。
そこでwebpackを利用することでWebアプリでもモジュールロードを可能にして依存性を自動で解決しよう!と考えました。

複数のファイルをまとめて出力したい

browserifyというwebpackに似たツールがありますが、こちらは1回のビルドで1つのファイルしか出力できません。
今回は複数のファイルを出力したかったこともあり、複数ファイルの出力が可能なwebpackを選びました。

現状を理解する

webpackに限ったことではありませんが、既存のサービスに対して手を加える場合、どのような作りで何をしているのか、を理解している必要があります。
まずは手を動かすよりも先にコードをしっかりと読むことにしました。

コードを読んで分かったこと

  • CommonJS, AMDに対応していない
  • 外部ライブラリはパッケージ管理をしていない
  • gulpでファイルを結合して圧縮をかけている

上記がwebpackを導入する前の状態でした。
また、既に運用中であることや、まずは導入してから徐々にwebpackで管理する領域を広げていこうという思惑もあったので、今回は Javascriptをwebpackでビルドする ことをゴールにします。

今回やること

  • CommonJSに対応させる
  • ライブラリをnpmでパッケージ管理する
  • webpackでファイルを結合して圧縮をかける

いざ、webpack

それでは導入にあたって行ったことを順を追って説明していきます。

1. CommonJSに対応させる

CommonJSというのはJavascriptの標準APIの仕様を策定している文書、プロジェクトのことです。
その中でモジュールのロードはrequireとexportsでやりますよ、と定義されています。
そして、これはES2015のimportとexportに非常に似ています。そんなこともあり今後ES2015に書き直した時に修正が簡単なようにCommonJSのモジュールロードの仕様に対応することにしました。
やったことは となっているコードを とするだけです。非常に簡単ですね!
これだけ?と思われるかもしれませんが、これだけです。モジュールロード最高ですね。
この作業をファイルの数だけ繰り返してmodule.exportsに既存のコードを詰め込んでいきました。
module.exportsを書いたコードはrequireを使うことで呼び出せるようになります。

2. ライブラリをパッケージ管理する

使っているライブラリも一緒にrequireしたいのでnpmで管理することにしました。
ConnehitoではBackbone.jsを採用しているのでnpm経由でインストールしてみます。

# 依存するunderscore.jsも一緒に入れます
$ npm install --save underscore backbone

インストールが無事終わったらrequireを使って呼び出すコードを書きます。 これでBackbone.jsとunderscore.jsが使えるようになりました。
他にも使用しているライブラリがいくつかあったのですが、そちらも同様にnpmで入れ直してrequireする、とするだけでした。 本当に良い時代です。これでライブラリがパッケージ管理されるようになり、簡単にrequireもできるようになりました。

3. webpackでファイルを結合して圧縮をかける

いよいよgulpのビルドタスクをwebpackへ移行します。
とりあえずwebpackをインストール。

$ npm install -g webpack

ファイルの結合に関してはbrowserifyのように依存解決と一緒にやってくれるので特にやることはありません。
というわけで、基本的な設定と圧縮するための設定を用意してあげます。 圧縮するだけならこれだけでOKです!短くていいですね!
そして、ついに実行する時がきました!webpackコマンドを叩いてみましょう!

$ webpack

2つのビルドされたJavascriptファイル(bundle-hello.js、bundle-backbone.js)とそれぞれのソースマップが無事生成されてwebpack移行第1弾が完了です!
他にもファイル監視やES2015のトランスパイルなど、webpackにやってもらいたい仕事がたくさん残っているので第2弾も現在計画中です...!

まとめ

Javascriptをビルドするだけ、という形で導入してみました。
今回はサンプルコードでのご紹介だったので直したのは一箇所でしたが、実際はexportsをサービス全体に埋め込んでいったので、今はどこからでもrequireで使いたい機能が呼び出せちゃいます。
初めから全てを移行するのではなく少しずつ移行することで敷居も下がって導入しやすいので非常にオススメな方法です!!


webpackとES2015を使ってJavascriptを書きたい!
そんなフロント好きなエンジニアの方はConnehitoへ遊びに来て私と今後のモダンなフロントについて語り合いましょう!

www.wantedly.com

PHP7にCakePHP2.xが来るぞ!!!!!

f:id:connehito:20160205104322j:plain

来るぞ!!!

ご無沙汰しております。
コネヒトでPHPを書いている金城 / @o0h_です。
タイトルの通りですが、CakePHP 2.xが次期バージョンの2.8でPHP7に対応!(!)という話を小耳に挟んだので、喰いついてみました。

PHP7 Compatibility!!!

f:id:connehito:20160204202829p:plain

CakePHP、PHP5時代と次世代への断絶

新しい世界・・・・怖いのかな・・・めちゃくちゃ大変なの??
という事には、(実際に使うかは別としても)興味を持つ人も多いのではないかな!!!と思いました。
かくいう私もその1人、さればとGithubを眺めながら「何が起きたか」を探って参りました。
CakePHPが通った道のりを紐解くことで、「PHP7に飛び乗るための覚悟」を少し育めたらなと思います。

続きを読む

まいにちUX - 新年からはじめる1DAY1UXの習慣 -

f:id:connehito:20160112191659p:plain

あけましておめでとうございます! 新年1発目の記事は、デザイナーのきよえし(@kiyoe_furuichi)が担当いたします。今年もどうぞよろしくお願いします!

さて、前回の私の記事では「チーム開発でのおもてなし」について触れましたが、今回は12月に登壇させていただいたUX MILKさん主催の「ゆるく学ぶUXイベント UX JAM 4 - UX Girls Special -」にてお話した内容をまとめてご紹介したいと思います。

UXことはじめ

突然ですが、みなさん「共感力 (Empathic ability)」という言葉をご存知でしょうか? UXをデザインする上で大切な力だと言われていて、私も日々、機能の新規開発やUI設計などを行っている中で共感力の重要性はとても感じます。

ざっくり説明すると、共感力は「他人の感情を理解する力」という意味を持ちますが、UXでの共感力は「サービスを利用するユーザーさんの視点と同じ目線に立ち、目的に達するまでの過程で感じる感情を自分ごとのように感じ取ることのできる力」のことをいいます。
この力を高めることにより、ユーザーさんにより近い感覚でサービスに関する問題や発見・気づきを得ることができ、より良いサービス体験へ改善するためのアイデアの質を向上させることができます。

今回はその「共感力」を高めていくためにはどうすれば良いのかを私なりに考え、実践している内容をまとめてみました。

「共感力」の必要性

ユーザーさんがより便利に・気持ち良くサービスを利用するための機能をリリースしたにも関わらず、想いに反しフィードバックではネガティブな意見が多かった。。なんてことはあったりしますよね。そんな時、設計・デザインに関わった自分はこう思うわけです、「共感力が足りてなかった…」と。ユーザさんの視点になりきれずに良いものを作ろうとすると、こういった失敗につながることがあります。
そんな共感力は、理論やツールの使い方うんぬんではなく感覚的なものですので、経験を積み、地道にコツコツ身につけていくものだと個人的に考えています。とにかく自らが多くのUXに触れてみることが身につけるための唯一の近道なのかなと思います。

1DAY1UXの習慣化

「UXに触れる」というアクションは、実はすでにみなさんも毎日の生活の中で行っています。 例えばコンビニでコーヒーを買う、定食屋さんでランチを食べるなど。WEBを介さなくても世の中のサービスを利用するシーンにおいてUXという考え方は必ず存在します。
そこで私はそれを1つ1つ意識し体験することで「共感力を鍛えるトレーニング」になるのではと考え、1日に1つでもUXを体験する「1DAY1UX」の習慣化にチャレンジしてみることにしました。

毎日考える工夫

毎日続ける工夫として、迷ったのがUXのアウトプット方法です。 UXを可視化するツールとして、有名なものでいうとカスタマージャーニーマップ(以下CJM)がありますが、事細かにまとめると数時間かかってしまうので毎日は続かない。。と感じ、自分なりに毎日続けられる工夫を考えてみました。そこで最近はじめた小さな習慣をご紹介したいと思います。

まいにちUXノート

f:id:connehito:20160114091526p:plain

「まいにちUXノート」というものを作ってみました。普段の生活で体験したUXを書き留めておくためのノートです。 CJMを少しシンプルにしたもので、5分でユーザーさんの体験を可視化できるようにしました。難しいことを考えずスラスラと書くことができるので、これなら毎日続けられそうです!

書き方

ノートは以下のようになっていて、CJMと同じく「行動」と、それぞれの課程で感じた「気持ち」を書き、その下に、時々の「感情の変化」を5段階で書けるようにしました。

f:id:connehito:20160112170714p:plain

具体例を見ながらイメージを掴んでいただければと思います。

例1 とある日のコンビニUX -お弁当編-

f:id:connehito:20160112152727p:plain

コンビニに入り、商品を探す。そして手に取ったお弁当をレジで購入し、温めてもらう。 このように普段の何気ない行動を書き出していきます。

例2 とある日のコンビニUX -コーヒー編-

f:id:connehito:20160113235243p:plain

次はコーヒーを買うことをゴールとした場合に、途中で離脱したパターンです。 お弁当編も然り、レジに並ぶ際に混んでいるとネガティブな感情になり買う気持ちが薄れてしまっているようです。

例3 とある日のランチUX -パスタ屋さん編-

f:id:connehito:20160113234719p:plain

ふらっと散歩した際に見つけたパスタ屋さん。 接客から商品まで大満足のお店でした。ご飯屋さんが比較的UXを考える上で分かりやすいかもしれないですね。

配布してます(pdf形式)

「まいにちUXノート」のデータは以下にて配布しています。使ってみたい!という方はどうぞ!
Dropbox - まいにちUXノート.pdf

やってみて思ったこと

1DAY1UXを習慣にしてから、自然と意識して自分の行動や気持ちの変化を考えるようになったのと、それから、私がもしこのサービスを提供する側だったらここはこう解決したい、といったところを想像するようになりました。
まだこのトレーニングが実際に生かされているかまでは分かりませんが、この取り組みを続けていくことより「共感力」を高めることはできると感じたのと、こういった小さな積み重ねが大事なので、続けていこうと思います!

さいごに

いかがでしたでしょうか。
今回私がご紹介した「まいにちUXノート」を利用した1DAY1UXの習慣のように、みなさんも日々の生活の中でUXを考える工夫をしながら、こつこつ「共感力」を高めてみませんか?もっともっと、ユーザーさんの目線に近い視点でサービスをより良くするデザイナーを目指していきましょう!

それでは、2016年もよろしくお願いします!
最後まで読んでいただきありがとうございました!

リンク



コネヒトではエンジニアさん、デザイナーさん、デザイナーさん、デザイナーさんをWANTEDしています! 一緒に300万人が使うサービスのUXをより良くしていきませんか?
www.wantedly.com

スタートアップ入社1ヶ月で実践した「低コストでデキる!開発を加速させる情報共有」の始め方

f:id:fortkle:20141210080057j:plain

こんにちは!今月12月から中途入社したエンジニアの高野フォートクル (@fortkle) です。

今日は、私が入社して実践した情報共有に関する取り組みのうち、効果があったものを「『低コストでデキる!開発を加速させる情報共有』の始め方」と題して共有したいと思います。

tl;dr

  • 関係者全員が情報共有ツールを使える環境を整える
  • 「この1ページだけ見ればOK」という情報の集約場所を作る
  • slackの分報でそのページの質をチェックし、足りない部分を更新してメンテナンスする

Connehitoの状況

まずは私が入社した直後のConnehitoの状況を列挙します。

人数 CTO 1名 + 開発者(エンジニア・デザイナー) 3名
ドキュメント GithubのPRに詳しく仕様は書かれているが、ドキュメントとしてまとめていない
情報共有
ツール
Slack, Docbase(あまり活発には使われていない, 全員分のアカウントがない)

当時は人数も少なく、1つのプロダクトにつき担当者が1~2名だったので、自分自身が知っていれば全く問題がありませんでした。つまり、情報共有の必要性が低かったのです。

また、スタートアップのため完璧なドキュメント作成はしない意思決定をしており、ユーザーに価値のあるサービスの提供を優先して日々の開発業務を進めていました。

これから発生が予想される問題

Connehitoが運営しているママリママリQは、いま物凄いスピードで成長をしており、やりたい施策も日々増えてきています。それに伴って開発者が増えていくことは容易に想像できますが、現状の情報共有のままでは今の開発スピードを維持したまま開発チームをスケールさせることが難しくなる事が予想されます。

具体的には下記のような問題が発生する可能性があります。

  • 会社の 開発フローや開発文化を理解 するのに 時間がかかる
  • 既に効率化された方法があるのに 共有されなかったせい無駄な時間 を使ってしまう
  • 新しく入ってきた人が、 「なぜ」 現在の実装・設計になっているか理解できない  

「開発を加速させる情報共有」の始め方

上記の問題に対して、あまりコストを掛けずに効果のある施策をできないか考えた結果、下記取り組みを実施し効果がありました。順を追って説明します。

1. 情報共有のための環境を整える

チャットツールがいかに有用か、という話は他の記事に譲るとして情報共有ツールを使うことは非常に重要です(ここでいう情報共有ツールというのは、Qiita:Teamやesa.io、Docbase等のブログとWikiを組み合わせた様なツールをイメージしています)。

Connehitoでは以前からDocbaseを使っていたものの、契約プランの関係で全員にアカウントを発行することができていませんでした。

情報共有ツールは一部で導入しても効果が出にくいので、私が入社して数日経ったタイミングでCTOに相談し、 開発者全員分のアカウントを発行できるプランまでアップグレード してもらいました。
 
~余談~
情報共有のもたらすメリットから考えると月額数千円は低コストだと思いますが、このあたりの交渉が難しいこともあると 思います。その場合は私も参加している「情報会議」という情報共有のコミュニティで話し合いがされているので、ぜひそちらの情報を御覧ください。

さて、こうしてConnehitoでは開発者全員がslackとDocbaseを使えるという環境が整いました。

2. 「この1ページだけ見ればOK」という情報の集約場所を作る

言葉より先に見てもらったほうが早いと思うのでまずはご覧ください。

f:id:fortkle:20151224155818p:plain

こちらはDocbaseに用意した、いわば「Connehito開発まとめページ」です。

開発に関するドキュメントや日々の業務で使っているツールなど、入社時に知っておきたい情報を全て網羅する目的で作成されています。 またそれだけでなく、日々の開発で使いそうな便利なリンク集やテスト用アカウントの共有などにも活用されています。

このページの良い所は 既存の資産を活用できる点です。

例えば、Connehitoではコードレビューを投資と捉え、時間をかけてしっかりと行っているため、Github上で行ったPR/コードレビュー周りの情報がそのままドキュメントとして有用なケースが多くあります。

新たに仕様書を作成するのではなく、このまとめページからGithubのPRに「仕様書/設計書」としてリンクを貼ることで、新しく入ってきたエンジニアが「PRに仕様が書いてないか検索してみよう」と思う状態を作り出すことができます。

新しく入社した開発者はこのページを一通り見ることで、頭のなかにConnehitoでの開発に関する情報の「インデックス」を作ることができるのです。

3. "分報"を活用して、情報共有を促し、陳腐化を防ぐ!

"分報"という手法をご存知でしょうか?少し前にバズっていた下記記事に詳細が書かれています。

c16e.com

私が入社してお試しで導入してみたところ、記事にあるように「10分以内に課題が解決できる」や「個人の学びが自然とチームに広まる」など効果を感じることができました。また、記事とは別にもう1つ効果がありました。

それは、「まとめページの質をチェックすることができる」 点です。

新しく入ってきた人は、個人の分報チャンネルを渡され、まとめページの「はじめての方へ」の項目をこなしていきます。当然、ドキュメントは書かれた瞬間から古くなっていくので、項目通りに進めていて問題が発生することがあります。

経験的にこういったとき、これまではたとえ問題が発生していたとしてもそのまま放置されることが多かったのですが、分報を導入することで作業が見える化され、「質問するほどではないけど詰まったところ・違和感を感じたところ」が共有されるようになりました。

その結果として、「○○さん、その詰まったところの更新おねがい!」とか「△△の記述が足りなかったので追記しておきました!」といったやり取りが行われるようになりました。

これで、低コストでドキュメントが陳腐化することをある程度防ぐことができるようになりました。

まとめ

「ドキュメントを残す」という作業はたしかに重要ではあるものの、そのコストは意外と大きなものです。特にスピード感を持ってフットワーク軽く進んでいかないといけないスタートアップにとって、その作成コストはある意味、死に直結する可能性もあり、無視できないものです。

一方で、成長途中のスタートアップにとって組織の拡大と情報共有の課題は解決すべき問題です。今回はそういったスタートアップでも出来る低コストかつ効果のある手法の1つだと思います。

同じような問題を抱えている方はぜひ試してみてください!


「わたしはこんなやり方でやってましたー!」というアツイ情報共有トークをしたい方はぜひ一緒にランチでも行きましょう!お待ちしております!

iOSアプリをローカルサーバーと通信させて実機デバッグする方法

f:id:connehito:20151210171608p:plain

お久しぶりです、社内で「ラブライブ、紅白出場おめでとうございます」と声をかけられる田村(@Utmrer)です。

私はiOS/Androidのクライアントサイドとサーバーサイドの実装をどちらも担当しているのですが、「ローカルサーバーで開発してるAPIを使いながら、アプリも開発する」ということをよくします。

その時に、アプリ側で通信するhostを本番環境のhostから自分のPCのローカルIP(192.168.1.XX, 10.0.1.YYなど)に変更してローカルサーバーとアプリを通信させていたのですが、IPv6サポートの流れからか、iOS9では出来なくなりました。*1

ローカルサーバーと通信出来ないとぶっつけ本番でデプロイする恐怖や、変更する度に開発環境にデプロイする煩わしさと戦わなければいけません。
それらを避けるためにiOS9でもローカルサーバーと通信する方法をご紹介します。

TL;DR

  • IPアドレス指定での通信が出来なくなったのでローカルホスト名を使う
  • hostnameを使ってhostの設定を自動化すると楽ちん
  • ATSの設定もScriptで自動化出来る

Macのローカルホスト名を確認しよう

f:id:connehito:20151208184424p:plain Macのローカルホスト名はシステム環境設定アプリから共有を選択すると表示されます。
このnozomi.localの部分があなたのローカルホスト名で、アプリが通信するhostです。

VagrantやMAMPで起動してるローカルサーバーのlocalhost:port(ex. localhost:8888)へ、Macと同じローカルネットワーク上のiPhoneのSafariからnozomi.local:8888という感じでアクセス出来るかと思います。

iPhoneからローカルサーバーと通信する

前項で確認した*.localのhostを本番環境のhostと置き換えればアプリとローカルサーバーが通信する準備が整ったのですが、App Transport Securityの影響でAllow Arbitrary Loads=YESにしてない場合は*.localのローカルサーバーとは通信は出来ない状態でしょう。
この設定も自動化して行きたいので環境別のhost設定からATSの設定まで自動化して行きましょう。

Info.plistにhostを持たせる

まずはこのようにInfo.plistに本番環境のhostを設定しておきましょう。 ServiceHostというKeyにexample.comという本番環境のhostが定義されています。

f:id:connehito:20151208191419p:plain

このServiceHostの値をビルド時に自動で設定します。サンプルコードではdiffを出したくないのでPreprocess Info.plist Fileを有効化しました。 Preprocess Info.plist Fileについて詳しくはこちら

ローカルホスト名はhostnameコマンドで取得できるのでBuild PhasesでScript追加してDebug Configurationの時だけInfo.plistを上書きするようにします。

Preprocessed-Info.plistを編集しているのでビルドの度にdiffが出てイライラすることもありません😊

そしてこのようにInfo.plistからhostを呼び出せばConfiguration毎に異なるhostへアクセス出来ます。

ATSの設定に*.localを含める

f:id:connehito:20151208200857p:plain

上記のようなATSの設定をしている場合、*.localはATS例外に含まれていないので通信できません。
*.localのhostもScriptでATS例外に追加しましょう!

上記のScriptをBuild Phasesに追加すると*.localもATS例外に追加出来ます。 Delete処理が入っているのはDerivedDataにPreprocessed-Info.plistのキャッシュが残っている場合があるからです。

ATSの環境別設定とPlistBuddyについてはこちらもご覧ください。 tech.connehito.com

今回ご紹介した内容を設定してあるサンプルプロジェクトも作ってみたのでもし良ければご覧ください。 特にBuild Phases辺りが肝です。 github.com

終わりに

以上で「iOS9でもローカルサーバーと通信する方法」&&「環境別の設定の切り替えを自動化」は終わりです。
「ナニソレイミワカンナイ」なところや、もっと簡単な方法があるよ〜って方は是非教えて下さい!ランチしながらPlistBuddyについて熱く語りましょう。

【1コマンドでOK】MySQLユーザーに贈る、スロークエリ解析の始め方

f:id:connehito:20151126162031j:plain

こんにちは!

CTOの島田(@tatsushim)です。前回の私の記事ではインフラ構成について触れました。
インフラを構築したらその運用が必要になりますね。今回は社内で行っているDBのスロークエリ解析について紹介したいと思います。

時間がない人向けに要点を3つにまとめると

  • ママリでは定期的にクエリの見直し時間をとっている
  • その理由は、レスポンスタイムがユーザーの滞在時間に大きく影響するため
  • pt-query-digestを使うとカジュアルにクエリログを解析できるから初心者にもオススメ

という感じです。それぞれについて解説していきます。

定期的にクエリの見直しをする

現在ママリでは、定期的にクエリの見直しをする時間を開発スケジュールに入れています。
それは、レスポンスタイムがユーザーの滞在時間に大きく影響するためです。
ORマッパーでコードを書いていると気づかないうちにスロークエリを発行してしまいがちなので、 定期的に対策を行うことで問題を未然に防いだり、コードを書く際にも発行クエリへの意識が向くようになりました。

スロークエリを解析してみる

元々MySQLにはスロークエリの閾値を決めて吐き出す機能がありますが、
どのクエリから対策をすれば良いかの取捨選択を行う際に、そのログを目grepするのは辛いので社内ではpt-query-digestを利用しています。

pt-query-digestとは

mysqlのslow queryのログ等を集計し、改善が必要なクエリを上位に並べてくれるツールです。

pt-query-digestで解析する

インストール

  • pt-query-digestコマンドを使うために、percona-toolkitをインストールする
  • mac環境でbrewが入ってれば、コマンドは以下のみ
brew install percona-toolkit

実行する

  • 以下コマンドで集計結果が出ます*1
  • pt-query-digestコマンドの引数にはスロークエリのログ(ここではmysql-slowquery.log)を渡します。
pt-query-digest mysql-slowquery.log

結果を見てみる

  • 結果には改善が必要なクエリが上位に出力されます。なので基本は上から潰していきます。
  • 頻度や実行時間を確認することができます。以下が1つの具体的な例です。*2
Attribute    pct   total     min     max     avg     95%  stddev  median
============ === ======= ======= ======= ======= ======= ======= =======
Count         19      44
Exec time     25     75s   514ms      3s      2s      3s   956ms      2s
Lock time      1     7ms   128us   263us   155us   214us    37us   131us
Rows sent     85   2.77M  20.33k 105.50k  64.42k 101.89k  38.80k  92.42k
Rows examine  26  36.57M 243.30k   1.40M 851.03k   1.39M 543.75k   1.03M
Query size     1  72.24k   1.64k   1.64k   1.64k   1.61k       0   1.61k
String:
Databases    foo
Hosts        10.1.0.193 (8/18%), 10.1.3.127 (6/13%)... 
Users        bar
Query_time distribution ← クエリの実行時間の分布
  1us
 10us
100us
  1ms
 10ms
100ms  ############################################
   1s  ################################################################
 10s+
  • このサンプルの場合、1sを超えることが多いクエリになっていますね。ここを改善すれば大きな改善になると思われます。

おわりに

いかがでしたでしょうか? インストールから実行まで2コマンドでできるので、カジュアルにトライしてみると今まで見落としていたスロークエリが見えるかもしれません。
弊社ではスロークエリを減らし、レスポンスタイムが改善されたグラフを見て一緒に(・∀・)ニヤニヤしたい方を募集中です。

参考サイト

pt-query-digest

*1:--typeを指定することで、PostgreSQLのログ等にも対応が可能です。詳しくは参考サイトをご覧ください。

*2:中身はサンプルです。実際の解析結果ではありません