kakakakakku blog

Weekly Tech Blog: Keep on Learning!

2016年の振り返りと2017年の抱負

2016年の振り返り

実戦投入力を高めることができた

2016年の抱負として掲げた「実戦投入力を高める」という目標を大きく達成することができた1年だった.「実戦投入力」とは「プログラミング言語,ミドルウェア,オープンソースなどをサービスに投入して実践的に使うこと」と定義している.日々「○○を試した」系のブログ記事を書いているが,実際にサービスに投入するためには運用面も考える必要があるし,チームに普及させる必要があるし,メリットがあることを組織に理解してもらう必要がある.またデメリットも予め考えておく必要がある.そういった「ラストマイル」的な部分も含めて経験することによって,スキルレベルが深まるし,社外発表のネタにもなると考えていて,1年間ずっと意識してきた.

1年前と比べると,圧倒的に AWS に詳しくなったし,ミドルウェアの運用面にも詳しくなったし,モニタリング技術にも詳しくなった.ずっと憧れていたウェブオペレーションエンジニアとして働くことができて本当に良かった(正確に言うと2016年3月頃からメインでウェブオペレーションを担当している).総じて「実戦投入力を高める」という目標設定が良かったなと感じている.

大きく成果を出すことができた

「実戦投入力を高める」という目標は個人のスキルアップだけではなく,組織にも大きく影響を与えることができた.サービスの大きな課題になっていたウェブオペレーションの部分を改善し安定性とスケーラビリティを格段に上げることができたし,チームメンバーのモチベーションアップにも大きく貢献したという話も聞いた.また評価もして頂くことができて,昇進をしたり,社内表彰に何度も名前が挙がったりもした.個人的に「頑張ったら評価される」とは思っていなくて「着実に成果を出し続けて,貢献度を組織(特に経営層)にアピールする」ことを常に意識していた結果だと思う.

さらにもう1点重要だったと思うことがある.それは「愚痴らない」と決めたことだった.2015年は比較的荒れていた時期も多く,Twitter に弱音を吐いたり,友人に愚痴っていたこともあった.今年は愚痴りたくなったら「その課題を解決するにはどうしたら良いんだろう?」を考えることを徹底した.その結果として,課題が明確になったし,考えた結果,課題ではなかったと気付けたこともあったし,何よりも「次のアクションに繋がる」ことが重要だった.これもまた成果に繋がった理由の一つだなと確信している.

たくさんアウトプットした

発表(社外)

2015年と同じく計4回社外発表をした.特に10月に発表した Coursera の体験談は非常に反応が良くて,発表後の懇親会でも話が盛り上がったし,凄く楽しかった.今年は LT だけじゃなく,ロングトーク枠で発表することを目標にしたい.

発表(社内)

2015年と同じく計7回社内発表をした.社内勉強会でも本気で準備をしていて,今年は「監視入門」や「Exponential Backoff」など,ホッテントリに入った記事も多くて嬉しかった.社内勉強会の運営は引き続き担当しているので,運営ノウハウを共有する「メタ勉強会」がまた開催されたら是非参加したい.

プルリクエスト

別記事にまとめた.2017年も積極的にコントリビュートしていくぞ!

ブログ

計125回更新できた.基本的に「週2回更新」をノルマにしていて,定期的にアウトプットすることが習慣になっているのは自分でも良いことだなと思う.ただし,2017年は新たな目標のために時間捻出が重要になるため,「週1回更新」をノルマにして,余力があったら「週2回更新」にしようと思っている.

たくさんインプットした

勉強会に参加した

今年は秋頃など意図的に勉強会の参加を控えた時期もあったけど,それでも多く参加することができた.今年は技術領域もある程度絞って「Golang / AWS / Docker / 監視モニタリング」関連にフォーカスして参加していた.

Coursera を受講して修了した

「アカデミックに基礎技術を学び直したい」という強い気持ちがあった.最初は MBA(経営システム科学専攻)を取得することも候補として考えていたけど,スパンが長くなってしまうし,仕事と並行してできることを考えた結果 MOOC だな!となった.今年は Coursera で “Cloud Computing Concepts, Part 1” を受講して「分散システム論」を学ぶことができた.5週間大変だったけど,毎日楽しすぎて,ナチュラルハイな状態が続いていた.今年も絶対また受講しようと思う.詳しくは以下の記事にまとめた.

