時差のあるリモートワークをやってみて

こんにちは、インフラストラクチャー部データ基盤グループの井上寛之(@inohiro)です。私事ですが今年の3月から、時差のあるリモートワークを行っています。今のところ主観的にも、客観的にもうまくいっている状況です。友人・知人にそのことを話すと、「実際のところどうなの?」「どうやってるの?」と聞かれることも多く、今回は日本にいるチームメンバーとの仕事のやり方、また私自身が心がけていることを紹介します。

背景

私が所属している インフラストラクチャー部データ基盤グループは、主にデータウェアハウス(DWH)の開発を行っています。具体的には、サービスのログやユーザーのマスターデータを継続的に取り込み、サービス開発のためのデータ分析や広告配信のためのシステム(DMP)に貢献しています。また、DWHユーザーのアカウントを発行したり、分析的なSQLの相談に対応したりしています。

クックパッドは、現在(2017年3月末時点)62カ国17の言語でサービスを提供しています。日本以外で比較的大きな拠点がブリストル(UK)、アリカンテ(スペイン)、ジャカルタ(インドネシア)に存在し、サービス開発およびコミュニティのサポートを行っています。日本のクックパッドと、海外のクックパッドのコードベースは異なりますが、データ分析のプラットフォームはDWHで統一されています。また、DWHの開発はデータ基盤グループが行っています。そこで、個人スキーマ作成や、新しいデータの取り込みなどの依頼は日本のみならず、世界各地のDWHユーザーから行われます。

前述の通り私は2017年の3月より、家族の都合でアメリカ西海岸に引越しましたが、引き続きデータ基盤グループの仕事を行っています。渡米の前に、部署を変えること(必然的に仕事内容も多少の変化があるはず)を検討しましたが、結局同じチームのままになりました。この辺の細かいところは個人で状況が異なると思うので省略しますが、私にとってはそれまでの仕事を引き続き行うという判断が正解だったと思っています。これまで一緒に仕事をしていたチームメンバーなので、仕事のやり方が理解できていると言うのは大きいです。

肝心のタイムゾーンは太平洋標準時(PST, UTC-8)ですが、現在は夏時間の期間なので太平洋夏時間(PDT, UTC-7)になります。日本が土曜日の朝になったとき、こちらが金曜日の夕方という感じです。ちなみにブリストルやアリカンテのあるヨーロッパが金曜日の夕方になる時、こちらは金曜日の朝になります。

クックパッド社内でリモートワークをやっている人は私だけではありません。個人や家庭の都合でリモートワークをやっている人、またある国では現地にコミュニティマネージャーしか社員がいなく、オフィスがまだ無いのでリモートワークと言う人もいます(アメリカにも現在オフィスはありません)。ただし、それぞれのやり方はほぼ共有されていないのが実情です。

具体的にやっていること

さて、具体的にチームと仕事をどうやっているのか紹介したいと思います。

1. 毎日朝会にビデオ参加する

日本でもチームで朝会を行っていたように、最近全社に導入されたZoom を使って、5分程度の朝会を行っています。日本の11時、こちらの19時なので私にとってはその日やったこと報告、相談する場になっています。

2. 重要なプロジェクトでは週一でビデオ会議をする

日本にいた頃から継続していた複数人で進めているプロジェクトについては、週に1回程度のビデオ会議を行いました。書くまでもありませんが、お互いの認識に相違が生まれないように、また発生してしまった相違を早い段階でなくすことができます。

3. 時差を活かす

時差があることは一見不便な点が多くありそうですが、視点を変えると便利だったりもします。例えば、こちらの昼間は日本の深夜なので、落ちたバッチジョブに迅速に対応することができています。また、前述の通り世界各地にある拠点から発生するデータ関連の依頼に対して、日本の営業時間よりも早く対応することができています(データ基盤に関するチームは現在日本にしかありません)。

4. 柔軟にやる

これはどちらかと言うと考え方になります。チームが必要と思えば、やり方をすぐに変えてみよう、うまくいくやり方を見つけようという考え方です。上で書いた朝会にビデオで参加する、というのは、渡米直後には行っていませんでした。チームのマネージャーとは週1程度でビデオで面談をやる予定を決めていましたが、朝会をやったほうがチームとして仕事がしやすくなると判断し、毎日行うようになりました。

