production.log

株式会社リブセンスでエンジニアをやっている星直史のブログです。

エンジニア版 人を動かすだと感じた TeamGeekを読みました。

最近はコードより人とやりとりすることが多くなってきたので、TeadmGeekを読んでみました。
今回はその感想を書きたいと思います。

エンジニアが他人とうまくやっていく知見が詰まった本

TeadmGeekは、チームで仕事をするプログラマーに向けた本です。
また、他人とうまく仕事をするということにフォーカスを当てているので、プログラムの話は一切出てきません。

この本は6章立てです。

  • ソフトウェア開発はチームスポーツである
  • チームの文化を作る効用
  • リーダーの必要性
  • 良くない振る舞い(行動的な意味)を排除する方法
  • 開発チームが属する組織に対しての操作技法

一人のエンジニアとしての心構えとして有名な3本柱、HRT(謙虚、尊敬、信頼)の重要性や、
チーム文化の重要性、組織に対しての行動の仕方などが書いています。

HRT(謙虚、尊敬、信頼)

チームで開発を進めていくと衝突する、あらゆる人間関係は、謙虚、尊敬、信頼の欠如により、発生するものだと書かれています。
謙虚、尊敬、信頼とだけ聞くと、自らの意見を殺た方がよいのか?と思ったのですが、そういうことではなく、
チームとしてよりよい成果を得るための効率的なコミニュケーション方法だと学ぶことができます。

本のなかでは、実際の事例を基に、テクニックを活かすとこうなる!というような構成で書かれています。

この本を読んだ後に思ったのは、
HRTを知らない人(例えば超絶自分勝手な人)に対峙した場合に、一歩引いた視点で接することができるのではないかと思いました。
本書の狙い通り、なるべく衝突を回避すべく、落ち着いて誠実に対応できるでしょう。

チームには文化が必要

開発チームが共有する文化(経験・価値・目標)は、効率的なコミニュケーションや、エンジニアリングに必要ということはなんとなくわかっていて、本にも書いていたのですが、
発見があった点は、新しく入ってきたメンバーに対しての抵抗力にもなるというところでした。

文化がないチームに新しくメンバーが入ってきた場合、入ってきたばかりのメンバーの声が強ければ、
一瞬にしてその人価値観が文化になってしまう恐れがあると書かれていました。

発足してから時間が経ったチームには、文化を明文化する必要性が見えてきたのは良かったです。

チームにはリーダーが必要

この本では、リーダーに"なってしまった"人のための行動のコツについても書いてあります。 具体的には下記のことが書かれています。

  • 初期の心理状態
  • 陥りやすい悩み
  • 心構え
  • エンジニアとリーダーは仕事が違うこと
  • 行動のアンチパターン
  • 良い行動パターン

リーダーは、チームの触媒になるよう、目標を掲げたり、メンバーやチームの成功と幸せを考えたりと、
コードを書いていた時とは違う時間の使い方をしなければならないと、この本でも書いていました。

マネージャー向けに書かれた本でも書かれていたのは、以前のエントリでも学びましたが、
エンジニア向けに書かれたこの本でも同様のことが書かれていたので、妙な納得感がありました。

良くない振る舞い(行動的な意味)を排除する方法

リーダーからもう一歩上の視点になったことについても書かれていました。
良くない振る舞い(行動的な意味)を排除する方法*1と、
開発チームが属している組織に対しての行動についてです。

基本的には、HRTの精神で臨むことを前提として書かれています。
良くない振る舞いに対しては、相手の想いと伝え方を最大限考え、対処するのがベストプラクティスだと学べます。
また、良くない振る舞いをしている人であったとしても、基本的には自分の中での正義があるので、
そのベクトルを揃えるために、チームの文化も必要だと感じました。

組織に対しての行動

エンジニアは、より良いコードを書くことばかりに集中していてはダメだと書いています。
組織でうまく働くことについても書かれています。

本を読んで感じたのは、入社した瞬間の信頼貯金0の状態から、組織に信頼され、自分の意見や運命をコントロールできるポジションにつくまでの行動について書かれていると思いました。

エンジニアとしては、リリースよりもリファクタリングや技術的な解決に目が行きがちだが、
組織としては、サービスのローンチやユーザーに与えるインパクトの方が圧倒的に価値があることを、認めるべきと書かれています。

エンジニアは開発するだけが全てではなく、客観的(会社やビジネス側から見る視点)に見た事実を理解した上で、技術を活かすアプローチではないと、苦しくなると、だいぶ生々しいことが書かれています。

まとめ

この本はエンジニア版の人を動かす*2だと思いました。
HRTを基本原則として、チームで成果を出すための知見が詰まった本なので、ほぼ全てのエンジニアにお勧めできる本だと思います。

また、リーダーとしての視点や、エンジニア個人として組織内での動き方についても書かれているので、"チームで成果を出す"という点以外でも十分学びを得られる本だと思います。

*1:本の中では有害な人の追い出し方と書いていますが、有害な人=特定の個人と勘違いしやすいので、良くない振る舞い(行動的な意味)を排除する方法としています。

*2:D・カーネギー

Solr 4.10.4でSolrCloudを試してみました。

ピクスタの開発部で開発合宿を開催したので、
Solr4からの新機能であるSolrCloudを試してみました。
前回の記事はこちらです。

また参考にした書籍は↓こちらです

分散インデクシングやレプリケーションを自前で構築してもいいけど・・・

