コネヒト開発者ブログ

コネヒト開発者ブログ

AWS Glueを用いてETL環境を構築したお話(RDS for MySQL → S3)

はじめに

こんにちは。2019年3月にMLエンジニアとしてJOINした野澤(@takapy0210)です。

最近はThe Mentalistという海外ドラマにお熱です。犯罪コンサルタントとして活躍する主人公の歯に衣着せぬ物言いやテンポの良さなど、見ていて爽快ですし一つ一つの作品が短いので気軽に楽しめます。(心理学に興味があると楽しさ倍増です)

前置きが長くなりましたが、初めてコネヒト開発者ブログに登場です。テンポ良くいきたいと思いますので、どうぞよろしくお願いします!

今回は機械学習基盤アップデートの一環としてAWS Glueを用いてETLしてみた話について、苦労したポイントなどを中心にお話できればと思います。

導入背景

コネヒトではママリというコミュニティサービスを運営しており、ユーザが投稿する質問に対する検閲フィルタとして機械学習が用いられています。

詳細は弊社CTOのスライドをご覧ください。

現在、モデルの更新が継続的にできていない(≒検閲フィルタのアップデートができていない)という課題があり、機械学習基盤のアップデートを実施しています。
その一環として「RDS for MySQLからデータ抽出 → 機械学習しやすい形へ加工 → S3に保存」のように良い感じでETLしたいよね!という話になり、AWS Glueに白羽の矢が立った次第です。

結論

AWS Glueを用いることでRDSに保存されているデータを抽出・加工し、それをtsv形式でS3に保存することができました。

以下その内訳です。

  • データ件数:約700万件
  • Job実行時間:5分
  • 出力tsvデータ:約3GB

結果としてはやりたいことが実現できた訳ですが、思っていたより複雑で学習コストがかかるな〜という印象を受けました。
(初見が難しいだけで、一度設定できれば以降はスムーズにいけそう感!はありました)

次項から、Glueの説明や設定方法、MySQLからのデータ抽出方法などについて述べていきます。

AWS Glueとは

AWSが提供する完全マネージド型 ETL (抽出、変換、ロード) サービスです。
公式ドキュメントはこちら

f:id:taxa_program:20190417115301p:plain
AWS Glueのアーキテクチャ図

言葉の定義について

上図を見ても分かるようにいろんなワードが出てきます。それぞれの定義が曖昧になり兼ねないので、一度整理しておきます。

  • Data Stores
    データを永続的に保存する(している)リポジトリ。S3バケットやRDS。本記事ではRDSを示す。

  • Data Source
    Job(Script)への入力として使用されるData Stores。 本記事ではRDSを示す。

  • Data Target
    データの書き込み先のData Stores。本記事ではS3を示す。

  • Data Catalog
    AWS Glue 環境を管理するためのテーブル定義、Crawler、接続情報などを管理するサービスの総称。

  • Crawler
    Data Storesに接続しデータのスキーマを判断し、Data Catalog にメタデータテーブルを作成するサービス。

  • Job
    ETL 作業を実行するために必要なビジネスロジック。プロパティ(Scriptのファイル名や保存先、接続情報)で構成される。このJobの作成時にData SourceとData Targetを指定する。 JobはApache Spark ETL ジョブPython シェルジョブの2種類から選択することができ、スケジュール起動/イベント起動が可能。

  • Script
    Jobに含まれるETLの実行処理スクリプト。S3に保存される。

構築したアーキテクチャ

今回構築したアーキテクチャの概要図です。

冒頭でも述べましたが、今回の目的はRDSに保存されている情報をGlueを使って抽出・加工し、それを.tsv形式でS3に保存することです。

f:id:taxa_program:20190417123456p:plain
今回構築したアーキテクチャ概要図

構築手順

今回は下記手順で構築しました。

  1. サブネットの作成
  2. セキュリティグループの作成
  3. Glue接続情報のIAMロール作成
  4. Glue接続情報の作成&接続テスト
  5. CrawlerのIAMロール作成
  6. Crawlerの作成&実行
  7. S3バケットの作成
  8. JobのIAMロール作成
  9. Jobの作成&実行

Glue接続情報とはData Storesへ接続するためのプロパティ情報です。これを元にClawlerを作成していきます。 そしてこのClawlerを実行してRDSのメタ情報を取得し、取得したメタ情報を元にJobでクエリを発行する、という流れです。