2017年の抱負

(継続)実戦投入力を高める

去年と同じく「実戦投入力を高める」ことを目標にする.去年は「技術的負債の解消」を中心に実戦投入することが多かったが,今年は「攻めるインフラ」のために実戦投入をしていきたい.やりたいことが無限にある.今の自分に満足すること無く,常に成長し続ける.

技術支援を仕事にする

今年は新たに「技術支援を仕事にする」ことを目標にアクションを積み上げていく.年末に「本当に挑戦したいこと」を発見するためにマインドマップを書いて,自分の目指している方向性に気付くことができた.自分は「技術者のためにパーソナライズしたアウトプットがしたい」ということだった.まだ「技術支援」の明確なイメージまで決められて無くて,候補としては「プログラミング指導/クラウド導入支援/ソリューションアーキテクト/サポートエンジニア/技術顧問」などを検討しているが,あまり背伸びせずに,今の自分の市場価値を考慮した上で判断したい.

英語でコミュニケーションを取れるようにする

今まで read / write を中心に使ってきた英語を speak / listening にまで幅を広げて,英語で苦労することなくコミュニケーションを取れるように学んでいきたいと考えている.具体的に言えば,海外のエンジニアとディスカッションをできるようになったり,海外イベントに登壇できるようになったりすることを想定している.まずは「英会話」を習って日常的に英語を使う機会を増やしていく.

まとめ

今年もよろしくお願いします 🙇

過去の振り返り

Amazon Athena で「郵便番号データ(CSV 形式)」を検索する

AWS re:Invent 2016 で発表されてからもう1ヶ月も過ぎてしまったけど,今さらながら Amazon Athena を実際に試してみた.検証記事は既に多く出てて,積極的に読んでいたけど,実際に動かしてみようと思った.

現在まだ東京リージョンには対応して無く,今回はバージニアリージョンを使った.ただし,S3 をバックエンドにする場合,リージョンが異なっていてもアクセスできるため,問題なく使えた.

aws.amazon.com

サンプルテーブル elb_logs

Athena のチュートリアル用に ELB アクセスログのサンプルデータが入った elb_logs が用意されていて,すぐに Athena を試すことができる.最初に試して雰囲気を感じることができた.既に多くの人が試しているし,今回は割愛する.さっそく独自データを用意して Athena を試してみた!

検証 : 郵便番号データを検索する

1. データセット

今回 Athena を試すときに以下の条件に合致するデータセットを探していた.Athena は大量データを対象にしてもパーティショニング設定をすることによってスキャン範囲を限定して軽量に動くけど,今回は試行錯誤することも考えて,フルスキャン可能な小さなデータ量にしたいと考えた.

  • CSV 形式でダウンロードできること
  • 複数ファイルになっていること
  • フルスキャンしても Athena 破産しないデータ量に収まっていること

結果的に日本郵政が公式に提供している「郵便番号データ(読み仮名データの促音・拗音を小書きで表記するもの)」が,全ての条件をクリアしていた.

  • CSV を ZIP にしている
  • 都道府県別データと全国一括データを選択できる
  • 全国一括データの CSV も 12MB 程度

www.post.japanpost.jp

2. データ変換 & データアップロード

都道府県別データ47個をダウンロードした後に以下の変換をする.

# ZIP → CSV に展開する(データ変換をするため & Athena は ZIP をサポートしていないため)
$ find . -name "*.zip" | xargs -n 1 unzip
# ZIP を削除する
$ rm *.zip
# SJIS → UTF-8 に文字コードを変換する
$ find . -name "*.CSV" | xargs -n 1 nkf -w --overwrite
# " を除去する(Mac で実行するため sed は BSD 互換になっている)
$ find . -name "*.CSV" | xargs -n 1 sed -i '' 's/\"//g'
# 半角スペースを除去する(Mac で実行するため sed は BSD 互換になっている)
$ find . -name "*.CSV" | xargs -n 1 sed -i '' 's/ //g'
# CSV → GZ に圧縮する
$ find . -name "*.CSV" | xargs -n 1 gzip

