Elasticsearch 先輩との戯れ日記(登場人物の整理)

この記事何?

お仕事で Elasticsearch 先輩を使うことになったので、そのお戯れの記録

登場人物の整理

事例を中心に調査していたが、色々混乱してきたので、 Elasticsearch の世界の登場人物を整理することにした。

雑な説明

hoge

オブジェクト 概要
Cluster Node を束ねる存在
Node Elasticsearch のインスタンスのこと
Shard Index を分割したもの
Index インデックス
Type テーブル
Document レコード

雑すぎるので1個ずつ見ていく。

Cluster

Node を束ねるもの。 Cluster Health を使って、 Cluster の状態を確認することができる。

  • green: すべての Shard が Cluster 上に配置されてる
  • yellow: PrimaryShard は Cluster 上に配置されているが、配置されていない ReplicaShard が存在している
  • red: Cluster 上に配置されていない Shard が存在している

Shard については、後述。

Node

Node | Elasticsearch Reference [5.4] | Elastic

Node には Master (eligible) Node と Data Node と Ingest node が主要な感じ(Tribe Node はよくわからなかった)

Master Eligible Node

  • クラスタ内で行う処理の分配を行う
  • もし、 Master Node が死んだら、別の Master Eligible Node が Master になってくれる(デフォルトでは全 Node)
  • Master Node は、基本的に分配だけをメインにやらせると安定運用につながる

Data Node

  • document の管理を行う
  • 主に CRUD 操作を担当
  • Master Node とは役割分離させようね
  • I/O 系の処理はメモリいっぱい使うからちゃんと監視しようね

Data Node が死んじゃったらデータは欠損する? discovery.zen.minimum_master_nodes を設定すれば、設定した値の数で最小構成として、データの書き込みとかを行うみたい(おそらく) なので、一応データの欠損は防げるらしい。

参考:Avoiding split brain with minimum_master_nodes

Ingest Node

  • Elasticsearch 5.0 から登場
  • index を貼る前にドキュメントを変換するために使う Node
  • パイプラインを作って複数の処理を組み合わせて実行もできる

Shard

Shards & Replicas

10億個の document を複数に分割して読み込めるように、 index を分割する仕組み。 これによって、オペレーションの分散と並列化ができるため、パフォーマンスの向上につながる。

Primary shard を増やせば増やすほど並列数が上がって1ノードのパフォーマンスが上がるかも? →ただ、その分スペックは要求される デフォルトは5つの Primary Shard と 各 Primary Shard 毎に 1つの Replica Shard

Replica Shard は Primary Shard コピーを複製してあるもの。 このコピーは同一 Node には作成出来ない。

elas_0401.png

出典 : How Primary and Replica Shards Interact | Elasticsearch: The Definitive Guide [2.x] | Elastic

Index

Document を纏めるもの。 インデックス 付け、検索、更新、削除全てを行う。

Reindex | Curator Reference [5.1] | Elastic

インデックスを貼り直すとかって事もできる。 ここらへんが検索周りのチューニングポイントらしい。

Type

Document を種類別に分別することができる。 データベースで言うところの table

Document

1レコード分の情報が入ってるもの。 JSON で表現される。

Index Type Document の相関図はこんな感じ el-640x374.png

出典: データ構造について – AWSで始めるElasticSearch(4) | Developers.IO

まとめ

登場人物整理したら、なんとなく事例でチューニングした話とかも分かりそうな気がした。 あくまで、気がしているだけ。 図とかは出典元を見ていただけるとうれしいです。

番外編

こいつで、docker-compose up ってするだけで、 kibana と elasticsearch がどっちも立ち上がるんだって :sugoi:

version: '2'
services:
  kibana:
    image: kibana
    links:
      - elasticsearch:elasticsearch
    ports:
      - 5601:5601

  elasticsearch:
    image: elasticsearch
    ports:
      - 9200:9200
      - 9300:9300