ここで押さえておきたい事としては、

  • Glueを利用する際には、最低限として「接続情報」「Crawler」「Job」の3つが必要だということ
  • そしてそれぞれに対してIAMロールが必要(接続情報用、Crawler用、Job用)だということ

だと思います。

構築する際のポイント

上記手順の中でも苦労したポイントについてお話します。大別すると2点です。

  • Glueには自己参照ルールが必要だった(セキュリティグループの話)
  • RDSを用いたユースケースがなかった(Jobの話)

Glueには自己参照ルールが必要だった件

手順「4. Glue接続情報の作成&接続テスト」で接続情報を作成しようとしたときに、適切なセキュリティグループを確認できません。JDBCの接続タイプを変更し、接続の追加を再試行しますというエラーメッセージが表示されました。

f:id:taxa_program:20190417150236p:plain
接続情報作成時のエラー

上記を解消するために、セキュリティグループに関しては下記のように設定する必要があります。

  • Glue 側のセキュリティグループ
    自己参照ルールにて TCP の全ポートからのインバウンドアクセスを許可する必要がある

  • Data Stores(RDS)側のセキュリティグループ
    Glueから3306ポートにアクセスできるようにする必要がある

今回の場合は、

  1. RDSにアタッチするセキュリティグループ(SG-A)とGlueにアタッチするセキュリティグループ(SG-B)を作成する。(新規作成しなくても良い。2つのSGを分けることが重要)
  2. SG-Aのインバウドルールに「TCP、ポート:3306、ソース:SG-B」を追加する。
  3. SG-Bのインバウドルールに「TCP、ポート:0-65536、ソース:SG-B」を追加する。(こちらが自己参照ルール)

という手順で設定しました。

RDS for MySQLを用いたユースケースがなかった件

冒頭でも述べましたが、GlueのJobはApache Spark ETL ジョブPython シェルジョブの2種類から選択することができます。

今回は「学習コストが低い」「分散処理するほどの大量データではない」などの観点から、Pythonシェルジョブを用いることにしました。

知の宝庫であるインターネットを駆使してユースケースを探しましたが、RDSからデータを取得するユースケースは見当たらず・・・。
公式ドキュメントなどにRedShiftを利用した事例はいくつかありました)

AWS サポートの力も借りつつ試行錯誤した結果、MySQL用のライブラリを外部よりインポートすることで実現できたので、次項でその手順をご紹介できればと思います。

PythonShellジョブからMySQLを利用する手順

Python Shellで外部のライブラリを使用したい場合はeggファイル利用する必要があります。
下記が大まかな手順です。

  1. eggファイルを作成
  2. 作成したeggファイルをS3にアップロード
  3. eggファイルをジョブに連携

こうすることで、JobからMySQLが利用可能になります。
(eggファイルの作成は、ローカルでも任意のインスタンス上でも可能ですが、python2.7がインストールされている必要があります)

1. git cloneで下記のPyMySQLライブラリをコピー

これは任意の場所にcloneすればOKです。

$ git clone https://github.com/PyMySQL/PyMySQL 

2. 任意の場所にpackage作成用のディレクトリを作成

$ mkdir package
$ cd package

3. packageを作成(python2.7.15で実行)

$ pip install PasteScript
$ paster create -t basic_package pymysql

設定項目は、全てデフォルトで進めました。

4. ソースコードを配置

1.でgit clone したディレクトリのpymysqlディレクトリの内容を、2.で作成したpackageディレクトリ配下にすべてコピーします。