最終的に .CSV.gz ファイルが47個用意できた.

$ ls -1 *.CSV.gz | wc -l
      47

S3 にアップロードする.今回はバケット直下に zipcodes ディレクトリを用意して,そこに置いた.

f:id:kakku22:20161230084932p:plain

3. テーブル作成

S3 にデータを準備したら,次は Athena 側にテーブルを作成する.

  • データベースは sampledb を使う
  • テーブル名は zipcodes とする
  • 配置した S3 パスを指定する(末尾の / を忘れずに!)
    • s3://xxx/zipcodes/

f:id:kakku22:20161230083735p:plain

次にデータフォーマットとして CSV を選択する.JSON も選べるんだ!

f:id:kakku22:20161230085223p:plain

次にカラム定義を設定する.CSV を1行 READ して必要なカラム数を最初から表示してくれる...的なアシストは無くて,地道に Add a column を押した.全てのカラムを定義する必要はなく,今回は9カラムを定義することにした(日本郵政の README に書かれている通り,実際には計15カラム存在する).

www.post.japanpost.jp

No. データ概要 データフォーマット Athena カラム名 Athena データタイプ
1 全国地方公共団体コード 半角数字 gov_code int
2 (旧)郵便番号(5桁) 半角数字 old_zipcode int
3 郵便番号(7桁) 半角数字 zipcode int
4 都道府県名 半角カタカナ prefecture_kana string
5 市区町村名 半角カタカナ city_kan string
6 町域名 半角カタカナ address_kana string
7 都道府県名 漢字 prefecture_char string
8 市区町村名 漢字 city_char string
9 町域名 漢字 address_char string

f:id:kakku22:20161230085420p:plain

パーティショニング設定はスキップした.アクセスログなど日付別にディレクトリが分割されているデータセットを扱う場合には必須の設定になりそう.

最終的に以下のクエリが自動的に生成されて,テーブルが作成できた.

CREATE EXTERNAL TABLE IF NOT EXISTS sampledb.zipcodes (
  `gov_code` int,
  `old_zipcode` int,
  `zipcode` int,
  `prefecture_kana` string,
  `city_kana` string,
  `address_kana` string,
  `prefecture_char` string,
  `city_char` string,
  `address_char` string 
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = ',',
  'field.delim' = ','
) LOCATION 's3://xxx/zipcodes/';

4. クエリ実行

SQL ライクに実行することができた.試しにオフィス(渋谷マークシティ)の郵便番号を検索してみた.

f:id:kakku22:20161230091817p:plain

GROUP BY も書ける.

f:id:kakku22:20161230100103p:plain

Athena 便利だ!

ハマった点

郵便番号検索を動かすまでに数回ハマった点がある.全て「2. データ変換」に反映してあるけど,簡単に残しておく.結論として Athena を使う場合,データセットの事前準備が重要になる.

1. SJIS

SJIS と知らずに Athena でクエリを投げたら完全に文字化けをしてしまった.nkf で変換して対応した.

f:id:kakku22:20161230110422p:plain

2. ダブルクオート

郵便番号データは以下のように文字列を " で囲っていた.Athena では除去されずに取り込まれてしまうため,事前に sed で除去した.ちなみに int で定義されているのに " で囲まれているカラムもあって謎だった.

01101,"064  ","0640941","ホッカイドウ","サッポロシチュウオウク","アサヒガオカ","北海道","札幌市中央区","旭ケ丘",0,0,1,0,0,0

f:id:kakku22:20161230110535p:plain

3. 半角スペース

2カラム目にある「旧郵便番号」は「3桁」と「5桁」の場合があった.「3桁」の場合に半角スペースが2個付いていて,int なのに文字数を合わせているデータ構造になっていた.Athena で取り込むと int ではないため,値が全て飛んでしまって,ブランクになってしまった.よって,同じく sed でブランクを除去した.

01101,"064  ","0640941","ホッカイドウ","サッポロシチュウオウク","アサヒガオカ","北海道","札幌市中央区","旭ケ丘",0,0,1,0,0,0
01106,"06122","0612261","ホッカイドウ","サッポロシミナミク","ミスマイ1ジョウ","北海道","札幌市南区","簾舞一条",0,0,1,0,0,0