公式もサポートしているっぽい。 library/elasticsearch - Docker Hub

Elasticsearch 先輩との戯れ日記(データの投入)

この記事何?

お仕事で Elasticsearch 先輩を使うことになったので、そのお戯れの記録

複数ドキュメントを扱う API って何がある?

Document APIs | Elasticsearch Reference [5.4] | Elastic

Multi-document API いっぺんにデータ突っ込んだり取ってきたりするやつっぽいな。

  • Multi Get API(データの取得)
  • Bulk API(データの挿入)
  • Delete By Query API(データの削除)
  • Update By Query API(データの更新)
  • Reindex API(インデックスの貼り直し)

データの投入について

Bulk API

Bulk API | Elasticsearch Reference [5.4] | Elastic

The bulk API makes it possible to perform many index/delete operations in a single API call. This can greatly increase the indexing speed.

endpoint は /_bulk, /{index}/_bulk, {index}/{type}/_bulk の3つ。 パラメーターに JSON 形式で挿入したいデータを指定する。 もし、データを送りたい場合は、

  • データの最終行に改行(\n)を入れる
  • もし改行したい場合は、 carriage return (\r) を使ってね
  • Content-Type: application/x-ndjson をヘッダーに含めて送ってね

を守ること。

$curl -X POST -H 'Content-Type: application/x-ndjson' 'localhost:9200/test/account/_bulk?pretty&refresh' --data-binary "@accounts.json"  
   ...
    {
      "index" : {
        "_index" : "test",
        "_type" : "account",
        "_id" : "990",
        "_version" : 1,
        "result" : "created",
        "forced_refresh" : true,
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "created" : true,
        "status" : 201
      }
    },
    {
      "index" : {
        "_index" : "test",
        "_type" : "account",
        "_id" : "995",
        "_version" : 1,
        "result" : "created",
        "forced_refresh" : true,
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "created" : true,
        "status" : 201
      }
    }
  ]
}

CSV ファイルから直接いけるか?

:no_good: :no_good: デフォルトでは CSV ファイルから、直接ぶち込むことはできず、一旦 JSON 形式に変換してあげる必要がありそう。

$ curl -s -X POST -H 'Content-Type: text/csv' 'localhost:9200/test/feed/_bulk?pretty&refresh' --data-binary "@test_feed1000.csv" | jq
{
  "error": "Content-Type header [text/csv] is not supported",
  "status": 406
}

打開案

1手目はできそうだけど、そこまでして、 Elasticsearch の内部でデータを持つ必要があるのか説はあるな。。。

注意点

設計によっては、 OOM とかが頻発しちゃうのは結構怖さあるな。 OOM 発動しなくてもデータ破損とかはかなり痛いしな もうちょっとここは追加調査が必要。 場合によっては、検索/保存で仕組みを切り離しちゃうのも1つなんだろうなというお気持ちになりました。

余談

データの取得

ついでに確認のために、調べたので、データの取得も _search に query を投げてあげれば取れる。 from で指定する値が行数。 size が何行取り出すか。

以下の例は100行目から2行取り出すとなるので、100,101行目が取り出せている。

$ curl -s -X GET http://localhost:9200/test/account/_search -d '{"query":{"match_all": {}}, "from": "100", "size": "2"}' | jq .
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1000,
    "max_score": 1,
    "hits": [
      {
        "_index": "test",
        "_type": "account",
        "_id": "383",
        "_score": 1,
        "_source": {
          "account_number": 383,
          "balance": 48889,
          "firstname": "Knox",
          "lastname": "Larson",
          "age": 28,
          "gender": "F",
          "address": "962 Bartlett Place",
          "employer": "Bostonic",
          "email": "knoxlarson@bostonic.com",
          "city": "Smeltertown",
          "state": "TX"
        }
      },
      {
        "_index": "test",
        "_type": "account",
        "_id": "408",
        "_score": 1,
        "_source": {
          "account_number": 408,
          "balance": 34666,
          "firstname": "Lidia",
          "lastname": "Guerrero",
          "age": 30,
          "gender": "M",
          "address": "254 Stratford Road",
          "employer": "Snowpoke",
          "email": "lidiaguerrero@snowpoke.com",
          "city": "Fairlee",
          "state": "LA"
        }
      }
    ]
  }
}