前回の記事では、インデクシング時の偏り、エラーによる単一障害によるシステム全体のダウンなどを挙げました。
SolrCloudは、分散インデクシングやレプリケーションのメリットを活かしつつ、
これらの問題を回避できる分散環境の仕組みを提供します。

具体的にはZooKeeperというものが組み込まれており、それがnodeのステータス管理、分散検索時のフェイルオーバー、単一障害点などをなくす仕組みになっています。

今回は、シャード数2, レプリケーション数2の4台構成のシステムを想定して、環境を構築していきます。

まずは各nodeの基となるデータを作成します。

$ cd ~/solr-4.10.4/
$ cp -R example/ node1
$ cp -R example/ node2
$ cp -R example/ node3
$ cp -R example/ node4

SolrCloudの起動

node1を立ち上げる際にzookeeperの起動と設定も同時に行います。

$ cd ~/solr-4.10.4/node1
$ java -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=myconf -DzkRun -DnumShards=2 -jar start.jar

注意する点が一点あります。
書籍では
java -DzkRun -DzkHost=http://localhost:9983 -Dbootstrap_conf=true -DnumShards=2 -jar start.jar
と書いてあるのですが、bootstrap_conf=trueだけでは、zookeeperがconfigファイルを読み込めないので、
bootstrap_confdirを設定する必要があります。

続いて、node2, node3, node4をzookerrperの管理下で起動します。

$ cd ~/solr-4.10.4/node2
$ java -Djetty.port=8985 -DzkHost=localhost:9983 -jar start.jar

$ cd ~/solr-4.10.4/node3
$ java -Djetty.port=8987 -DzkHost=localhost:9983 -jar start.jar

$ cd ~/solr-4.10.4/node4
$ java -Djetty.port=8989 -DzkHost=localhost:9983 -jar start.jar

node4まで立ち上げたらSolrCloud(zookeeper)が起動しているhttp://localhost:8983にアクセスしてみましょう。
zookeeperを立ち上げた状態であれば、サイドバーにCloudというタブがあるはずなので、表示してみましょう。

f:id:watasihasitujidesu:20160124011240p:plain

設定した通り、シャード数2, レプリケーション数2の構成が出来上がりました。
ここまで簡単に環境ができるとはあっぱれ。

また、SolrCloudではRest APIを提供しており、管理画面からだけではなく、CLIで設定を変更できます。
一覧や詳細はこちらを参照してみてください

CLIを使用しても、レプリケーション数やシャード数を変更することができるので、
サーバー監視ツールからのalertなどで、状況に応じて柔軟にスケールすることができます。

今回の開発合宿では手元の書籍がSolr4系だったので、それで進めてきたのですが、
今後は5系でも同様の構成が作成できるように学んで行こうと思います。

Solr 4.10.4でレプリケーション(master-slave構成)を試してみました。

ピクスタの開発部で開発合宿を開催したので、
そのネタとして、Solr4.10.4でのレプリケーション(master-slave構成)を今更ながら試してみることにしました。
前回の記事はこちらです。

また参考にした書籍は↓こちらです

レプリケーションの設定(master)

$ cp -R solr-4.10.4/example/ solr-4.10.4/master1
$ cd ~/solr-4.10.4/master1
$ vim solr/collection1/conf/solrconfig.xml

上記ファイルを開いたら、下記のように編集します。

  <requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="master">
      <str name="replicateAfter">commit</str>
      <str name="replicateAfter">optimize</str>
      <str name="replicateAfter">startup</str>
      <str name="confFiles">schema.xml,stopwords.txt</str>
    </lst>
  </requestHandler>

こちらの設定はcommit, optimize, 起動直後にslaveに対してレプリケーションを実行するという設定です。

続いて、Slave側の修正もしましょう。

レプリケーションの設定(slave)

$ cp -R solr-4.10.4/example/ solr-4.10.4/slave1
$ cd ~/solr-4.10.4/slave1
$ vim solr/collection1/conf/solrconfig.xml

上記ファイルを開いたら、下記のように編集します。

  <requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="slave">
      <str name="masterUrl">http://localhost:8983/solr/collection1</str>
      <str name="pollInterval">00:00:30</str>
    </lst>
  </requestHandler>

こちらは、masterURLを指定しており、ポーリング間隔を30秒にしています。

これでレプリケーション(master-slave構成)設定は完了です。
それぞれ起動してみましょう。

$ cd ~/solr-4.10.4/master1
$ java -jar start.jar
$ cd ~/solr-4.10.4/slave1
$ java -Djetty.port=8985 -jar start.jar

http://locahost:8983/solr/#/にアクセスし、
collection1のreplicationタブを確認すると、Disable Replicationというボタンが表示されていることが確認できます。
f:id:watasihasitujidesu:20160124001449p:plain

続いてslaveの確認をしてみましょう。
http://locahost:8985/solr/#/にアクセスし、
collection1のreplicationタブを確認すると、Replication Nowボタン、Disable Polingボタンが表示されていることが確認できます。
f:id:watasihasitujidesu:20160124001453p:plain

これらのボタンを押すと、ボタンのキャプションの通り、下記の動作ができます。

GUIでサクッとレプリケーションの確認ができるなんて3系のadmin画面を知っている身からすると、
なんだか嬉しいような切ないような気持ちになりますね。
甥っ子がいつの間にか大人になっていた的な。
(個人的には3系の無骨な画面も好きだったりします。)