f:id:kakku22:20161230111008p:plain

今後 Athena を活用したいところ & まとめ

現在 AWS のサービスログで,直接 S3 からログをダウンロードして分析したり,Elasticsearch に突っ込んで分析したりしている場合がある.

  • ELB アクセスログ
  • CloudFront アクセスログ
  • VPC フローログ
  • CloudTrail ログ

アドホックに実行するための準備が面倒だなと感じていたため,今後は Athena を使おうと思う.ただし,パーティショニング設定は理解して使う必要があるから別途仕様を整理する.ただまぁ,1TB / $5 だからそう簡単に課金されないと思う.

またアドホックに実行するとしても,頻繁に使うにしては GUI が厳しいかもと思ってたら,先週のアップデートで QuickSight と連携したみたいだし,Redash 連携もできそうだし,Athena をバックエンドとして使う形が一般的になる気がする.

今まで AWS のサービスログに対してアドホックに分析する環境を作って無く,運用上のボトルネックに感じていたため,Athena 最高!という感じ.積極的に使うぞ!

年賀状を送るときに(笑)

タイミング良く年賀状の時期!もし年賀状を送るときに郵便番号がわからなかったら Athena で検索すれば調べられる!最高に便利だ(笑)

(素直に公式サービスを使おう!)

www.post.japanpost.jp

関連記事

elb_logs テーブルで Athena を試したり,独自データを検索するなど,基本的な操作を学ぶときに参考になった.

dev.classmethod.jp

Athena リリース直後にすぐ出た BigQuery との比較記事で「おー,Athena 凄そう」と感じることができた記事だった.

data.gunosy.io

導入しようと考えている CloudFront アクセスログの検索だった.スキーマを用意してもらっててすぐに試せそう.

blog.manabusakai.com

ログ構造的に CloudTrail ログの検索は難しそうだった.

dev.classmethod.jp

Athena のベースになっている Presto も勉強して,Presto の特性を理解しておくと良さそうだなと感じた.

repeatedly.github.io

2016年のプルリクエストを振り返る

2016/02

  • Repository : fiveisprime/marvel-api
  • Language : Node.js

アイアンマンなどで有名な Marvel が公式に提供してる API のラッパーで,Node.js で実装されている.Hubot で Marvel のキャラクター情報を返すボットを作ったときに使った.Hubot を実装しているときに,特定の条件下で marvel.creators.findByName() の動作が変なことに気付いて,API 側が期待しているパラメータになるように修正した.コメントで “amazing pull request” と書かれていてとにかく嬉しかった.

This is an amazing pull request. Thank you so much!

github.com

2016/05

  • Repository : thuss/standalone-migrations
  • Language : Ruby

Rails のマイグレーション機能を切り出した Gem で,Rails に互換性のあるマイグレーションを管理することができる.担当してるプロダクトに導入しようと検証していたときに,README に記載されている通りに動かなくて,rake に渡す環境変数名が間違っていることに気付いた.修正内容は README だけだけど,デバッグするときに ActiveRecord のコードまで読まないと原因が特定できなくて,個人的には苦労したプルリクエストだから記憶に残っている.

github.com

2016/07

  • Repository : mackerelio/mackerel-agent-plugins
  • Language : Golang

7月頃から本格的に Mackerel を導入するために検証をしていた.プラグインのバイナリは今でこそ /usr/bin に展開されているけど,以前は /usr/local/bin に展開されていたらしく,今も一部のプラグインは /usr/local/bin に残っている(シンボリックリンク).Mackerel を導入した直後の僕はディレクトリが変更されたことを知らなくて,さらに README を見ても更新されていなくて,気付けなかった.同じところにハマる人もいるだろうと思って,README を修正した.ここから Mackerel 関連のプルリクエストが増えていくことになる.

github.com

2016/08

  • Repository : mackerelio/mackerel-agent-plugins
  • Language : Golang

Fluentd を監視するために mackerel-plugin-fluentd を検証していた.動作確認をするだけではなくて,プラグインのコードも読めるように勉強していた時期だったので,たまたまコメント部分にミスがあることに気付いて修正した.

github.com

  • Repository : mackerelio/cookbook-mackerel-agent
  • Language : Ruby