というわけで、100行単位でページングみたいな使い方はできそうということが分かった。

Elasticsearch 先輩との戯れ日記(セットアップなどなど)

この記事何?

お仕事で Elasticsearch 先輩を使うことになったので、そのお戯れの記録

今回調べたものなど

まず Elasticsearch でどんなことができるかを調べるために、公式のチュートリアルとここ載ってる記事を読み漁った。

環境準備

公式さんから最新版(5.4)を Download してきた。 Kibana も合わせてローカルで準備しておく(戯れ用)

Download Elasticsearch Free • Get Started Now | Elastic Download Kibana Free • Get Started Now | Elastic

日本語全文検索用のプラグインである analysis-kuromoji を入れてみる。

# /Users/pokotyamu/Downloads/elasticsearch-5.4.2
$ bin/elasticsearch-plugin install analysis-kuromoji
-> Downloading analysis-kuromoji from elastic
[=================================================] 100%
-> Installed analysis-kuromoji

curl で叩いて、 plugin が入っていることを確認。

$ curl -X GET 'http://localhost:9200/_nodes/plugins?pretty'
{
  "_nodes" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "cluster_name" : "elasticsearch",
  "nodes" : {
    "tfQ1ZsOzQ9CYZtA0jXw2ww" : {
      "name" : "tfQ1ZsO",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1",
      "version" : "5.4.2",
      "build_hash" : "929b078",
      "roles" : [
        "master",
        "data",
        "ingest"
      ],
      "plugins" : [
        {
          "name" : "analysis-kuromoji",
          "version" : "5.4.2",
          "description" : "The Japanese (kuromoji) Analysis plugin integrates Lucene kuromoji analysis module into elasticsearch.",
          "classname" : "org.elasticsearch.plugin.analysis.kuromoji.AnalysisKuromojiPlugin",
          "has_native_controller" : false
        }
      ],
     ...
}

基本コマンド

起動は以下で行う。終了は Ctrl-C-d オプションでバックグラウンド起動可能。

# /Users/pokotyamu/Downloads/elasticsearch-5.4.2
$ bin/elasticsearch

ポートはデフォルトで 9200番が使われるみたい。 crul で叩いてみて、次のように出たらOK

$ curl localhost:9200
{
  "name" : "tfQ1ZsO",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "Y2-U0XlwSxWX771QXbIN0w",
  "version" : {
    "number" : "5.4.2",
    "build_hash" : "929b078",
    "build_date" : "2017-06-15T02:29:28.122Z",
    "build_snapshot" : false,
    "lucene_version" : "6.5.1"
  },
  "tagline" : "You Know, for Search"
}

データ投入してみる

マッピング定義

MySQL Elasticsearch
database index
schema mapping
table type
record document

だいたいこんな感じの対応をしている。 マッピングの定義はこんな感じ↓

{
    "mappings": {
        "sample": {
            "properties": {
                "name": {
                    "type": "string",
                    "index": "not_analyzed"
                },
                "coord": {
                    "type": "geo_point"
                },
                "description": {
                    "type": "string",
                    "analyzer": "kuromoji"
                }
            }
        }
    }
}

sample の部分が type の名前になっている。 これを landmark という index に突っ込むためには PUT で書き換えれる。

# curl -X PUT http://localhost:9200/<Index Name>
$ curl -X PUT http://localhost:9200/landmark --data-binary @mapping.json
$ curl -s -X GET http://localhost:9200/landmark | jq .
{
  "landmark": {
    "aliases": {},
    "mappings": {
      "sample": {
        "properties": {
          "coord": {
            "type": "geo_point"
          },
          "description": {
            "type": "text",
            "analyzer": "kuromoji"
          },
          "name": {
            "type": "keyword"
          }
        }
      }
    },
    "settings": {
      "index": {
        "creation_date": "1498037230489",
        "number_of_shards": "5",
        "number_of_replicas": "1",
        "uuid": "9tFY4-F5S-KTyVEAa40DCg",
        "version": {
          "created": "5040299"
        },
        "provided_name": "landmark"
      }
    }
  }
}

ちなみに、このマッピング定義をしないでも、登録はできるらしい。 その時は Elasticsearch 側がよしなに値から型定義をしてくれるとか。凄い。

データ投入

今回は Bulk API でデータ投入してみる。 Bulk だと一回のリクエストで一気にデータを突っ込めるみたい。

{ "index" : {} }
{ "name": "スカイツリー", "coord": { "lat": "35.710063", "lon": "139.8107"}, "description": "東京スカイツリー(とうきょうスカイツリー、英: TOKYO SKYTREE)は東京都墨田区押上一丁目にある電波塔(送信所)である。"}
{ "index" : {} }
{ "name": "BLUE NOTE TOKYO", "coord": { "lat": "35.661198", "lon": "139.716207"}, "description": "N.Y.の「Blue Note」を本店に持つジャズクラブとして、南青山にオープンしたブルーノート東京。ジャズをはじめとする多様な音楽ジャンルのトップアーティストたちが、連夜渾身のプレイを繰り広げている。"}
{ "index" : {} }
{ "name": "東京タワー", "coord": { "lat": "35.65858", "lon": "139.745433"}, "description": "東京タワー(とうきょうタワー、英: Tokyo Tower)は、東京都港区芝公園にある総合電波塔とその愛称である。正式名称は日本電波塔(にっぽんでんぱとう)。"}
# curl -X POST http://localhost:9200/<Index Name>/<Type Name>/_bulk --data-binary @landmark.json
$ curl -X POST http://localhost:9200/landmark/sample/_bulk --data-binary @landmark.json
{
    "errors": false, 
    "items": [
        {
            "index": {
                "_id": "AVzJ-slvXdDNsyfvvuMV", 
                "_index": "landmark", 
                "_shards": {
                    "failed": 0, 
                    "successful": 1, 
                    "total": 2
                }, 
                "_type": "sample", 
                "_version": 1, 
                "created": true, 
                "result": "created", 
                "status": 201
            }
        }, 
        {
            "index": {
                "_id": "AVzJ-slwXdDNsyfvvuMW", 
                "_index": "landmark", 
                "_shards": {
                    "failed": 0, 
                    "successful": 1, 
                    "total": 2
                }, 
                "_type": "sample", 
                "_version": 1, 
                "created": true, 
                "result": "created", 
                "status": 201
            }
        }, 
        {
            "index": {
                "_id": "AVzJ-slwXdDNsyfvvuMX", 
                "_index": "landmark", 
                "_shards": {
                    "failed": 0, 
                    "successful": 1, 
                    "total": 2
                }, 
                "_type": "sample", 
                "_version": 1, 
                "created": true, 
                "result": "created", 
                "status": 201
            }
        }
    ], 
    "took": 286
}

検索

最後に検索。検索も json で query を作って実行する。 メソッドは GET を使用。 検索に使えるのは、調べ中。。。 AND 検索はもちろん、数値の比較とか範囲指定とかもできるみたい。

$ curl -s -X GET http://localhost:9200/landmark/sample/_search -d '{"query":{"match":{"description":"ジャズ"}}}' | jq .
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.928525,
    "hits": [
      {
        "_index": "landmark",
        "_type": "sample",
        "_id": "AVzJ-slwXdDNsyfvvuMW",
        "_score": 0.928525,
        "_source": {
          "name": "BLUE NOTE TOKYO",
          "coord": {
            "lat": "35.661198",
            "lon": "139.716207"
          },
          "description": "N.Y.の「Blue Note」を本店に持つジャズクラブとして、南青山にオープンしたブルーノート東京。ジャズをはじめとする多様な音楽ジャンルのトップアーティストたちが、連夜渾身のプレイを繰り広げている。"
        }
      }
    ]
  }
}