今回で分散インデクシングレプリケーション(master-slave構成)を学んだので、
お次は待望のSolrCloudを試してみましょ〜!

Solr 4.10.4で分散インデクシングを試してみました。

ピクスタの開発部で開発合宿を開催したので、
日頃からお世話になっているCloudSearchの内部を少しでも知るべく、
Solr 4から登場した分散インデクシングを今更ながら試してみることにしました。

参考にした書籍は↓こちらです

合宿中に検証したことは下記の通りです。

今回の記事では

  • 分散インデクシング(Sharding)

この部分について触れようと思います。

Solr 4.10.4を配置

$ wget http://ftp.jaist.ac.jp/pub/apache/lucene/solr/4.10.4/solr-4.10.4.tgz 
$ tar zxvf solr-4.10.4.tgz

分散インデクシング(Sharding)

$ cp -R solr-4.10.4/example/ solr-4.10.4/master1
$ cp -R solr-4.10.4/example/ solr-4.10.4/master2
$ cd ~/solr-4.10.4/master1/
$ java -jar start.jar &
$ cd ~/solr-4.10.4/master2/
$ java -Djetty.port=8985 -jar start.jar &
$ cd ~/solr-4.10.4/master1/exampledocs
$ java -Durl=http://localhost:8983/solr/collection1/update -jar post.jar [a-m]*.xml # master1 にインデクシング
$ cd ~/solr-4.10.4/master2/exampledocs
$ java -Durl=http://localhost:8985/solr/collection1/update -jar post.jar [n-z]*.xml # master2 にインデクシング

結果

# ipad solrという文字列を検索
$ curl "http://localhost:8983/solr/collection1/select?shards=localhost:8983/solr/collection1,localhost:8985/solr/collection1&indent=true&q=ipod+solr" | grep '<str name="id">'
    <str name="id">IW-02</str>
    <str name="id">F8V7067-APL-KIT</str>
    <str name="id">SOLR1000</str>
    <str name="id">MA147LL/A</str>

良い感じに4件取得できました。
query stringのshards=localhost:8983/solr/collection1,localhost:8985/solr/collection1という部分で、
分散インデクシングされたdocumentをまとめて取得しています。

念のため本当にまとめて取得してきているか確認してみましょう。

$ curl "http://localhost:8983/solr/collection1/select?indent=true&q=ipod+solr" | grep '<str name="id">'
    <str name="id">IW-02</str>
    <str name="id">F8V7067-APL-KIT</str>
    <str name="id">MA147LL/A</str>

$ curl "http://localhost:8985/solr/collection1/select?indent=true&q=ipod+solr" | grep '<str name="id">'
    <str name="id">SOLR1000</str>

port番号8983と8985に同一のクエリを投げた結果です。
8983からは3件, 8985からは1件取れてきたので、合計4件となり、分散インデクシングに成功しています。

Solr3時代ではレプリケーションしてLBで振り分けなければいけなかったものが、
シャーディングすることによってサーバーあたりのindex容量が下げられるのはだいぶ大きいと思いました。

注意すべき点

ただし、documentをindexに登録する際に、サーバーによって偏りがあると、
システム全体の検索応答速度は、最もレスポンスが遅いサーバーに引っ張られます。
そのため登録の際は、ラウンドロビン / ハッシュの剰余による分配など検討する必要があります。

また、リクエスト数上限によるデッドロック、URL(getリクエスト時)制限やエラーによる単一障害によるシステム全体のダウンもあるので、
十分に注意して構築していく必要があります。

「ついていきたい」と思われるリーダーになる51の考え方 を読みました。

ひょんなことから、リーダーポジションになり、色々勉強してきたのですが、
いわゆる"理想の上司"的な人物像について書かれている本が多く、少し懐疑的になっていました。
そんな時に「ついていきたい」と思われるリーダーになる51の考え方という本を読んだので、
その感想を書きます。

リーダーは完璧でなければいけないのか?

この本の読者層は、マネージャー / リーダーなど、部下が一人でもいる方です。

先のエントリでも書きましたが、やはりリーダー像って、
(だいぶ抽象的ですが)

  • 仕事ができる
  • リーダーシップがある
  • プレゼンとか話がうまい
  • カリスマ性がある

などなど、完全無欠のビジネスパーソンが頭に浮かぶのですが、
この本は、「いやいや、そんなことないよ〜。頑張れば誰でもリーダーになれるよ〜」
っと、全てのリーダーが上記のようなリーダーではないということについて書かれています。

この本を読むと、人間力を高める(磨く)ことがリーダーの最低条件だなということが学べました。

  • 誠実
  • 信頼できる
  • 責任感がある
  • 人に優しい
  • 気配りができる

などなど、著者のエピソードを基に、いかに人間力が重要かについて書かれています。

この本を読んで、理想のリーダーになったる!!!!!!!といった感じで、
鼻息を荒くして行動していたのですが、こういうリーダーもいるということが学べました。

これまで、自分のことばかり考えていたなぁと反省したのと、
自分一人ではなく、メンバーと協力して大きな仕事をしていくのが重要だと気付きが得られました。

上司のルール を読みました。

ひょんなことから、リーダーポジションについたので、
まずは、理想のリーダー像を学ぶことを目的に 上司のルールという本を読みました。

今回はその感想を書きます。

理想の上司がとる行動とは?

この本の対象読者は、"1人でも部下ができた人"です。

この本は、2部構成です。

  1. 部下を育てる時のルール
  2. 上司力を磨くルール