僕の環境では Mackerel 関連のプロビジョニングを全て Chef で完全自動化していて cookbook-mackerel-agent を使っている.勉強も兼ねて実装を読んでいたら,既に消された attribute の記述が README に残っていることに気付いて,混乱を招かないように削除した.cookbook-mackerel-agent は非常に良くて,プルリクエストを送るような問題に遭遇したことがない.

github.com

2016/09

  • Repository : wimg/PHPCompatibility
  • Language : PHP

PHP 5.3 → PHP 5.6 にアップデートするプロジェクトを担当していたときに,PHP の非互換コードを静的解析できる PHPCompatibility を使っていて,PHP 5.4 以降で禁止となった break 0;continue 0; を検知できないことに気付いた.基本的に Sniff と呼ばれるルールを追加していく実装になっているので,検知できるような Sniff を実装した.僕が実装しているときに同じ .php が大幅にリファクタリングされていて再実装し直す必要があったり,細かくコードレビューをしてもらってロジックを書き直したり,英語表現を添削してもらったり,凄く勉強になったプルリクエストだった.感謝…!

github.com

2016/10

  • Repository : mackerelio/mackerel-agent-plugins
  • Language : Golang

Mackerel で Memcached をモニタリングしようと思って mackerel-plugin-memcached を検証していたときに,Memcached に保管されているアイテム数(curr_items)をメトリクスとして取得できないことに気付いて,修正した.マージしてもらった後に ElastiCache の追加対応をしてもらったらしく少しご迷惑をお掛けした気がする.ちょうど ISUCON の時期だったように思う.

github.com

2016/12

  • Repository : winebarrel/roadworker
  • Language : Ruby

Route 53 を Infrastructure as Code として管理する Roadworker を検証していたときに,レアケースだとは思うけど,DNS レコードに GeoLocation を使っている場合に DSL のコンバーターがうまく動かなくて,自分の AWS アカウントで動作確認をしながら修正した.プルリクエストを送る前に RSpec を流したら,Route 53 で管理している僕のドメイン設定が全て消えて,焦った話は良い思い出.

github.com

まとめ

今年のプルリクエストは計8個だった.全然多くないし,自慢できるような難易度のプルリクエストもないけど,全てマージしてもらえたことは素直に嬉しいなと思う.さらに Node.js / Ruby / Golang / PHP など幅広くデバッグする機会になって勉強になった.来年も積極的にコントリビュートするぞ!!!

Hatena Blog で記事下に関連記事を表示する Tips と約4ヶ月運用した効果

あまり気付かれてなさそうな気もするけど,実験的な施策として,今年9月から PC 限定でブログの記事下に関連記事を表示するようにデザインを変更していた! ( ゚д゚) 施策を約4ヶ月運用したので,設定方法と効果を1度まとめておこうと思った.

もともとあった課題感

Google Analytics に「ページ/セッション」というメトリクスがある.これは「1セッション中に閲覧されたページ数の平均値」のことで,ブログで言うと,流入後に複数の記事を閲覧してもらえると,値が上がっていく.逆に言うと「ページ/セッション」の値が 1 の場合,それは「直帰」となる.このブログの「ページ/セッション」は,月平均で 1.20 ぐらいで,せっかく毎週記事書いてるし,同じような技術領域の記事も多いし,もっと回遊してもらえないのかな?という課題感があった.

まずは記事下に関連記事を表示したいなと思って調べたところ,Hatena Blog で関連記事を記事下に出すテクニックは複数ありそうだった.ただし,個人的には外部サービスに依存したくなかったし,API を叩いて結果を取得するような仕組みも避けたくて,もっとシンプルな方法はないのかなと考えていたら,Hatena Blog 公式の関連記事機能(サイドバーモジュール)をカスタマイズすることで実現できることがわかった.求めてたシンプルさはこれだ!と思ってすぐに適用することにした.

www.aritai.net

Hatena Blog で記事下に関連記事を表示する 3 ステップ

ステップ 1

「デザイン → カスタマイズ → サイドバー」で「関連記事」を追加する.

デフォルトの「関連記事」だと以下のように表示される.

f:id:kakku22:20161223154018p:plain

ステップ 2