やはりコミュニケーションが課題になるため、柔軟にやらないとどんどん考えていることがズレていってしまうという危機感が常にあります。

心がけていること

また、私個人が心がけていることを紹介します。

1. 仕事が見えるようにする

仕事が進んでいるのが分かるように意識しています。近年では Slack にGithub へのコメントが流れたりするので、ちゃんとやってれば勝手に見えるようになります。しかし、少し早めの段階でプルリクエストしたり、雑に イシューを立てておいたりすることで、より「仕事してますよ」感を出していくことが重要だと考えています。

さらに、これは日本にいたときからの習慣ですが、任意の日報を社内ブログに書いています。実際のところチームメンバーが見ているかどうかは不明ですが、自分のための記録としておすすめできます。

ちなみにチームとしてのタスク管理にはPivotal Tracker を使っています。PivotalTracker を見ることで誰がどのタスクを担当していて、いまどんな状態(着手、未着手、完了、…)なのかが分かります。また2週間に1度はイテレーションミーティングを開催し、そのイテレーション(2週間)に片付けたタスク、次のイテレーションで誰が何をやるのかをチーム全員で見直しています。もちろん私はビデオで参加しています。

2. 脱線を予防する

仕事中は完全に一人になることが多く、脱線を予防することが重要と考えています。業務上 2,30 分かかるようなSQLを実行することが多く、待っている間にふらっと SNS などを眺めだしてしまうと危険です。古典的ですが、/etc/hosts ファイルに任意のサービスのドメインを localhost に向けると言うのは結構効き目があったりします(SNSは息抜きに携帯電話から見るようにする)。

また、私は家からフルリモートという働き方だと、経験上なかなかスイッチを切り替えるのに時間がかかると判断し、コワーキングスペースから仕事をするようにしています。

3. 仕事にやりにくさについて率直に聞く

私が仕事をやりやすいと思っていても、日本にいるチームメンバーがやりにくいと考えているならば何か対策をする必要があります。一時的に帰国した時や面談で「実際リモートワークやりにくくないですか?」と率直に聞くようにしています。

まとめ

時差のあるリモートワークから得られた知見や経験について、特に日本にいるチームメンバーとの仕事のやり方、また私自身が心がけていることを紹介しました。

クックパッドに限らず、リモートワーク等の比較的自由な働き方が増えつつあると感じていますが、時差があるとよりコミュニケーションに気を使う必要があると考えています。今までと同じように仕事ができることや、チームメンバーの協力に感謝しています。一方で、私は「リモートだからできない」と言うような、リモートを言い訳にしないように、むしろ時差を活かしたリモートだからこそできることを増やしていきたいと考えています。

他社で同じような状況でお仕事されている方の Tips など教えていただけると参考になります。

Slack 上のエンジニア同士の会話を増やした一つの工夫 + ちょっとした OSS の紹介

こんにちは、技術部開発基盤グループの小室 (id:hogelog) です。

最近エンジニアが全員集まる Slack のチャンネルからデプロイ通知等の機械的な通知を排除したらエンジニア同士のコミュニケーションがほぼ毎日発生するようになり満足しています。自分のような無名なペーペーエンジニアも業界に名を馳せる著名エンジニアもフラットに属しているチャンネルが通知で埋まっていて人間の会話がまったく発生しないなんてもったいないですからね。Slack のチャンネルをどう運用するか会社によって文化の違いがあると思いますが、良い運用は参考にしたいので各社どんどん発信してほしいのでよろしくおねがいします。

さてそんな話で終わっても良いのですが、ここは開発者ブログだしせっかくなので最近開発した Slack 関連のアプリケーションを紹介します。

tokite で GitHub から Slack への通知をカスタマイズ

クックパッドでは GitHub Enterprise (以下 GHE) 上で日々開発やレビューなどをおこなっています。そこで生まれる Issue や Pull Request などを Slack に通知するためのツールとして tokite というツールを実装しました。

https://github.com/hogelog/tokite

今までは主にメールとJasper *1 等を利用して GHE 上でのレビューやコミュニケーションを進めていました。 Slack 通知も利用していましたが、GitHub の Slack 通知はリポジトリ毎の設定しか存在せず、自分が見たい通知のみを特定のチャンネルに流すといったことはできませんでした。