まとめ

ひとまず、ローカルで立ち上げる→データを突っ込む→検索するの流れは試せてた。 次はどーやったら、がつっとデータ突っ込めるかを調べてみる。

社会人2年目もチェスト!!!

ついに社会人1年目終了。

東京の生活には全然慣れませんが、健康体でいれたので、 病欠による休みはゼロでした! (5分ぐらいの遅刻1回)

ただ、オリジン弁当とズブズブの関係なので、体重は7キロぐらい太りました。適正体重まであとちょっとですw


1年目は、技術力が高い先輩や同期に圧倒されつつも、ちょっとずつ自分の出来ることが増えていくのを感じれることができました。

自分の中で、学びたかったスクラムの知識を整理できたのも非常に身になりました!

pokotyamu.hatenablog.com

ただ、プログラミングスキルに関しては、まだまだ発展途上… 結局 Rails しか満足に勉強できてないし…(その Rails もまだまだ修行中)


今の会社では、自分のエンジニアとしてのキャリアパスに対して、色々挑戦させていただいたり、サポートしてくれる環境が整っているので、それに応えれるように準備してこうな!

この一年は自分のプログラミングスキルを一から見直す。

そのための勉強をするときのコストはなるべく惜しまないようにしていきたいと考えていて、2年目の初日、 Mac Book Pro の 2016年モデル買いました。