$ cp -pr <git cloneしたパス>/PyMySQL/pymysql/* <2.でpackageディレクトリを作成したパス>/package/pymysql/pymysql/

※__init__.pyについては、上書き保存します。

この時点で、ディレクトリ構成は下記のようになると思います。

f:id:taxa_program:20190417184915p:plain
ディレクトリ構成

5. eggファイルを作成

packageディレクトリの配下(setup.pyファイルが作成されているディレクトリ)で、以下コマンドを実行します。
これでeggファイルが作成されます。

$ ls
-> pymysql  pymysql.egg-info  setup.cfg  setup.py 

$ python setup.py  bdist_egg
$ ls
-> build  dist  pymysql  pymysql.egg-info  setup.cfg  setup.py 

6. distディレクトリの下に、eggファイルが出来ていることを確認

$ cd dist
$ ls
-> pymysql-0.1.dev0-py2.7.egg

下記のようなeggファイルが作成されていれば問題ありません。

f:id:taxa_program:20190417185007p:plain
ディレクトリ構成

以上でインポートするeggファイルの作成は終了です。

7. 作成したeggファイルをs3にアップロード

CLIを使わずとも、マネジメントコンソール上からアップロードしても問題ありません。

$ aws s3 cp ./pymysql-0.1.dev0-py2.7.egg <s3パス>/pymysql-0.1.dev0-py2.7.egg

8. GlueのPython Shell Jobを設定

マネジメントコンソール上でジョブの作成を行います。 Pythonライブラリパスに 7.でアップロードした.eggファイルを指定してジョブを作成します。

f:id:taxa_program:20190417185200p:plain
Job作成時にPythonライブラリパスを指定

以上でMySQLが利用できるPythonShellジョブの作成は終了です。

スクリプト

参考までに、今回作成したスクリプトを公開します。 (一部、値をマスクしています)

import boto3
import sys
import csv
import pymysql.cursors
import pandas as pd
import re
from io import StringIO, BytesIO

connection = pymysql.connect(
    host='XXXXXXXXXX.rds.amazonaws.com',
    user='user',
    db='dbname',
    password='password',
    charset='utf8mb4',
    cursorclass=pymysql.cursors.DictCursor
    )

sql = "SELECT column1, column2 FROM table WHERE 0 = 0 ORDER BY column1 desc"
df = pd.read_sql(sql=sql, con=connection)

# Delete tab char
df['column1'] = df['column1'].apply(lambda x: x.replace("\t",""))

# Replace CR char
df['column1'] = df['column1'].apply(lambda x: x.replace("\n"," "))

# Convert DF to TSV format
csv_buffer = BytesIO()
df.to_csv(csv_buffer, sep='\t', encoding="UTF8") #TSV出力

# output to S3 as CSV file
bucket = "s3-bucket"
key = "hoge/hogehoge.tsv"
s3 = boto3.resource('s3')
obj = s3.Object(bucket, key)
s3response = obj.put(Body=csv_buffer.getvalue())

最後に

テンポ良くいくつもりが盛りだくさんになってしまいました。

現段階ではGlueを用いてRDSからデータ抽出するユースケースがネット上にないと思うので、この記事が一人でも多くの方の参考になれば幸いです!

imgix導入でコンテンツダウンロード量を85%削減した話

こんにちは。インフラエンジニアの永井(@shnagai)です。

今回は、imgixという画像変換に対応したCDNを導入して、コンテンツダウンロードの削減を実現した話について書こうと思います。

imgixとは

はじめに、imgixって何と思われる方も多いかと思いますので簡単に特徴を紹介します。

  • クエリパラメータで、画像のリサイズや圧縮が出来るCDNサービス
  • S3をバックエンドに指定出来るので、画像のコピー等が不要でそのまま使える
  • バックエンドはFastlyが使われているので高速配信
  • 国内だと、日経や一休で採用実績あり
  • コストは、標準プランだとCDN Bandwidth: 8¢/GB + Master images accessed $3/1000

imgix • Real-time image processing and image CDN

導入した背景

ママリが運営しているメディアサイトや記事関連のwebviewにおいて、PCサイズの大きめ画像をどのデバイスにおいても配信していたため、コンテンツダウンロード量が大きくなりモバイル回線で見た時のユーザ体験を損ねていました。

速いは正義ということで、速度改善の第一弾としてimgixの導入を決めました。 Lighthouseのスコアでも画像系の指摘が多くスコアが伸び悩んでいたのでこれを一つのKPIとして導入作業を進めました。

  • Properly size images 20s…
  • Serve images in next-gen formats 15s…

今回の移行で行ったこと

CloudFrontから配信していたサイズの大きな画像をimgixからの配信に切り替え、コンテンツダウンロード量を削減するために、移行と同時にクエリパラメータによる画像圧縮とリサイズ、フォーマット変更を行いました。

基本的なパラメータを下記にまとめたのでご参考までに。

内容 パラメータ 備考
サイズ圧縮 q=値 or auto=compress 動的に圧縮率を変更可能, autoの場合はデフォルトで75%の圧縮率
リサイズ w=値,h=値 動的にリサイズ可能
※fitパラメータで、縦横比維持、トリミング、また顔のズーム等にも対応しています。
画像フォーマット変更 auto=format 対応ブラウザ配信時にwebp対応

気になる方は、公式ドキュメント に細かく書かれているのでこちらをご覧ください。

下記のように、パラメータを付与するだけで一枚のオリジン画像から簡単にリサイズすることが出来ます。 ほぼ劣化なしにリサイズや圧縮出来る点がimgixの強みだなと個人的には感じています。

元画像 209KB

リサイズ画像(auto=format,compress&q=90&w=400) 32KB

導入後の成果

画像の最適化だけではスコアが劇的に上がるということはないのですが、下記を見ていただくとわかる通り画像系の課題が多かった関係で、一定のスコア向上を実現できました。

特に、今回の狙いだったコンテンツダウンロードサイズの削減が実現出来たことで、モバイル回線でママリを使ってくれるユーザのユーザ体験向上に寄与できた点が一番大きかったです。

コストに関しては細かくは書けないのですが、画像圧縮の結果配信量が減ったのでその分コストカットも実現出来ました。

Lighthouseの結果

そもそものスコアが低いという話はありますが、導入結果としてわかりやすいので参考として貼っておきます。

スコアという意味では、まだまだ改善の余地があるのでフロントエンドエンジニアと協力してより速さとその先にある快適なユーザ体験を追求していきたいと思っているのでまだ途上です。

  • 記事タブのwebview
項目 CloudFront imgix 差分
モバイル トータルコンテンツダウンロードサイズ 5551KB 807KB 85%減
パフォマンススコア 63 74 +11
コンテンツの初回ペイント 1.0s 0.9s -0.1s
意味のあるコンテンツの初回ペイント 3.4s 1.0s -2.4s
速度インデックス 4.7s 4.1s -0.6s
CPUの初回アイドル 6.7s 6.0s -0.7s
インタラクティブになるまでの時間 8.1s 6.7s -1.4s
入力の推定待ち時間 460ms 190ms -270ms
  • 記事ページ
項目 CloudFront imgix 差分
モバイル トータルコンテンツダウンロードサイズ 3682KB 1739KB 50%減
パフォマンススコア 29 44 +15
コンテンツの初回ペイント 1.7S 1.4s -0.3s
意味のあるコンテンツの初回ペイント 1.7s 1.4s -0.3s
速度インデックス 10.7s 6.0s -4.7s
CPUの初回アイドル 15.3s 11.0s -4.3s
インタラクティブになるまでの時間 21.9s 13.3s -8.6s
入力の推定待ち時間 160ms 140ms -20ms

導入メリット

導入メリットとして、下記が上げられます。

  • エンドユーザには、コンテンツダウンロードサイズの削減によるユーザ体験の向上を提供
  • アプリケーション的には、よく画像アップロードトリガで走らせたりする画像リサイズ処理をCDN側にオフロード出来る
  • コスト面でも、契約にはよりますがリサイズ等による配信量軽減によるコストダウン
  • 画像のリサイズを人力で行っているようなケースの場合は、その作業もすべてクエリパラメータベースに置き換えることが出来ます

注意点

最後に、imgix導入を検討する上で注意しておいた方がよい点についてもまとめておきます。

料金体系

Imgixは、Master Image数+帯域での課金になります。 Master Imageとはオリジナルのイメージ数のことで、これが無限に増えていくようなユーザアップロード用途で使うと思わぬコスト増を招く可能性があるので事前に検証してコスト計算しておくのがおすすめです。

TLS1.2未対応ブラウザへの対応

TLS1.1以前のSSL通信はサポート外なので、Androidのwebview標準ブラウザだと画像が表示されません。セキュリティ観点から世の中的には少なくなってきていますが、動作確認時にチェックするのがベターです。

サポートや営業とのやりとりは英語が必須

日本の代理店はないので、ボリュームディスカウントの交渉やテクニカルサポートはすべて英語です。ただ、とても親切に対応してくれるのであまりネックにはなりませんでした。

最後に

既に導入していた @akasakas に色々と情報をもらいスムーズに移行を進められたので、この場を借りてお礼を言いたいと思います。ありがとうございました。

コネヒトでは変化を恐れずに良いものを取り入れながらサービスの信頼性向上をミッションに一緒に働く仲間を探しています。 少しでも興味もたれた方は、是非気軽にオフィスに遊びにきていただけるとうれしいです。

www.wantedly.com

Droidcon Boston 2019に行ってきました!

f:id:tommy_kw:20190411215936j:plain

こんにちは!

Androidエンジニアの富田です。4/8、4/9にDroidcon BostonというAndroidエンジニア向けのカンファレンスがボストンで開催されました。国内のAndroidカンファレンスのブログは比較的多いと思うのですが、一方海外に目を向けると日本語ブログが少なく、どんなカンファレンス内容か気になることはないでしょうか?今回はDroidcon Bostonに参加してきましたので、気づきやナレッジを共有します。

Droidcon Bostonって?

www.droidcon-boston.com

Droidconとは、Androidエンジニア向けのグローバルなカンファレンスで、開発者同士のつながりを深めたり、技術の知見を共有するカンファレンスです。今回参加した開催地はボストンですが、それだけではなくニューヨークやロンドンなどでも開催されている大規模なカンファレンスです。

僕はDroidconに一度も参加したことがなかったのですが、DroidKaigiの登壇者、かつDroidcon Bostonスタッフでもある@droid_singhさんから‏幸運にもDroidcon Bostonのチケットを頂きましたので、初参加させて頂きました!色んな縁があるのだなとしみじみ感じたので、日々徳を積んでいこうと心に誓いました。

カンファレンス全般

Droidcon Bostonは2017年からスタートして、今年で第3回目となります。トラックは2つあり、トータル27トークセッションと4つのワークショップがありました。DroidKaigiと比べると参加者は若干少なく規模も小さめでしたが、立ち見をすることなくどのセッションでも座って落ち着いて見ることができました。

マルチトラックイベントにおいて、気になるセッションや時間を有効活用してセッションをみたいものですよね。そんな時に役立つのがカンファレンスアプリです。全体のスケジュール確認はもちろんのこと、気になるセッションが始まる前のプッシュ通知がくるので重宝しました。キャプチャではわからないのですが、カンファレンス当日には、アプリの最下部に「JUMP TO CURRENT」というボタンが表示され、それをタップすると進行中のセッションにスクロールされるようになっていました。こちらのカンファレンスアプリのソースコードも公開されているので、気になる方はご覧ください!

f:id:tommy_kw:20190413155603g:plain

カンファレンスの楽しみといえば無料でいただけるグッズですよね。ピンバッチやシールなど頂き、さらにこんな可愛いTシャツを頂きました!

f:id:tommy_kw:20190411215854j:plain
Droidcon Boston Tシャツ

また、全体を通して全てのセッションでライブスケッチを行なっていることに気づきました。下記のセッションを見ていただくと、登壇者の横に大きなボードがあるのがわかります。セッション開始と同時に下書きなしでセッション内容を描き始めます。

f:id:tommy_kw:20190411220750j:plain
Building @ speed of thoughtのセッション

そして実際に出来上がったスケッチがこちらです!60分枠のセッションがほとんどだったのですが、限られた時間でこのクオリティって...本当すごいですよね!セッション自体を見るのはもちろんですが、ライブスケッチを見るだけでも楽しめます。

f:id:tommy_kw:20190411221230j:plain
巨大なライブスケッチ

セッション一覧

セッション内容にはJetpack、Kotlin、テスト、Firebase、Flutter、Coroutine、RxJava、ML、アーキテクチャなど様々なジャンルで構成されていました。セッション一覧スライドに関しては以下のGithubにて管理されており、今年のセッションスライドだけでなく、20172018年分のセッションスライドもキャッチアップできるようになっています。ご興味ある方はぜひご覧ください!ここからは特に気になったセッションを3つ紹介します。

github.com

Do the Loco-MotionLayout: Building animations with MotionLayout

@mikescamellさんによるMotionLayoutの紹介です。MotionLayoutがどのように機能するか基礎についてサンプルコードを基に体系的に学ぶことができます。MotionSceneとは何か、またそれを利用して状態とレイアウトから分離する方法、トランジションのトリガーとなるクリックとスワイプの利用方法、KeyAttributesを利用してアニメーションの微調整方法などまで言及されていました。

f:id:tommy_kw:20190413151129g:plain
サンプルアプリ

Destination navigation: You’re going to love the transition

github.com

@emmaxさんによるNavigationアーキテクチャコンポーネントの入門紹介です。Android開発を加速するJetpackの一つであるのNavigationの利用方法について説明になります。基本利用からSafe Args、Conditional Navigation、Deep Link、テスト方法などまで言及されていました。

Leveling Up As An Android Dev

github.com

@moyheenさんによるAndroidエンジニアのキャリアについての紹介です。Android向けの技術カンファレスなので技術的な内容のセッションは多いですが、このセッションではキャリアについて紹介されています。Androidエンジニアの各レベルで求められていることって意外とわからないものですよね。今回紹介されていた内容は以下の通りです。

  • ジュニアエンジニア
  • ミドルエンジニア
  • シニアエンジニア
  • リードエンジニア
  • マネジメント
  • その他(GDEなど)

各レベルで何をすべきか、そして今のレベルを把握することによって、次のレベルに前進するための情報を得ることができます。

最後に

ひょんなことからDroidcon Bostonに参加させてもらったのですが、グローバルなカンファレンスであり、かつ豊富なジャンルのセッションでとても刺激的でした。スライド一覧を見ていただくと興味のある内容もあると思いますのでぜひご覧ください!また、Droidconはボストンだけでなく、様々な地域で開催されているため、Droidcon Bostonをきっかけに他のDroidconにも参加して行きたいと思います。以上になります、ありがとうございました!

新米マネージャーが1on1で実践していること

f:id:itosho525:20190409183944p:plain

こんにちは。サーバーサイドエンジニアの @itosho です。

Bリーグ(日本のプロバスケットボールリーグ)がシーズン佳境を迎え、週末はDAZN漬けの毎日を送っています🏀*1

というわけで、今日はバスケの1on1の話…ではなくミーティングの方の1on1の話をしたいと思います。僕は半年ほど前からプレイングマネージャーのようなポジションでマネジメント業務をしており、その中で1on1ミーティングも定期的*2に実施しています。

1on1については導入企業も増えてきており、事例も広く公開されてるようになってきましたが、まだまだ現場の個別具体的なノウハウは世に出てきていないと個人的には感じています。そこでこの記事では半年間の振り返りと知見の共有を兼ねて、僕が1on1で実施した取り組みを4つ紹介させていただきます。

なお、前職等でも多少のマネジメント経験はありますが、ガッツリやるのは初めて+コネヒトでは初めてのマネジメント経験になるので新米マネージャーという表現をさせていただいております。

1. 1on1の目的を共有

まず、初回の1on1では目的の共有を行いました。一口に1on1と言っても、社長が実施する1on1と直属の上長が実施する1on1は役割が違います。また、個々人が1on1に対して抱いているイメージや期待値も様々です。ですので、最初にそのギャップを埋めるために僕が想定している1on1の目的やイメージなどを伝えるようにしました。

具体的には以下の目的でやるよ!ということを共有しました。

## 1on1の目的
- 設定した目標を達成するための支援 
- 生き生きと働ける(≒その人が100%の力を発揮出来る)ようにするための支援
  - もやもやしていることや本当はやりたいこと何でもいいので話してください
- よろず相談
  - 会社関係なくキャリアのお悩みとかあれば(話したい人はプライベートの話でもOK)

また、これは雰囲気というかただのイメージの共有ですが、野球で例えると僕(メンター)は監督やコーチではなくキャッチャーでメンバー(メンティー)はピッチャーだよということを伝え、1on1はキャッチボールをするような場であることもセットで共有しました。

2. 1on1シートの作成

目的の共有と併せて、面談シートのような1on1シートを作成しました。個人的に1on1では雑談も大切だと思っているので、あまりガチガチにやりたくないと思っています。とは言え、やってる感だけ出して、目標の達成支援が出来ていないなら、それはメンバーの貴重な時間をいたずらに奪っているだけなので、トラッキングも兼ねて1on1の数日前に1on1シートを用意して事前に話したいことなどを書いてもらうようにしていました。また、僕からも気付いたことがあれば積極的に書くようにしていました。ただ、1on1を受ける側からすると準備のコストが高いと1on1が億劫になってしまうこともあるので事前に書くのは任意にしていました。

1on1シートのフォーマットは何度かアップデートを行い、現在は以下のような形で運用しています。

## YYYYMMDD: 第X回

### お話
- 事前に話したいことがあれば書いておいてください!

### プチ振り返り&フィードバック

#### よかったこと
- 最近よかったことや上手くいったことをお互い書くコーナー

#### よくなかったこと
- 最近よくなかったことや改善したほうがよいことをお互い書くコーナー

### Todo
- メンターの宿題を書くコーナー

簡単に説明すると、最初のお話枠は何でもよいので話したいトピックがあれば書いてもらっています。2つ目のプチ振り返り&フィードバック枠は日頃からカジュアルにフィードバック出来る場があったほうが良いかなと思い、メンバーが自分の行動でよかったと思うことやよくなかったと思うことを書き、僕はその人を傍から観察して、よかったと思うことやよくなかったと思うことを書くようにしています。基本的にはポジティブなフィードバックが多めですが、お互いに書き、それを共有することで期待値調整や認識齟齬の早期解消を行っています。最後のToDo枠は1on1の過程で発生した僕がやるべきタスクを忘れないようにメモします。ここで書いたタスクは次の1on1で進捗を報告したり、対応したタイミングで共有したりしています。

3. フィードバックワークの実施

コネヒトではOKRによる目標設定をしているのですが、その過程で中間振り返りを実施するタイミングがあります。そこで目標達成のためにいつも1on1より長めに時間を確保し、目標の振り返りと併せてワークショップ形式でフィードバックを行いました。

いわゆる、ジョハリの窓に近いようなワークなのですが、目的としては、

## フィードバックワークの目的
- 自身の振り返りと他者の振り返りを掛け合わせることで、気付きと学びを得る。
- そして、行動を変える一歩を踏み出すための後押しをする。

というのを掲げ、以下のような流れでワークを行いました。

## フィードバックワークの流れ

### 1. メンバーが以下の内容を付箋に書く
- 目標を意識して移せた行動や言動
- 目標を意識していたが出来なかった行動や言動

### 2. 僕が以下の内容を付箋に書く
- 目標に沿っていたと思う行動や言動
- もう少し目標に沿わせられたと思う行動や言動

### 3. それぞれの付箋を発表する
- 発表された付箋をメンバーが以下の画像のような四象限にマッピングする

### 4. マッピングされた付箋をみながら質問し合う
- 何故出来ないか深掘りしたりどうすれば出来るようになるか考えたり

### 5. 最後に今後注力したいポイントを1つ決める
- 決めたものは1on1シートに記載する

f:id:itosho525:20190409154121p:plain

やってみた所感としては、対面でやるフィードバックよりもコトに向かいやすい(僕のフィードバック力不足に依るところも多いですが)点が非常に良いなと感じました。

4. オフサイトでの実施

普段の1on1はオフィス内*3で行っているのですが、たまにカフェなどのオフサイトでも1on1を実施しています。もちろん、オフィス外なのでコンフィデンシャルな話は出来ませんが、いい意味で仕事っぽくない雰囲気になり、いつもと違う話が構造的にもやりやすいので時々オフサイトでやるのは良いなと思います。ちなみに事前に苦手な飲み物がないかどうかを確認しておくことも地味に大切です。

まとめ

このようにまとめると、ややもすればいい感じに1on1をやっているようにみえるかもしれませんが、まだまだ勉強不足で試行錯誤の毎日です。それでも、僕は1on1の質はメンバーのことを考えている量に比例すると思っているので、これからも日々努力を積み重ねていきたいと思っています。冒頭にも述べましたが、1on1の現場の個別具体的なノウハウはまだまだ世に出てきていないと感じています。それは最適解が会社や職種、個人、はたまたフェーズなどの変数によって大きく異なることに起因するのも原因の一つだと思います。しかし、だからこそ様々な事例を知ることも重要だと思うので、またノウハウが溜まってきたタイミングで定期的に共有を行っていきたいと考えています。この記事が誰かのためになれば幸いです。

*1:ちなみに当方、アルバルク東京のブースターです。

*2:基本的には隔週1回30分のペースで実施していますが、頻度は各人の状況や時期に応じて適宜見直しています。

*3:オフィスで実施する場合も、会議室っぽくないスペースかつ対面にならない場所を選ぶことが多いです。

PHPerKaigi 2019にシルバースポンサーとして協賛いたします!

こんにちは。サーバーサイドエンジニアの 高野 (@fortkle) です。
さて、今日はイベント協賛の告知をさせてください!

PHPerKaigi 2019に協賛いたします!

タイトルにもある通り、PHPerKaigi 2019 にシルバースポンサーとして協賛いたします。
コネヒトではメインプロダクトである「ママリ」を始めとして開発のメイン言語としてPHPを活用しており、フレームワークとしてはCakePHPを採用しています。

phperkaigi.jp

イベント概要

PHPerKaigiはどんなイベントか、公式サイトから拝借すると

PHPerKaigi(ペチパーカイギ)は、PHPer、つまり、現在PHPを使用している方、過去にPHPを使用していた方、これからPHPを使いたいと思っている方、そしてPHPが大好きな方たちが、技術的なノウハウとPHP愛を共有するためのイベントです。

という 過去・現在・未来PHPerに向けたお祭り のようです! 他のカンファレンスと同様に公募トークがありつつ、数人で特定のテーマについてディスカッションするInteractive Round Tableや、アンカンファレンスなどちょっと違ったことも企画されているとのこと!

タイムテーブルもすでに発表されているので興味がある方は要チェックです!

タイムテーブル | PHPerKaigi 2019 - fortee.jp

3日間にかけて行われる大規模なイベントなのでどのトークを聞こうか迷っちゃいますね。 個人的には、設計やアーキテクチャの話と、PhpStorm/コードリーディングまわりの話と最終日のLTが気になっています!

最後に

ここまで読んでくださった皆様、ありがとうございました。
そして、 PHPerチャレンジ中の皆様、お目当てのPHPerトークンはこちらです!

#EnjoyPHPWithConnehito

それでは!

コネヒトではPHPerを積極採用中です!

www.wantedly.com

「やさしいかんしのご提案」をしました 〜コネヒトなりの「監視の民主化」入門〜

こんにちは! @o0h_です。
3月は・・・王様ランキング!!!!おめでとうございます🎉

王様ランキング 1巻

https://cdn-mamari.imgix.net/authorized/5c92686d-9b58-410f-8b54-0037ac110003.jpg

さて、唐突に本題なのですが
先日、入門監視を読んで思ったこと・感じたことを当ブログに投稿しました。

tech.connehito.com

今回は、ちょっとした続編のようなものになります。

先の記事では、自分自身に生じた内省や「べき論」「目指すべき地点」を中心に取り扱いました。
具体的な「私や他のメンバーが取るアクション」や「変更されていく内容」についてはスコープにしておりません。

当然、こうもデカい口を叩いた以上は、実践をしていく必要があります。
でないと・・・ダサダサ君になってしまいますよね。
そんな訳で、「実際に組織を変えていくぞ」と、その最初の一歩目として 監視の民主化に向けたキックオフ を行いました。*1

先日のブログのような内容が「概念」「抽象」だとするなら、こちらは「実践」「具体」に相当するものでもあります。
折角ですので、私と同じような課題感を持った人と共闘すべく、この場で公開してみます!

あくまで社内向けに企画・作成した内容なので、「内輪ならコンテキストがあるから、ちゃんと伝わるだろうけどさ」な部分も少なくありません。
それでも、今回の内容はある程度の一般性を保てているのではないか〜なんて考えています。

*1:先日、弊社にて開催した勉強会での私の発表内容もこの内容を想起しながらまとめたものになります

続きを読む

Slack Block Kitを使って既存ツールをカッコよくしてみた

こんにちは、 BLUE GIANT SUPREME (7) (ビッグコミックススペシャル)を読みました。金城(@o0h_)です。
読後、へーしゃで称賛が発生していました。

f:id:o0h:20190303130444p:plain
こちら、社長と私です

そんな感じで色々にSlackを利用している身のものですが、先月「新しい機能をリリースしたよ!」という発表がありました。
「Block Kit」です。

Block Kitは、「Slack投稿の表現力を上げる」「ユーザーと、より気の利いたインタラクションをつなぐことを支援する」ための新UI(のためのAPI)です。
これを利用すると、いつものSlackの投稿がとても高機能になります。

実際に触ってみたので、使い方やハマったポイントなどを共有していきます。

https://cdn-mamari.imgix.net/authorized/5c7ccc81-7170-439c-8949-0034ac110003.jpg

続きを読む