それを解決するため作成したのがユーザ毎のルールで通知を設定できる tokite というツールです。

f:id:hogelog:20170719111939p:plain

tokite のルール

tokite ではユーザ毎に任意個数の通知ルールを設定します。ルールにはそれぞれクエリと通知先等を設定し、どのようなイベントを Slack のどのチャンネルに流したいかを決められます。

社内で運用している tokite に自分が設定しているルールは以下の3つです。

ルール名クエリ解説
opsrepo:tech-dept/ops開発基盤グループのタスク管理リポジトリの Issue を流すルール
呼ばれたbody:/sunao-komuro|dev-infra|hogelog/メンション等で自分のアカウント名、グループが呼ばれた時に流すルール
dev-infra-memberuser:/XXX|YYY|ZZZ/チームメンバーの発言を流すルール

また通知先のチャンネルは自分専用の通知チャンネルとして運用し、全発言が Notification を出すように設定しているためこれらのルールにマッチするイベントが発生すれば Slack 経由で通知が届くようになっています。

tokite の動作

tokite は各リポジトリの Webhook を元に、それぞれのイベントにマッチするルールがあれば Slack の対象チャンネルに通知するという動きをします。 ルールのクエリ実装はなにか既存のライブラリやフォーマットがないものだろうか、と少し探したのですがちょうど良いものが見当たらなかったため parslet *2 という PEG ライクなパーサライブラリを利用しました。PEG ベースのパーサライブラリは使ったことがなかったのですが、ドキュメントも丁寧で使いやすいライブラリでした。 ユーザ認証には GitHub を利用していて Webhook 追加も各ユーザのトークンをそのまま利用しています。

tokite で得られたもの

tokite を使うことでリアクションが必要な GHE 上で発生する同僚の行動 (Pull Request, Issue, Issue Comment) の通知をほぼ Slack に集約し、すぐに気付けるようになりました。

tokite を使う前でもメール、Jasper 等の経路でそれらの行動を観測することはできていました。ただし、僕にとってはそれはどうもかなり意識的におこなわなければできないことで、見逃しも度々ありました。一方で自分は Slack の通知ならばすぐに気づき自然に読み始めることができています*3。tokite による通知だけで完結するという程には至らずメールの通知や Jasper に頼っているところもあるのですが、Slack という経路が一つ増やせたのは割と実装した意味があったなと思っています。

今後の予定

tokite はある方が便利だなと感じていますが、今のところ機能は色々と足りていません。今後も OSS の形で公開しながら改善を続けていこうと思うので、よろしくおねがいします。

https://github.com/hogelog/tokite

*1:http://techlife.cookpad.com/entry/2017/03/14/100000

*2:http://kschiess.github.io/parslet/

*3:何故だろう。Slack のアプリケーションがよくできているからというのが大きい気がしている

ファイルを直接読み込んで集計する

こんにちは。マーケティングプロダクト開発部の中村です。今回は大量のデータを対象に集計できる Hive の使い方について説明しようと思います。

前提

私が所属しているマーケティングプロダクト開発部では広告配信も行っています。その広告配信では大量のアクセスログを蓄積しています。通常ですとそのログは Amazon Redshift で簡単に集計できます。しかし、ログファイルを直接集計しなければならない場合が稀にあります。その際に使用しているのが Amazon EMR です。今回は Hive を用いてその集計を手元の端末で試してみます。

インストール

まずは動作環境を作るために Hive をインストールします。

brew install hive

集計する前の準備

Hive は任意のディレクトリを作業ディレクトリとすることができます。まず、その作業ディレクトリを作成し、そのディレクトリに移動しておきます。

mkdir -p /tmp/cookpad/logs
cd /tmp/cookpad

次に、その作業ディレクトリで使用する Schema の種類を指定する必要があります。今回は資料でデフォルトで使われてる derby を選択します。

schematool -initSchema -dbType derby

ここまでの作業で、ローカルで起動させるための準備ができました。次に、実際に起動させてみます。

hive

Hive のコンソールが立ち上がれば成功です。

集計してみる

次にサンプルをもとに簡単に集計します。今回は Nginx のアクセスログをサンプルとして集計してみようと思います。具体的には以下の内容のファイルを /tmp/cookpad/logs/nginx.log として、先程作成したディレクトリ以下に保存します。