全100ルールが1ルールごとに見開きで書かれているのと、 あまり前後関係がないので、隙間時間に読むのに最適です。

内容としては、リーダーはどのような人格の人なのか? という点について、それをルールとして書かれています。

例えば、下記のルールがあります。

  • 褒め、励ます
  • チームのために戦う
  • 懸命に働く
  • 会社の目的を忘れない

おそらく誰しも、ぼやっとした"理想の上司像"があると思いますが、 その人物像の行動や思想を全て明文化したのがこの本です。

ここに書かれているルールを全て実践できている人は、圧倒的な信頼を得ているんだろうなと想像できます。

一定の期間で、この本のルールを鑑みて、振り返りをしていけば、 おのずと、模範となるマネージャー / リーダーになれるのではないのかと思います。

人を動かす を読みました。

色々な人と接する機会が増えたので、今更ながら
人を動かすを読みました。
今回はその感想を書きます。

人と接するときの基本思想が学べる一冊

対象読者は読者は人類全員です。

この本は、人と接するときの基本思想が学べる一冊です。 議論の最中に相手を論破しにいく行為は愚の骨頂であり、なんの価値も生まないことや、
傾聴力を上げるための方法論が書かれています。
また、タイトルの通り、人を動かす(やる気にさせる / 交渉する / 結婚生活をうまくいかせる / 人に頼み事をする)ときに有効な接し方も書かれているので、
会話の場面ごとに接し方を考えて行動するとうまく物事を運ぶことができるでしょう。

社会人であれば必読の一冊であることは間違いありません。

CircleCIで回しているRspecのテストを40%高速化しました

タイトルの通り、CirclCIで回しているテストを40%高速化した話をします。

うちの会社では、342files, 27300examples強を回しており、テスト時間が肥大化傾向にありました。
そこで、テスト高速化を図ろうと試行錯誤したので、その過程を書きます。
RRRSpec使えよ!というツッコミはなしで。CircleCI上で試行錯誤の記録を残すために書きます。

また、spec自体の高速化ではなく、CircleCIの仕様に合わせた高速化の方法についてのみを書きます。

やり方

なんと、この2つだけです!
シンプル!なんてシンプル!
並列実行して、遅いテストを特定するだけです。
そもそも技術力なんていりません。気合と根性*1で速くできます。

並列実行する

並列数を変更

CircleCIで並列実行数を増やすオプションがあります。

Project Settings => Tweaks => Adjust Parallelism
から設定ができます。

f:id:watasihasitujidesu:20150924222541p:plain

並列数増やせば(金で解決すれば)高速化できるんじゃね?っと、頭がよぎりましたが、
今回の話は、並列数は据え置きのまま(6並列)という縛りプレイでいきます。

もちろん、並列数は多いほど高速になります。

並列で実行するときに理解しておきたいこと

並列で実行する際、CircleCI上では複数コンテナを使ってテストを実行します。
理解しておきたいのは、複数コンテナ上実行されるテストはファイル単位となることです。
example単位ではないので、注意が必要です。

また、並列化した場合、テスト完了は、最も遅く終わったコンテナに引っ張られます。

  • コンテナA: 10分
  • コンテナB: 20分

この場合、CircleCI上では、テスト完了時間が20分になります。
要は、1コンテナあたりの実行時間限りなく、全コンテナの平均時間に近づけたいのです。

で、分散させる方法は下記の通りです。
1. まずはcircle.ymlを修正

この設定では、テスト実行を上書きしており、parallel: true (並列実行モード)にしています。

test:
  override:
    - ./script/parallel_for_circle.sh:
        parallel: true

では、parallel_for_circle.shを見ていきましょう。
2. 各コンテナで実行するテストは指定する方法

#!/bin/bash
set -xe

i=0
files=()
for file in $(find ./spec -name "*_spec.rb" | sort)
do
  if [ $(($i % $CIRCLE_NODE_TOTAL)) -eq $CIRCLE_NODE_INDEX ];then
    files+=" $file"
  fi  
  i=$((i+1))
done

echo $files
bundle exec parallel_rspec ${files[@]} -n 2
exit $?

CircleCIでは、並列実行時、各コンテナにCIRCLE_NODE_INDEXという、何個目のコンテナか?というインデックスが振られます。
また、CIRCLE_NODE_TOTAL全部で何並列か?という数値も取れます。
CircleCIではテストコマンドを上書きすることができるので、1ファイルごとにループを回し、
どのコンテナに割り当てるかをゴリゴリ書いていけば、均等に割り当てることができます。

もちろん、*1_spec.rbなどとすれば、コンテナを指定することができます。
が、全実行時にコンテナを指定するメリットがあまりないので、今回は上記のスクリプトで並列化します。*2

遅いテストファイルを特定する

次のステップは遅いファイルを特定して、そのファイルを分割することです。
6並列でテストを回すとこのような結果になります。
f:id:watasihasitujidesu:20150924224914p:plain f:id:watasihasitujidesu:20150924224935p:plain f:id:watasihasitujidesu:20150924224952p:plain f:id:watasihasitujidesu:20150924225039p:plain f:id:watasihasitujidesu:20150924225051p:plain f:id:watasihasitujidesu:20150924225103p:plain