f:id:pokotyamu:20170403003051p:plain

2年目もチェスト!!!!!(宗りんおかえり!!!!!!)

新卒が真面目にアジャイル勉強してみた

社内勉強会で、アジャイルについて発表してみたので、こちらにも残しておきます!!!

当日資料はこちら↓↓

やってみた感想

きっかけは、なぜスクラムしているの?

資料の中にも書いていますが、自分が今回アジャイルについて勉強を始めたきっかけは、1番新しくチームメンバーとして入った方の「なぜスクラムしているの?その利点は何?」という発言でした。

実際に開発メンバーとして仕事をしている上で、何も知らない中スクラムを実施していることに違和感があったので、今回社内勉強会という機会を利用して、自分で勉強して、発表することにしました。

結果として、今のチームとしてここは良い点悪い点が言えて、そこから改善案も考えれるようになりました。

新卒が開発手法について口を出す

チームの中でも1番年下になりやすい新卒だからこそ見える世界もあると思います。 ただ、意見を1番いいにくいのも新卒な気がします(経験の問題や会社の風土だからという感じに流される)。

だからこそ、意見を言うための確かな知識を勉強して、経験じゃない根拠を持って話すことが出来れば、雰囲気に押し流されない意見を言えるようになるのではないか?とやってみて感じました。

アジャイル守破離の心構え

「これが正解」「こうやるもの」というわけではなく「何を目的にしていてこういうやり方が進められている」を知るのが「守」かな

これは、発表を終えたあと頂いた弊社 CTO からの感想です。

これも先程述べたように、原理原則を知った上で行動や意見をする必要があるという気づきにつながりました。

勉強会に対するモチベーション

準備期間が長く取れる場合ほど、途中で別のことしたくなったりなどあるかと。

今回はそれ対策で、途中途中で発表内容に使う本のまとめやセミナーのまとめを社内 Qiita やこのブログにまとめることで承認欲求を満たしつつ準備するというので乗り切りましたw

何かしらのリアクションやご意見を頂きつつ勉強することで、自分の見えてない見方や考えを途中の段階でも知れるきっかけになります! これは意外とよかったです。

pokotyamu.hatenablog.com