172.17.0.1 - - [14/Jul/2017:07:48:37 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:48:38 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:48:38 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:49:19 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:49:40 +0000] "GET /hoge HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:49:42 +0000] "GET /hoge HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:49:51 +0000] "GET /piyo HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:49:52 +0000] "GET /piyo HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"
172.17.0.1 - - [14/Jul/2017:07:49:53 +0000] "GET /piyo HTTP/1.1" 404 571 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36" "-"

次にそのファイルを集計するクエリを用意します。なお Hive は起動時にクエリをファイルから読み込めるため、ファイルに書いた方が後から参照できて便利です。具体的には以下の内容で /tmp/cookpad/sample.q として保存します。

drop table nginx_logs;

create external table nginx_logs (
    remote_addr string
    , remote_user string
    , time_local string
    , method string
    , path string
    , protocol string
    , status int
    , body_bytes_sent int
    , http_referer string
    , http_user_agent string
)
row format serde
  'org.apache.hadoop.hive.serde2.RegexSerDe'
with serdeproperties (
    "input.regex" = "([0-9\\.]+) - ([^ ]*) \\[([^\\]]*)\\] \"([^ ]*) ([^ ]*) ([^ ]*)\" ([0-9]*) ([0-9]*) \"(.*)\" \"(.*)\""
)
location
    'file:///tmp/cookpad/logs'
;

select
    *
from
    nginx_logs
where
    path = '/hoge'
;

その保存したファイルを指定して Hive を起動します。

cd /tmp/cookpad/
hive -f /tmp/cookpad/sample.q

クエリが実行されてアクセスログが表示されれば成功です。

UDF を書いて Hive に組み込む

Hive には様々な関数が組み込まれています。通常の集計ではその関数で充分なのですが、時折複雑な条件で集計したくなります。そのようなときは関数を自作して組み込んで使用することができます。

実際に関数を組み込んで集計してみます。ただし、少し準備することが多いので事前にコードは GitHub に用意しておきました。以下のリポジトリを任意の場所に clone してください。

https://github.com/devisualy/udf

そのクローンした場所に移動してビルドします。具体的には以下のコマンドを実行します。

mvn package

ビルド成功すると target/devisualy_udf.jar ができるはずなので Hive の作業ディレクトリに配置します。

cp target/devisualy_udf.jar /tmp/cookpad/devisualy_udf.jar

Hive を起動して組み込んでみます。

cd /tmp/cookpad
hive
hive> ADD JAR /tmp/cookpad/devisualy_udf.jar;
hive> CREATE TEMPORARY FUNCTION converter as 'devisualy.Converter';

OK のような表示が出れば成功しています

UDF を使って集計する

上記までで Hive 上で自作の関数を使う準備は整いました。次に実際にクエリを投げてその関数を使ってみます。具体的には以下のようなクエリを Hive のコンソール上で実行します。

select method, converter(method) from nginx_logs limit 1;

クエリ内で同じ method を参照していますが converter という関数の戻り値が method とは異なっているのを確認できます。

これまでの作業でできるようになったこと

上記までの作業で以下のことができるようになりました。

  • 集計対象ファイルを Hive で読み込めるようになった
  • そのファイルに対してクエリを投げられるようになった
  • そのクエリから自作の関数を呼べるるようになった

その中でも自作の関数を呼べるようになったのは強力です。クエリだけではなかなか表現しきれないビジネスロジックを表現できます。また UDF ファイルを共有することにより他人がその表現を簡単に流用することができます。

まとめ

Hive の基本的な使い方について説明しました。前提にも書きましたが、私が所属しているマーケティングプロダクト開発部では広告配信も行っているため、大量のアクセスログを蓄積しています。そのログに対してローカルで Hive を使うということは無く Amazon EMR を使って高速にログを集計しています。

AWS には、似たようなことが簡単に可能な Amazon Athena というサービスもあります。しかし、集計対象のデータが大きいと料金が高くなるため Amazon EMR を使ったほうが良い場合もあるかと思います。

これらの技術により、大量のデータを高速にかつ簡単に集計できるようになりました。次はその集計結果をどのように活用できるかです。いつかログからユーザーを想像できるようになれればいいなと思っています。