見にくくて申し訳ないですが、実行時間は
- 1台目:14:03
- 2台目:15:55
- 3台目:16:29
- 4台目:38:46
- 5台目:13:13
- 6台目:12:06
合計96分。平均16分で終わるはずなので、それ以上かかっているコンテナに遅いファイルが存在する可能性が高いです。
この中ではダントツで4台目が遅いので、4台目に時間がかかっているテストファイルが存在するだろうと推測できます。

次に、並列数はそのままで、4台目の実行されたテストファイルを実行していきます。
さきほどのスクリプトではecho $filesと書いているので、CircleCI上のダッシュボードから実行されているテストファイルが確認できますのでメモっておきましょう。

メモっておいたテストファイルの絞り込みは、単純に

rm -rf ./spec/*
cat output_file | awk '{print "git checkout "$1""}'
....

などとしていけば4台目で実行されたものだけが残り、
実行することができます*3
理論的には6分ほどで終わるでしょう。

これを繰り返していけば、実行時間が長いファイルが特定できます。

遅いテストファイルを分割する

遅いファイルが特定できたら、あとはファイルを分割するだけです。
おそらく遅いファイルでは複数describeブロックやcotextブロックが存在すると思います。

# coding: utf-8
require 'spec_helper'

describe 'Hoge.fuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fuga? }

  it{should be_true}
end

describe 'Hoge.fugafuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fugafuga? }

  it{should be_false}
end

例えば、このテストファイルが実行完了まで10分かかっていたとします。
このファイルをhogehoge_fuga_rspec.rbとhogehoge_fugafuga_rspec.rbの2ファイルに分割した場合

# coding: utf-8
require 'spec_helper'

describe 'Hoge.fuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fuga? }

  it{should be_true}
end
# coding: utf-8
require 'spec_helper'

describe 'Hoge.fugafuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fugafuga? }

  it{should be_false}
end

並列で実行すると、最高で5分に短縮できます。

このような泥臭いことを続けていきます。
ファイルを特定 => ファイル分割 => ファイルを特定 => ファイル分割 => ....................

ただし、分割するのはいいのだけれど、間違った分割の仕方をしたら、死罪に値するかもしれません。
たとえば、
hoge_controller_get_action_spec.rb hoge_controller_post_action_spec.rb とかだったら中身を見なくとも、どのようなテストが書かれているか予測ができると思うのですが、

hoge_controller_1_spec.rb hoge_controller_2_spec.rb

などとした場合、いちいちファイルを開かねばならず、苦労しそうですので気をつけましょう。

まとめ

テクニカルなことは一つもやっていないのですが、簡単なことでテスト時間を40%も高速化することができました。*4

また、CircleCIの挙動に合わせた高速化ではなく、spec自体の高速化は、
下記のエントリが参考になりますので、お試しください。

ruby-rails.hatenadiary.com

*1:うちの会社の裏行動指針です

*2:もっと簡単な方法もあります。Qiitaで探してみてください

*3:かならず違うブランチでやりましょう

*4:これを自動化すれば良いって話ですが

スクラムのプランニングで見積もりと計画がうまくいかなかった時に参考になった本を紹介します

スクラム導入の目的の一つとして、進捗の可視化という点*1が挙げられたのですが、
うまく説明できなかったので、 「アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~
という本を読んだら、見積もり、計画、スケジューリング、他者への説明も以前よりはできるようになったので、
紹介しようと思います。

見積もりってどうやれば効果的なのだろう

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

まず、前書きの時点で震えるような言葉が書いていました。

アジャイル界隈に出かけていくと、私はいつも次のような質問を受ける。

  • 大規模チームの計画はどうやって立てれば良い?

  • イテレーションの長さはどれぐらいにすべき?

  • マネージャへの進捗報告はどうすれば?

  • ストーリーの優先順位づけの方法は?

  • プロジェクトの全体像をどう把握するのか?

ここに挙げたような疑問(と、その他多くの疑問)への見事な回答が本書だ。

読み終わってから思ったのが、「まさに、前書きに書かれていた通りだ」でした。

内容としては大きく下記のように構成されています。

  • (見積もりと計画においての)問題とゴール
  • 規模を見積もる
  • 価値のための計画づくり
  • スケジュールを立てる
  • ラッキングと情報共有
  • なぜアジャイルな計画づくりがうまくいくのか
  • ケーススタディ

計画と見積もりにフォーカスしているだけに、その内容はとても濃いです。
おそらく、スプリントを進めていると、ものすごく小さな疑問にぶつかると思います。
例えば、

  • 再見積もりはどのタイミングで行うか?
    • そもそも再見積もりして良いのか?
  • 部分的に完了した状態でスプリントが終わった場合は完了したストーリーポイントに加算するか?
  • 優先順位はどのようにつければ良いのか?
  • ユーザーストーリーは分割するのか?できるのか?
    • いつ分割するのか?
  • プランニング時に担当は決めるものなのか?
  • プランニング時に設計が始まっちゃうんだけで良いのか?
  • ベロシティにバッファは必要か?
    • どれくらい必要か?
  • バーンダウンチャートのうまい書き方はあるのか?
  • 個人のベロシティを計測したいのだが・・・

"プランニング"だけでも疑問を挙げ出せば切りがないのですが、
この本を読むと自分が感じた疑問は全て解決しました。

また、内容についても、深く書かれています。

なぜ必要なのか?いつ実行すべきか?実行すべきタイミングではないのはいつか?
誰が実行するのか?どう実行すれば良いのか?

それぞれ、明確に書かれており、疑問を残す余地がないほどです。

なぜ?の部分に関しては、学術的にも書かれていますので納得度も高いです。

優先度の決め方、知ってますか?

プロダクトオーナーは優先度を決める役割を担うわけですが、
優先度はどのように決めれば良いのでしょうか。

えいやで決めることもあれば、Aと比較してBは優先度は高いといった二分木探索的に決めるかもしれません。

この本では、優先度のつけ方についても詳細に書かれています。
ただ、その決め方がやや難解です。

具体的には下記項目を指標にします。

  • 金銭価値
  • コスト
  • 新しい知識を得られるか
  • リスク

収益を増加させることができるか、新しい収益を生むか、コストを抑えるか、業務効率化できるか、
実装にかかるコスト、理解するのにかかるコスト
ハイリスクのものから取り組むか、ローリスクのものから取り組みナレッジを積み上げるか
などが書かれています。

また、財務指標(内部収益率、回収期間、割引回収期間)を判断基準に用いるので、
より納得できる優先順位をつけることができると思いますし、
対外的にも納得感のある優先順位になると思います。*2

この本を買うべきだと思ったポイント

ポイントは2つあります。

1点目は、なんといっても見積もりと計画づくりにおいての網羅率と詳細度だと思います。
この本を読めば、切りが晴れたような感覚になると思います。
疑問点はなくなるでしょうし、納得感もあります。

また、"アジャイルな"と書いてありますが、見積もりと計画づくりを"アジャイルに"(「すばやい」「俊敏な」という意味)運ぶための本です。
本の中では、アジャイル開発中心として進められていますが、本を読んだ後振り返ると、
学んだことの肝は、ウォターフォール開発の中でも活きると思います。

2点目は、ソフトウェア開発(全体)についても学ぶことが多かった点です。
TDD, CI, ペアプロなど、技術者だけでアジャイルなプラクティスを回すことはできますが、
計画や見積もりなどといったビジネスサイドのプロセスがうまく回っていなければ、ソフトウェア開発がうまくいってると言えないと思います。

この本では、ビジネスサイド(計画や見積もり)のプラクティスを学び、技術とビジネスを調和を図るための一冊になると思います。

ビジネスサイドと技術サイドの人間は、決して相反するような関係であってはなりませんし、
互いに強調しながら価値のあるプロダクトを提供しなければならないと思います。
この本は、主にプラクティスについて書かれているのですが、それを実行するだけでは、"信頼のおける"見積もりと計画づくりにはできないと思います。
信頼のおける見積もりと計画づくりは、両サイドの人間が強調し合いながら、一つのプロダクトを磨くプロセスを共に歩んでこそ生まれるものなのだと学べます。

315ページ程度なのですが、1ページあたりの文字量と難しい言葉がやや多いので、気合を入れて読まないと挫折します。
(業務の合間にですが)気合を入れて読んだので、1週間程度で全て読む事ができました。

*1:要は、いつ終わるの?に答えられること

*2:とはいえ、だいぶパワーのいる作業なので、実際やれていない...orz

スクラムのレトロスペクティブをもっと掘り下げて学ぶときに参考になった本を紹介します

スクラムを導入して3ヶ月が経ち、チーム全体にスクラムが浸透してきましたが、
なんとなく、レトロスペクティブ(振り返り)がマンネリ化してきたので、
アジャイルレトロスペクティブズ 強いチームを育てる「ふりかえり」の手引き
という本を読んだら、フリカエリのバリエーションと手法が増えたので、 紹介しようと思います。

レトロスペクティブ(振り返り)にマンネリ化を感じたら読むべき本

アジャイルレトロスペクティブズ 強いチームを育てる「ふりかえり」の手引き

この書籍では、レトロスペクティブを5つのステップに分け、
それぞれのステップにおけるプラクティスを説明しています。

  • 場を設定する
  • データ(意見)を収集する
  • イデアを出す
  • 何をすべきかを決定する
  • レトロスペクティブを終了する

また、スプリント毎のレトロスペクティブだけではなく、
ある大きなプロジェクトが終わった際に行うレトロスペクティブの方法についても記載しています。

各プラクティスは、一定のフォーマット(目的、所要時間、概要、ステップ、材料と準備、使用例)
で書かれているので、理解も用意でした。

リーダーとしてのレトロスペクティブ

この本は、主にレトロスペクティブをリードしていく層に向けての本だと感じました。

本の冒頭には、振り返りの目的はもちろん、フォシリテーションについても書かれています。
レトロスペクティブだけでなく、議論を前に進めるというスキルも学べると思います。 具体的には*1

  • レトロスペクティブの準備の仕方
  • リード(ファシリテーションの仕方)
  • 議論へ参加させる方法
    • 口数が少なく、あまり話さない人
    • 口数が多く、喋りすぎてしまう人
    • 上位職の人が圧力をかけてきた時の対処
    • メンバーにイレギュラーな出来事が発生したときの対応
      • 泣いた時
      • 怒った時
      • 部屋を出て行った時
      • 不適切に笑いが起こった時
      • 静寂に包まれたとき
      • 表面化で何かしている時(内職をしている時)
  • 自分を落ち着かせ、頭を整理する方法

上記のような事についても書かれています。

この本を買うべきだと思ったポイント

先述の通り、レトロスペクティブを5つのステップに分け、それぞれのステップにおけるプラクティスを説明しています。
買うべきだと思ったポイントは、その手法の多さです。
量だけ説明すると

  • 場を設定する => 6件
  • データ(意見)を収集する => 8件
  • イデアを出す => 9件
  • 何をすべきかを決定する => 6件
  • レトロスペクティブを終了する => 9件

合計 38件の手法をこの一冊で学ぶことができます。
一度のレトロスペクティブで使える手法は5つかもしれませんが、
知識として自分のツールボックスに入れておくには十分すぎる量だと思います。

また、各ステップにおいて、どのプラクティスが有効かについても、書かれていますので、
逆引き的にも使えます。

レトロスペクティブを進めるリーダーにはオススメな書籍です。

160ページ程度なので、3~4時間程度で全て読む事ができました。

*1:一部抜粋

Xcode7 で Buildしたときにyou must rebuild it with bitcode enabledと 出てしまう場合の回避方法

概要

Xcode7 で Buildした際に f:id:watasihasitujidesu:20150919173334p:plain

does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7

といわれてしまい、Failしてしまったので、その対応方法を書きます。

手順

  1. プロジェクトのルートフォルダをクリック
  2. Build Settingsタブを選択
  3. Allを選択(Basicではない方)
  4. Enable BitcodeNoに設定
  5. Product => Clean
  6. Buildする

こちらを参考にしました。 qiita.com

rbenvを使用したrubyのバージョン管理と最新状態に保つ方法

概要

  • rbenvのインストールと設定
  • rubyのバージョンの最新を取得

rbenv インストール

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ mkdir -p ~/.rbenv/plugins
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

rbenvを入れているが、rbenv install -lので最新のrubyバージョンが出てこない場合

$ cd ~/.rbenv
$ git pull origin master
$ cd ~/.rbenv/plugins/ruby-build
$ git pull origin master

Amazon CloudSearch における適切なスケーリングオプション(Scaling Options)を紹介します

概要

Amazon CloudSearch における適切なスケーリングオプションの設定を紹介します。 設定できる項目は下記の通りです。

以下、公式ドキュメントより引用

ドメインのスケーリングオプションを設定するときは、コストとパフォーマンスのトレードオフが生じます。望ましいインスタンスタイプ、レプリケーション数、パーティション数を変更すると、ドメインを実行するコストに大きな影響があります。

また、各項目の変更はそれぞれ下記の通り影響があります。

設定項目 期待できる効果
インスタンスタイプ アップロードキャパシティの増加
パーティションカウント 検索リクエストの応答速度の向上
レプリケーションカウント 検索キャパシティの増加および耐障害性の改善

インスタンスタイプ

インスタンスタイプは格納するIndexサイズ(データ総容量)とドキュメント数の目安から決定しましょう。

インスタンスタイプ Indexサイズ ドキュメント数
m1.small 1GB未満 625,000
m3.medium 1GB ~ 8GB 1,250,000
m3.large 8GB ~ 16GB 2,500,000
m3.xlarge 16GB ~ 32GB 5,000,000
m3.2xlarge 32GB ~ 64GB 10,000,000

※Indexサイズが64GBを超える場合は、後述のパーティションカウントの設定変更を検討します。

Indexサイズ(データ総容量)について

容量はindexing optionsの設定により増加していきます。 indexing optionsで設定できる項目は下記の通りです。

  • Highlight
  • Return
  • Sort
  • Facet

これらはそれぞれ、次のようにIndexサイズを肥大化させます。

設定項目 増加するIndexサイズ(%)
全て指定しなかった場合 0%
全て指定した場合 243%
Highlight 220.8%
Return 153.2%
Sort 12.7%
Facet 0.3%

不要なindexing optionsの設定をしないことで、コスト削減と応答速度向上が見込めるため、 indexingする際には注意する必要があります。

パーティションカウント

インスタンスタイプが2xlargeの場合、パーティション数を指定できます。
また、インスタンスタイプを決定する際に、格納するIndexサイズ(データ総容量)を確認したと思いますが、
この容量が64GBを超える場合はパーティションカウントの上限を上げることを検討をします。
具体的なパーティション数は
(Indexサイズ / インスタンスタイプの容量上限) + 1
が望ましいパーティション数です。

例) Indexサイズが150GBの場合
インスタンスタイプ: m3.2xlarge
パーティションカウント: (150GB / 64) + 1 = 3

レプリケーションカウント

レプリケーションカウントはリクエストするクエリの複雑度と、トラフィックに応じてレプリケーションカウントを調整します。
現状CloudSearchでは応答速度のメトリクスは取れませんので、
NewRelicのWeb externalを確認し、調整するしかないようです。

または、下記の表を目安にしても良いでしょう。

インスタンスタイプ JMeterの設定 スループット
m3.medium 2 hosts 10threads 48.3 qps / 206 ms
m3.large 4 hosts 20threads 291.5 qps / 68 ms
m3.xlarge 8 hosts 40threads 665.9 qps / 59 ms
m3.2xlarge 16 hosts 80threads 985.3 qps / 80ms

その他スケーリングについてのtips

  1. スケーリングオプションではレプリケーションカウントの変更はIndex再構築が必要ない(変更自体は無料で変更できる)ですが、
    インスタンスタイプとパーティションカウントの変更にはIndex再構築費用がかかるため、十分に検討する必要があります。
    Index再構築費用は下記の通り
    Indexサイズ 1GB あたり 0.98 USD

  2. 上記より、Webサイトのピークタイムがわかる場合は、AWS CLIより自動で設定します。
    例) 10 ~ 18時のピークタイムに合わせてレプリケーションカウントを2 => 3に変更する場合

0 10 * * * /usr/bin/aws --region ap-northeast-1 cloudsearch update-scaling-parameters --domain-name hogehoge-production --scaling-parameters DesiredReplicationCount=3,DesiredInstanceType=search.m3.2xlarge,DesiredPartitionCount=4
0 18 * * * /usr/bin/aws --region ap-northeast-1 cloudsearch update-scaling-parameters --domain-name hogehoge-production --scaling-parameters DesiredReplicationCount=2,DesiredInstanceType=search.m3.2xlarge,DesiredPartitionCount=4

まとめ

CloudSearchはフルマネージドと謳いつつも、AutoScalingの検知やスケールが遅かったり、
メトリクスが貧弱なため、トライ&エラーで知見を得ていくしかありません。
また、障害が発生した場合の問題を自分達で調べることができない上、サポートに問い合わせをしても腑に落ちない回答になる場合が多いです。
(レプリケーションカウントとパーティションカウントを増やして対応してくださいで終わる、など…)

ただ、経験が溜まっていくと、オンプレでSolrやElasticSearchを運用するよりは楽だと感じています。

スクラムのレトロスペクティブをKPTで振り返りするときに参考になった本を紹介します

スクラムを導入してなんとか1スプリントが終わったばかりなのですが、
レトロスペクティブ(振り返り)の具体的な進め方がわからなかったので、
「これだけ!KPT」という本を読んだらスムーズに進行できたので、
紹介しようと思います。

KPTをするの時のバイブル

これだけ!KPT

全6章立てで、1,2章はよくある問題とか、KPTの効能とかが書かれています。
KPTが何なのかを既に知っている方は、ここは正直読み飛ばしてしまってもよいかと思います。

3~6章にかけては、ハウツーについて書かれています。
KPTを使った振り返りについて、時間配分が分単位で書かれています。
また、時間配分された項目ごとに、実際に

  • 何を話すか
  • ポイントとコツは何か

についても書かれています。

そのほか、後半の章になると、下記のことについても掘り下げて書かれています。

  • KPTの応用編と称した、慣れてきたチーム向けに時間圧縮バージョンの進め方
  • Keep, Problem, Tryそれぞを引き出すための質問例
  • 意見が多く出た場合の情報分類術
  • KPTの結果からチーム状態の分析
  • ファシテーションの方法

これまで、KPTを体系的に学ばず、普通のメンバーとしてダラダラ振り返っていると感じる人や、
KPTを使った振り返りでのファシテーションをします!

って人まで、KPTに関わる人全員におすすめだと思います。

ページ数が少なく、文字も比較的多く、イラストを使って説明もされているので、
1.5時間くらいでサクッと読めました。

これからスクラムを始める人へのお勧め本を紹介します

ひょんなことから、会社でスクラムを使って開発をすることになり、スクラム関連の本を読み漁ったので、 これを機会にお勧め書籍を紹介します。

アジャイル手法

アジャイルサムライ

アジャイル開発手法についてまとめた本。
これを読んだ時は、スクラムの存在を知らなかった状態で読んだが、
アジャイル開発の思想は理解できる内容。
ただし、ハウツー本ではなく、思想の解説本であるため、実際にチームが
いつ、なにをするかという具体的な内容は文面から想像ができませんでした。
一度読んで理解すればそれだけで良い本かなと思います。

また、この本を読んだ後にスクラム本を読み始めたが、前提となる知識はこの本で理解していたので、
後続のアジャイル系の本をサクサク読んでいくことができました。

文字数が多く、すべて読むのに6時間くらいかかりました。

スクラム

SCRUM BOOT CAMP THE BOOK

読んだ直後は、後に紹介するスクラム実践入門と比較して内容が薄い。と思ったのですが、
スクラムはただの開発手法でありフレームワークにしかすぎないので、
フレームワークを実践する組織なり、チームに合わせた内容にアレンジする必要があると考えさせられました。

ベースとなるストーリはマンガで書かれているので、とても読みやすいので、
サクッとスクラムの概要をサクッと理解するには良い本です。
2時間ほどで読める内容なので、はじめの一冊にオススメです。

スクラム実践入門

体系的にまとまった一冊。
SCRUM BOOT CAMP THE BOOKとは違う種類の書籍で、参考書的に使いたいです。
今、机の上においてあるのはこの一冊だけです。それほどよくまとまっています。

スクラムで登場する役割、成果物、イベントなどを説明のほかに、オススメできる内容として

  • パターンプラクティス
  • スクラムを使っている会社の導入事例3社分
  • スクラム運用における、よくある問題と解決集

が掲載されているので、何か不穏な空気を感じた時とはこの本を参考にすると、だいたい解決するのではないかと思います。
実際、救われたことが何度かありました。

4時間ほどで読める内容ですが、何度も何度も読んで理解を深めるのに最適です。
もしかしたらSCRUM BOOT CAMP THE BOOKはいらないかも?

まとめ

振り返ると、スクラム実践入門だけあれば、文字通り実践までできるのではないかと思います。
スクラム勉強会などでも、スクラムマスターとして、様々な人と対等に話せるレベルになります。
(スクラムが、理解'は'容易だからってのもありますが・・・)

チームのメンバーに対してスクラムに興味を持ってもらうには、
SCRUM BOOT CAMP THE BOOKのマンガ部分をサクッと読んでもらう程度で良いかと思います。
それくらいライトな本です。

それでは、よいスクラムライフを!