pokotyamu.hatenablog.com

※内容がネタバレ的になっちゃう系の場合はこそこそ頑張りましょう!

まとめ

スライドメインなので、さらっと終わりますが、今までチームとしてのやり方しかしらず、アジャイルスクラムを研修や独学で知識を付けてない方はぜひ一度勉強することをおすすめします!!!!

LEGOスクラムに参加した!(レゴ編)

この記事なに?

12/14(木) に行われたLEGOスクラムのレポートです!

イベントの詳細についてはこちら↓

waicrew.doorkeeper.jp

座学編はこちら↓

pokotyamu.hatenablog.com

今回は実際のワークでもあるレゴ編です!

ユーザーストーリーを作る

各チームが1つの家族で、家族が希望する街に引っ越すという形でワークが始まりました。

私が担当したのは私立女子校に通う JK の娘↓

f:id:pokotyamu:20161214131920j:plain

要求(ユーザーストーリー)はこのテンプレートにそって書いていきます。

(役割や立場)として、
(機能や性能)が欲しい。
それは(理由や目的)のためだ。

f:id:pokotyamu:20161214135450j:plain

うん!実に最近の JK っぽいですね()

ここでポイントとなるのが、3行目で、3行目の理由や目的を解決するための手段として、2行目があるので、できるだけ3行目を具体的に書くことが大事になってきます!

もちろん、別な手段(2行目)で解決出来ることが開発側からあれば、そちらを提案できるようにしておくのが、顧客にも求められます。

プランニングポーカー

それぞれのユーザーストーリーがまとまったら、プランニングポーカーを使って、見積もりをしていきます。

あくまで絶対評価ではなく、相対評価で、作業の見積もりを行うやり方です。

写真は、10個の都道府県の人口を 1,2, 3, 5, 8 に分けるワークを行っています。 基準として与えられたのが、福岡が5、長野が2という情報だけです。

f:id:pokotyamu:20161214133326j:plain

絶対評価だと、難しいですが、相対評価になることで、見積もりの精度を上げることができます。

ただし、このやり方は声の大きい人の意見が通りやすいので、ファシリテートが大事そうに感じました。

いよいよ LEGO

ここまで終わったら、実際に LEGO を使ってまちづくりです。 今回のスプリントでやることを決める(2分) →作る(7分)→顧客が評価する→振り返り この流れで3スプリント分行いました。

f:id:pokotyamu:20161214143157j:plain

f:id:pokotyamu:20161214165811j:plain

成果

最初は獲得したベロシティは0pt だったのですが、最後は9pt 分獲得することができました。

その要因としては、

  • チームとして、最終成果物の認識を合わせることが大事
  • 作業の分担を決めた
  • 全員で1つの作業に取り掛かった
  • PO に質問を最初にまとめておこなった
  • 時間管理を行った

このような点が考えられます。

2つ目に挙げた作業分担ですが、正直これに関しては、スクラムというやり方的には真っ当ではなかったのですが、3スプリントで成果をだすことを目標にしたので、固定化しました。

もっと期間がながければ、役割を何度かシャッフルして、得意な分野に対して、サインアップしていくやり方が正しい気がします。今回はスキルなどもわからない点が多かったためにこのような形をとりました。

また、最後の時間管理については、あと何分だから、ここは諦めるなどの決定をチームで行ったことで、ミニマムな建造物を作る方にシフトしてたのもベロシティがあがった要因だと思います。

これは、品質の悪いものをとどけるという意味ではなく、成果が0よりは、何かしらの形あるものに対してフィードバックをもらって開発を進めたほうがよいという判断をチームで行ったために、このようになりました。

結果として、アジャイルな開発に沿った形で開発を行えた気がします。