サイドバーから関連記事を非表示にするために「デザイン → カスタマイズ → デザイン CSS」に以下の CSS を入力する.

.hatena-module-related-entries {
  display: none;
}

ステップ 3

サイドバーから記事下に移動させるために「デザイン → カスタマイズ → 記事 → 記事下」に以下のスクリプトを入力する.

<div id="relateArticle"></div>

<script>
var timer = setInterval(function() {
    if (typeof jQuery != 'undefined') {
        $("#relateArticle").html($(".hatena-module-related-entries").html());
        clearInterval(timer);
    }
}, 1000)
</script>

すると,以下のように記事下に関連記事を表示することができる.

f:id:kakku22:20161223154457p:plain

効果

気になる運用効果としては,Google Analytics で以下の条件で KPI 推移を確認した.

  • 期間 : 2016/03 - 2016/12
  • メトリクス : ページ/セッション(月次)
  • セグメント : PC
  • データ : 精度優先

結果として 2016/09 以降は 1.23 or 1.24 となっていて,適用前より少しは改善しているように感じられる.ただし「大成功!」と言える効果ではないと思う.

YYYY/MM ページ/セッション ステータス
2016/03 1.20 □適用前
2016/04 1.21 □適用前
2016/05 1.20 □適用前
2016/06 1.19 □適用前
2016/07 1.22 □適用前
2016/08 1.22 □適用前
2016/09 1.24 ■適用後
2016/10 1.23 ■適用後
2016/11 1.23 ■適用後
2016/12 1.24 ■適用後

施策を実施する際は Google Analytics のメモ機能を使って日付を記録しておくと,振り返りやすくなって最高に便利!

f:id:kakku22:20161223161953p:plain

Google Analytics はとにかく機能が多すぎて難しい印象があるけど,逆引き本を読んでから幅広く活用できるようになった.仕事にも活かせるし,Google Analytics を使うなら買っておいて損はしない1冊だと思う.

できる逆引き Googleアナリティクス Web解析の現場で使える実践ワザ240 ユニバーサルアナリティクス&Googleタグマネージャ対応

できる逆引き Googleアナリティクス Web解析の現場で使える実践ワザ240 ユニバーサルアナリティクス&Googleタグマネージャ対応

記事に付けるタグの順番に意味がある

関連記事のロジックは観測する限りだと「記事の1個目のタグと同じタグを持った最新記事」だと思う.よって「重要なタグを1個目に付けると良い」という Tips があるので,覚えておくと良いかと!!!

まとめ

今年は週2回ブログを書くことを目標にアウトプットを続けていて,既に 120 記事以上書いている.記事を書く以外にも楽しさがあったら良いなと思って,Google Analytics と Search Console をメインに様々な KPI を計測しているんだけど,今回は KPI 改善施策の1個として「記事下の関連記事」を紹介した.多少なりとも効果はありそうなので,導入してみてはいかがでしょう!

Amazon Elasticsearch Service を運用して学んだこと

「Amazon Web Services Advent Calendar 2016」20日目の記事を書くぞー!

最近 Amazon Elasticsearch Service を本番環境で運用していて,そこそこに運用経験がまとまったので,どこかで LT でもしようと思って先に発表資料だけを作っていたんだけど,年内に発表できそうな勉強会が無くて,このままにしておくのも残念だなと思って,今回 Advent Calendar に資料を公開する形で参加することにした.もし良さそうな勉強会があれば発表したいので是非教えてもらえると!

qiita.com

Amazon Elasticsearch Service を運用して学んだこと

まとめ

正直言ってハマるポイントも多くある Amazon Elasticsearch Service だけど,Elasticsearch クラスタの運用をフルマネージドにできるメリットは大きいし,インスタンスタイプも柔軟に選べるし,Elasticsearch クラスタの運用に悩んでいるなら移行を検討しても良いと思う.ただ今回は全文検索エンジンなど高負荷に Elasticsearch を使うユースケースではないため,その場合はまた別のポイントでハマる可能性はあると思う.

資料は結構頑張って作ったので,誰かの参考になれば嬉しい!!!

関連記事

資料に載せた「学んだこと」の多くは既にブログにまとめてある.合わせてどうぞ!

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com

kakakakakku.hatenablog.com