難しかった点

  • 他のチームの PO を捕まえて仕様を確認する必要が度々発生したのですが、やはり PO は忙しいので、個別でいくのではなく、まとめて質問する必要があると感じました
  • 成果物のイメージが固まっていないと、各々の方向に向かって開発を進めてしまって、結果何もできないという未来がまっていた
  • カンバンに対する意識を7分間の中に入れ込むのは少し難しい
    • もっと時間のある期間であれば問題なさそう

感想

2つの記事に分けてまとめていきましたが、率直に参加して良かったと思っています。

体型的に知識を入れることができた点もありますが、実際のワークを通して、アジャイルな考え方が整理された気がします。 また、スクラム開発を行うのであれば、チームメンバーは最低限の知識として、このぐらいは経験じゃなく本や研修として学んでおくほうがよいと感じました。

もうしばらく、スクラムアジャイルについて勉強を深めていきたいと思います!!!! f:id:pokotyamu:20161214170602j:plain

LEGOスクラムに参加した!(座学編)

この記事なに?

12/14(木) に行われたLEGOスクラムのレポートです!

イベントの詳細についてはこちら↓

waicrew.doorkeeper.jp

参加の理由としては、「今のチームでやってる手法がちゃんとアジャイルのレールに乗っているか?」「体系的に一回知識を入れてる一貫として、先輩におすすめされたから」

といった感じでした。

チーム決めでは、スクラムについて詳しい順に並んでくださいということで、まさかのプロジェクトでやってる方が私しかおらず、参加者の中で1番詳しい人となりましたw

この記事では座学で学んだ部分についてまとめます。

ちなみに、メモは会社の slack で垂れ流ししてました。

f:id:pokotyamu:20161215114442p:plain

アジャイル is 何? スクラム is 何?

まずは、なんでもかんでもアジャイルを適用すればいいのか? いわゆる銀の弾丸なのか?という話です。

大前提アジャイルに定義はない!!

あえてあげるとすれば、態度概念

スクラムやカンバンといった方法論を身につけることで、アジャイルが習得されるでいいということです。

では、スクラムとは何なのか?

スクラム=複雑で変化の激しい問題に対応するためのフレームワーク。可能な限り価値の高いプロダクトを生産的かつ創造的に届けるためのもの。

複雑で変化の激しいとはどんな状況なのか?

何を作ればいいか・どうやって作ればいいかが中途半端なものをここでは、複雑(Complex)なものとして定義します。

例えば、夏休みの宿題のようなものは、スクラムに向いていません。

なぜなら、何をするかも、どうやるかも明確で、各教科を1つずつ終わらせていけば全ての作業が完了するようなものだからです。特に変化が発生する要素がないので、別の方法を適用する方がよいらしい。

セミナーの中では WBS*1 に切ることが出来るものということも仰っていました。

また、漠然としすぎていてもそれはそれで問題だそうで、「世界を良くするものを作る」という、何を作ればいいか・どうやって作ればいいかが難しすぎる(Anarchy)な問題に関してもスクラムを適用することはできません。

これを達成するには、デスマーチしかないとのこと。

これらの真ん中の作業の時にスクラムが有効な手段となりうるそうです。

アジャイル開発は、オブジェクト指向開発を人間に当てはめたもの

オブジェクト指向形のプログラミング言語の特徴として、クラスに生えてるメソッドはどのインスタンスでも同じような振る舞いを行うというものがあります。

その考え方をプロダクトマネージメントにも応用しようと考えたのがアジャイルなチームの始まりで

  • 1つ1つのタスクが誰がどの作業をやれる状態となっている
    • アサインではなく、サインアップ
  • 機能横断型なメンバーでチームを構成する

1つ1つのタスクが誰がどの作業をやれる状態となっている

これは、タスクの粒度や共通認識のレベルの話で、全員が同じ規模感や認識を持つことが重要ということです。

そして、1つ1つのタスクに対して、誰かから当てはめられるのではなく、手が空いた人から「これやります!」というのが大事になっています。

確かに、うちのプロジェクトでもサインアップは意識されている気がする

機能横断型

機能横断型とは、自分の領域を絞らずに全部出来る(しようとする)ゼネラリストのような人が集まった集団が求められるということです。

例えば、「自分はバックエンドだけしかするつもりありません」という人より、「デザインもできますし、インフラもできます」というような感じです。

今まで、スクラムは一手法として捉えていたので、オブジェクト指向を人間に当てはめたものという表現は納得感のあるものでした。

一回で完成品を作ろうとするのは無理

半年がかりで、どかっとした機能を作るのではなく、雪だるまのようにちょっとずつやれることを増やしていく考え方でプロジェクトを進めます。

  1. 最小の単位で作ってみる
  2. 製品とプロセスの振り返りを行うこと

特にどのようにこれらを作っていったか?というプロセスまで振り返りができるようにすることで、個人としてではなく、チームとしての成長を狙っています。

座学の中では最高に美味しい焼きそばの作り方というテーマでワークが行われました。

ラグビー型のチームへ

複雑で変化の激しい領域に対応するならば、継続的にちょっとずつ前に進める変化に強いチーム作りを意識しなければならない。

f:id:pokotyamu:20161217134846g:plain

引用:The New New Product Development Game

type A のようなリレー形式のように、引き継ぎ引き継ぎで作業をするのではなく、同じチームで継続的に少しずつ進んでいく type C のようなラグビー型のチームのほうが早く進めることができるという調査。

このラグビー型チームにしていくためには、決まったパターンがあるので一回それに当てはめてみてトライアンドエラーで進めていくことが大事そうに感じました。

基本的に【プロダクトオーナーxスクラムマスターx開発チーム】の構図

ここでいう開発チームは、実際にコードを書く人だけでなく、テスターやデザイナーも含まれるそうです。

そして、プロダクトオーナーは「何を作るかの責任者」であるため、必ずしも技術に長けている必要はない。 顧客からの要求をスキニングしたり、製品の価値として、どこまで求めるかの意思決定を行う。

スクラムマスターは「どうやって作るかの責任者」であるため、そのチームの中で一番技術に長けている人がなるべき。

チーム内で発生したバックログに全く関係のない雑務(例えば会議の調整)もスクラムマスターが行うべきだそうです。

その理由としては、チームとして目標を達成できることが一番なため、個人のスキルを高めるために余裕のある人が「技術的に一番余裕がある人」である点。 また、他の人に目を配る余裕がある点や、何をやっているかが(技術的に)わかる点も1番スキルの高い人がやるべき要因です。

そしてなにより、技術に長けている= Complex な問題を解決する力が強いわけではないということも前提としてあります。

まとめ

ここまで、アジャイルの方法論の一つであるスクラムについて書いてきましたが、最後にまとめると。

  • スクラムは適度に複雑(Complex) な問題を解決する方法で簡単すぎても漠然としすぎてもいけない。
  • なんども繰り返してチームとして問題解決を行える力を付ける
    • そこでは必ずプロダクトとプロセス両方の振り返りを行う

この座学のなかではあまり触れられていなかったのですが、お客さんがアジャイルに積極的かどうか?という点も実際の仕事においてはかなり重要になっていくそうで、お客さんの理解を得る方法については、アジャイルサムライに、確実に動くものを毎週届けることで、少しずつ信頼を得ていくというのが大事という風に書いてありました。

あと、ここや本に書いてあることはあくまでもテンプレートなので、最終的な形は自分たちでカスタマイズして作っていくことが大事になってくるのかなと思いました。

最初から、アジャイルな気持ちで〜と言っても何をすれば?となってしまうので、初めは型にハマって、次第にカスタムしていくというのかな。

特に Web 業界だと、週に1回のリリース頻度だとちょっと遅すぎるので、そこらへんのバランスも必要になってきたりしそうです。

というのが座学の感想です。

後半のレゴ編に続きます

pokotyamu.hatenablog.com

*1:Work Breakdown Structure:作業分解構成図