Japan Product Manager Conference (#pmconf) に行ってきたのでその所感などを書いてみました

pmconf.jp

先日、会社のお金で Japan Product Manager Conference (#pmconf) に行ってきました。 学ぶところが多かったので、その内容と所感を簡単にまとめてみました。 (誤植ありましたらご指摘ください、修正いたします)

トピックス

nekokak さんのスピーチ 「大規模システム開発に於けるプロダクトマネジメントについて」

[大規模システムの課題]

サービス開発は具体的なユースケースが想像できるが、大規模システムの場合はパーツごとに担当者がバラバラである。よって、各パーツの作業者は全体像が把握しにくい。 結果、抜け漏れが発生したり、必要なSpecが想定しきれず、抜け漏れが発生する可能性があった。 また、そこから起因して、モチベーションが下がってしまう作業者も発生する危険性がある。

[プロダクトマネジメント]

そこで、全体像を把握し、指揮者として、作業者に適切に伝える人が必要 = プロダクトマネージャー また、プロダクトマネージャーは適宜モチベーターとしての役割も担う必要があるだろう。

freee 「絶対失敗すると言われたプロダクトを成功させること」

そもそも、クラウド会計ソフトをやろうと思ったきっかけは、自身がALBERTでCFOとして働いていて、その時に会計関連業務に感じた課題を解消したいという思いから。

プロダクトによって、スモールビジネスに関わるみんなが創造的な活動にフォーカスできるようにしよう、と考えていた。そのために、これまでのバックオフィスの業務を徹底的に見直した。 コンセプトはスマホから5分で会計などの業務を完了させること。

プロダクトは9ヶ月の開発期間を経てリリースしたが、製作途中のインタビューではほとんど手応えが感じられなかった。殆どの人がクラウド会計ソフトという新しいものに興味を示さなかった。 しかし、それでも実際にプロトタイプまで作ってみて、改めて自分たちの作業をこのソフトを使ってやったらどれくらい業務短縮につながるか計測してみた。 結果、作業量が 1/50 程度となった。

この結果から、迷いは確信に変わり、プロダクトの完成までモチベーションを持って作り上げることができた。

あとになって思うのは、インタビューはペルソナをしっかりと定義し、そこに合致した人に対して行うことの重要性だった。保守的な人は最初の顧客になりえない。この手のサービスの場合、最初の顧客を見つけ、その顧客に最適化する形でプロダクトを成長させていくのが基本。よって、そのような人をきちんと定義してインタビューしたほうが本当は良かった。

クックパッド

クックパッドにはプロダクトマネージャーという肩書の人はいない。 クックパッドでは基本ユーザーのデータから仮説建てを行い、検証するための機能開発を行うスタイル。機能開発はあくまで検証のため、スプリットテストは必ず実施する。 効果があったものだけ、全展開する。

楽天トラベル 「What's PM?」

  • 営業
  • マーケ
  • プロダクト

PM とは、プロダクトやサービスの定義・設計を行う。 顧客を喜ばせ、戦略的な価値を会社に与えるものである。

PM が行う仕事で、必ず行うべきと結論が出ているのはドキュメンテーション。 プロダクト・サービスの定義、設計は必ず文字に落とし込むことが大事。 それがない状態での開発開始は絶対に行ってはならない。

楽天トラベルでは、ドキュメンテーションを行うことをルール化してから、開発スピードが5倍程度まで向上した。

プロダクトを作るときには、一番話者が多い英語で作り始めましょう。話者が多ければ、市場も大きく、結果投資も集まりやすく、世界を取る確率も高まります。

メルカリ 「メルカリ流グローバルなプロダクト開発」

社内リソースの9割をUS開発に当てている。 これを明確にすることで、「どっちのほうが優先度高いんだっけ?」みたいな無用な議論を発生させる必要がなくなった。 新機能はUSにどんどん入れて試し、良かったものを一部JPにも適用、というような考え方。 ソースコードは共通化されており、if文を外せば適用される、という感じ。

[PMにとって邪魔なもの]

  • 余計な説得
  • 余計なツッコミ
  • 余計な心配

メルカリでは経営陣がスピードにこだわっており、とにかく権限委譲をしてくれる。 承認会議もスラックで報告するだけでよくなった。 スピードを高めるためには、経営陣の理解が不可欠である。

学んだこと

  • PM の役割
    • プロダクトやサービスのプロフィールを作り、設計をする
    • 一度出荷したら、その後は定常状態にしない。変化の仕掛けを作る。
    • 顧客を喜ばせ、会社の価値を高める
  • PM に期待されていること
    • プロダクトを出荷させる
    • 市場に受け入れられるプロダクトを作る
  • PM に求められる能力
    • 問題解決
    • コミュニケーション能力
      • 技術の会話ができ、エンジニアからリスペクトされる
    • プロジェクトマネジメント
  • バグの定義
    • 仕様と実際の振る舞いが異なること
      • 仕様に書いていないものはバグではない!!!
  • スピードを高めるためには何が必要なのか
    • 経営陣の権限譲渡が極めて重要

Ubuntu 15.10 から LINE にアクセスする

Ubuntu から LINE にアクセスしたかったので。

http://altrepo.eu/git/purple-line

今回は、これが良いらしいので、使うことにしました。 libpurple を LINEプロトコルに対応させるプラグインのようです。

pidginディストリビューションで標準的なメッセンジャーツールですが、 未インストールの場合、apt-get でいれておきます。

sudo apt-get install pidgin

purple-line をコンパイルするには、libpurple の開発環境と Apache thrift が必要らしいです。

libpurple の開発環境

sudo apt-get install libpurple0 libpurple-dev libpurple-bin

Apache thrift

$ sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev python-dev

最新のソースコードをダウンロードしてきます。

http://www.apache.org/dyn/closer.cgi?path=/thrift/0.9.3/thrift-0.9.3.tar.gz

※ 私はホームディレクトリに src というディレクトリを掘っているので、そこに落とします。

$ cd ~/src/thrift-0.9.3/
$ ./configure
$ make
$ sudo make install

その他 install しておくべきもの

$ sudo apt-get install libgcrypt-dev

purple-line

$ git clone http://altrepo.eu/git/purple-line.git/ ~/src/purple-line

purple-line を取得してきて、

$ cd purple-line
$ make
$ sudo make install
$ sudo ldconfig

起動

Pidgin を起動し、アカウント種別の中からLINEを選択します。 ユーザー名にメールアドレスをいれ、パスワードを設定すればみることができます。

References

ubuntu 15.10 における resolvconf まわりの初期設定

私の環境だと、 ubuntu 15.10 におけるデフォルトの resolvconf 設定だと、 頻繁に google.com の名前解決ができなくなる現象が発生した。

これを解決するために、以下を実施した。

  • eth0 に固定アドレスを設定
  • /etc/avahi/avahi-daemon.conf の domain-name の箇所を domain-name=.alocal と修正
  • /etc/nsswitch.conf を修正
  • /etc/NetworkManager/NetworkManager.confdns=dnsmasqコメントアウト

eth0 に固定アドレスを設定

eth0 に固定アドレスを設定するようにした。 (/etc/network/interfaces, /etc/resolvconf/resolv.conf/base などを設定した)

例:

  • /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.11.2
    netmask 255.255.255.0
    gateway 192.168.11.1
    dns-servers 8.8.8.8 8.8.4.4

結果として、 /etc/resolv.conf が生成される

設定を有効にするには、 resolvconf コマンドを実行すれば良い。

$ sudo resolvconf -u

/etc/avahi/avahi-daemon.conf を修正

/etc/avahi/avahi-daemon.conf# domain-name=local の箇所に、

domain-name=.alocal

と追記。

/etc/nsswitch.conf を修正

/etc/nsswitch.conf の次の箇所を修正する。

変更前:

files mdns4_minimal [NOTFOUND=return] dns mdns4

変更後:

files dns

/etc/NetworkManager/NetworkManager.confdns=dnsmasqコメントアウト

dns=dnsmasqコメントアウト

Trouble Shooting

"ping: unknown host google.com" but IP's works fine

の時は resolvconf を入れなおした。

sudo apt-get remove --purge resolvconf && sudo apt-get install --reinstall resolvconf

References

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 102

homebrew 経由で mysql をインストールし利用しているのですが、先日アップグレードを行いました。 その後 mysql サーバに接続しようとしたら、下記エラーが発生し接続ができなくなりました。

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 102

調べてみると原因は、/etc/hosts.allow に記載がないためのようでした。

/etc/hosts.allow で接続を許可するホストを記述します。

mysqld: ALL: allow

あとは、反映させるために再起動をかけて完了です。

$ mysql.server restart
Shutting down MySQL
.... SUCCESS!
Starting MySQL
.. SUCCESS!

References

mysql2 gem 経由で MySQL サーバ接続時ライブラリの `LoadError` が発生する

mysql2 gem 経由で MySQL サーバに接続しようとすると、ライブラリ /usr/local/lib/libmysqlclient.18.dylibがロードされず、LoadErrorが発生しました。

/Users/username/reposname/vendor/bundle/ruby/2.3.0/gems/mysql2-0.4.3/lib/mysql2.rb:31:in `require': dlopen(/Users/username/reposname/vendor/bundle/ruby/2.3.0/gems/mysql2-0.4.3/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/lib/libmysqlclient.18.dylib (LoadError)
  Referenced from: /Users/username/reposname/vendor/bundle/ruby/2.3.0/gems/mysql2-0.4.3/lib/mysql2/mysql2.bundle
  Reason: image not found - /Users/username/reposname/vendor/bundle/ruby/2.3.0/gems/mysql2-0.4.3/lib/mysql2/mysql2.bundle

今回僕がこのような状況になってしまった原因は、 brew update し、既存の MySQL を更新してしまったためです。 これにより、既存のライブラリへの参照を消してしまったのでした。

よって、これを解消するために、消してしまった参照を再度付け直します。

$ sudo ln -s /usr/local/Cellar/mysql/5.6.17_1/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib

これで解消されました。

References

http://stackoverflow.com/questions/5446747/ruby-mysql2-gem-not-working-mac-os-x-snow-leopard-ruby-1-9-2

エッセンシャル思考を読んだので、まとめてみた

グレッグ・マキューン氏の「エッセンシャル思考」を読んだので、自分用に内容をまとめてみた。

エッセンシャル思考とは

エッセンシャル思考は3つのコンセプトでなりたっている。

  • 選択
    • → 「やらなくては」ではなく「やると決める」
  • ノイズ
    • → 「どれも大事」ではなく「大事なものはめったにない」
  • トレードオフ
    • → 「全部できる」ではなく「なんでもできるが、全部はやらない」

選択

世の中には魅力的な選択肢で溢れている。 よって、我々は長い間、どんな選択肢があるかにばかり目を向けており、選ぶ能力を見過ごしてきた。 しかし、選ぶことを忘れると、自分の意思がなくなり、他人の選択を黙々と実行するだけになり、無力感にとらわれてしまう。 「選ぶ」という行為の価値を再認識し、大切に実行せよ。

ノイズ

「ほとんどあらゆるものは、徹底的に無価値である」に基づき、努力の量と成果が比例するという考えを捨て去る。 やるべきことを正しく選べば、その見返りはとても大きいことを理解する。

トレードオフ

トレードオフは回避できないと心得る。 それを認めたうえで、むしろチャンスと捉え、自分のほんとうの望みを明確にし、理想的な成功を目指す。

見極める技術

エッセンシャル思考の人は、何かに手を出す前に、幅広い選択肢を慎重に検討する。 そして「これだけは」ということだけを実行する。 行動を起こす数は少ないが、やると決めたことについては最高の結果を出す。

したがって、数ある選択肢の中から本質的なものを見極めるための技術を身に付ける必要がある。

これを支える5つの要素は以下のとおりである。

  • 孤独
  • 洞察
  • 遊び
  • 睡眠
  • 選抜

孤独

じっくり考えるには、誰にも邪魔されない時間が必要である。 そして、集中するためにはそうせざるを得ない状況を作る必要もある。 コレを実現するために、一人になれる場所で、時にはオフライン環境に身をおいて集中する必要がある。

洞察

情報の本質を掴み取る力も必要である。 そのためには以下の力をトレーニングするのがよい。

  • 大局をみる
  • 情報をフィルタリングする
  • ジャーナリストの目を手に入れる

ジャーナリストの目を手に入れるというのは、カオスな環境から、誘惑に惑わされずに本質をつかみとる力を手に入れる、ということである。 これをトレーニングする良い方法として、

  1. 日記をつける
  2. 現場を見る
  3. 普通を知り、逸脱を探す
  4. 問題を明確にする

がある。

1 の日記について細くしておく。人は忘れやすい生き物であるという前提のもと、脳のバックアップ装置として日記を書く。これを定期的に見返すことで、正しく大きな流れを把握することができ、結果としてまとめてみた時に大きな違いに気づくことができる、という狙いがある。

遊び

遊びは、選択肢を広げてくれるし、ストレス軽減もしてくれるし、脳の高度な機能を活性化したりもする。 よって、本質は遊びの中から生まれることが多い。

睡眠

優秀なビジネスパーソンは皆睡眠を重視している。 睡眠を犠牲にするということは、自分自身という資産をないがしろにすることである。 継続的により良いパフォーマンスを発揮するためにも、睡眠の優先度を高く持とう。

選抜

選択の基準をとことん厳しくすることで、瑣末な選択肢を容赦なく切り捨てられる。 明確で厳しい基準があれば、誰でも不要な選択肢をシステマティックに却下し、重要な選択肢を選び取ることが可能になる。

捨てる技術

見極める技術により、「いるもの」と「いらないもの」に分類することはできた。 この章では、「いらないもの」を捨てる技術として以下の5つの技術の説明がある。

  • 目標
  • 拒否
  • キャンセル
  • 編集
  • 線引

目標

たとえば、プロジェクトにおける目的や戦略を考える。 これらが「かなり明確」か「完全に明確」かでは大きく異ってくる。 「完全に明確」でなければ、人を動かせないし、目的の分からない仕事はメンバーとしてやる気がでないのだ。

「完全に明確」を実現するには、達成をどう判定するかが重要である。 例えば、「ニューオリンズの下9地区に住む世帯のために、低価格で環境に優しく、災害に強い家を150戸建設する」というメイク・イット・ライト財団の目標は、具体的でリアルであり、完全に明確である。

拒否

大切なことを知っていれば断ることはできる。 自分の中で優先順位を明確に持ち、上手に「ノー」という技術を身につけることで、周りに禍根を残さず拒否できるようになる。

キャンセル

「サンクコストバイアス」による心理的バイアスがキャンセルを難しくする。 所有しているものを上手に手放すテクニックとして、以下がある。

  • 持っていないふりをする
    • 「まだコレを持っていないとしたら、手に入れるのにいくら払うか?」
  • 「もったいない」を克服する
    • → 頑張って流されない
  • 失敗を認め、成功に向かう
    • → 失敗は恥ずかしいことではない
  • 逆プロトタイプ
    • 何かをやめるとき、本格的に撤廃する前に、簡単な形で試験的にやめてみる

編集

編集は、不要なものや余分なものを容赦なく削り、作品の本質を取り出す仕事。 ツイッターの共同創業者のジャック・ドーシーは、CEOの役割を「最高”編集”責任者」と定義した。 → 「エンジニアやサポート担当やデザイナーが次から次へとアイデアを持ちかけてくるが、その中から1つのことを実行すると決めるのがCEOの仕事である」

編集の4原則

  1. 削除する
  2. 凝縮する
  3. 修正する
  4. 抑制する (作品に手を入れ過ぎない)

線引き

隣人が、全く芝生に水をやらない人だったとしよう。あなたがスプリンクラーをつけると、水の勢いが強すぎていつも隣の芝生に降り注ぐ。 あなたの芝生は枯れそうになるが、隣人は自分の青々とした庭をみて、「今日も調子がいいな」と満足している。あなたの努力は無駄になるし、隣人はいつまでたっても水やりの習慣を身につけない。

塀を立てなさい。問題をあなたの庭から追い出して、隣人のもとに帰してやるんです。

しくみ化の技術

見極める技術、捨てる技術を身に付ければ、エッセンシャル思考の実践をすることは可能である。 しかし、それを継続するためにはしくみ化が必要である。 一旦やるべきことをきめたら、それを無意識に実行できるようにするということだ。

  • バッファ
  • 削減
  • 前進
  • 習慣
  • 集中
  • 未来

バッファ

学生37人に、卒業論文の執筆に何日かかるかという質問をしたという実験の結果が面白い。 「すべてが上手く言った場合」の見積もりは、平均で、27.4日間。 「何もかもうまく行かなかった場合」の見積もりは、平均で48.6日間だった。 しかし実際に執筆に掛かった時間をみてみると、平均時間は55.5日間で、最悪の場合の見積もりを超えていた。 当初予想した時間内で終わらせた学生は、たったの3割だった。 皆、見積もりが甘すぎる傾向にあることは認めるのだが、それでも目の前の仕事を見積もる段になると甘すぎる見積もりをしてしまう。

なぜ実際よりも短く見積もってしまうのかという理由については諸説あるらしいが、「周囲により良く見られたいから」という説がなかなか興味深い。匿名で見積もりをさせた場合には、計画錯誤が起こらなかったという報告もある。

基本的に、見積もりを守れない前提で1.5倍で考えておくとうまくいく。

また、シナリオ・プランニングを行うことで、正しいバッファを想定することができる。

  1. このプロジェクトにはどのようなリスクがあるか?
  2. 最悪の場合、どんなことになりうるのか?
  3. 周囲の人への影響はどのようなものがあるのか?
  4. そのリスクは自分(会社)にとってどの程度経済的に負担となるか?
  5. リスクを減らすためにどのような投資を行うべきか?

削減

「ザ・ゴール」で扱われていたボトルネック:バービーを改善する方法がこの”削減”である。 ザ・ゴール式、うまく削減するための3つのコツは以下のとおり。

  1. 目指すことを明確にする
  2. ボトルネックを明確にする
  3. 邪魔なものを取り除く

前進

最初から派手な目標を立ててしまうと、達成度合いが小さく過ぎて成長が感じられず、結果続かなくなってしまう。 心理学の研究によると、人間のモチベーションに対して最も効果的なのは「前に進んでいる」という感覚である。小さくても前進しているという手応えがあれば、未来の成功を信じられる。そのまま進み続けようという力になる。

大事なことは、「早く小さく」始め、最小限の進歩を重ねつつ、その進歩を目に見える形にすることである。

習慣

決まりきった行動は、賢い人の場合、高い志のあらわれである。

→ 本質的な行動を無意識化しよう

同じことを複数回実行することで、ニューロン同士の間に新たな結びつきが生まれる。 何度も反復することで、結びつきは強化され、情報の伝達がスムーズになる。 これが習慣である。

習慣化すれば、それほど努力しなくても自然にうまくいくようになり、効率も上がる。 また、習慣にすることで、一旦脳に回路がつくられるので、それまで思考や判断に使っていた領域が別のことに使えるようになる。 これにより、重要な仕事を無意識にこなしながら、同時に別の作業をすることも可能になる。

集中

最高の力を発揮するために、「今、この瞬間」だけを意識する。 過去や未来についてとらわれると目の前の大事なことが疎かになってしまう。

未来

エッセンシャル思考の考え方を心の底まで染み込んだ時、自分を内側から変える力になります。

エッセンシャル思考のリーダーシップ

  • 目的が完全に明確になるまで話し合う

非エッセンシャル思考のリーダーは目的が不明確なので、中途半端にあらゆることに手を出そうとする。 その下で働かされるメンバーは、山程仕事を振られてどの方向にも少しずつしか勧めない。 どうでもいい作業に時間を費やし、重要な仕事に手が回らない。 目的を明確にすると、チーム全体の結びつきが緊密になる。 全員が同じ所を目指し、一致団結して進んでいける。 チームがばらばらになることを防ぐためには、とことん明確な目的が不可欠なのだ。

  • メンバーの役割をあいまいにしない

各メンバーの役割をとことん明確に規定する → 全員が自分の役割を完全に理解し、さらに自分以外の役割も全て把握できる

PayPalの創業者ピーター・シールのやり方:全社員にたった一つの仕事だけをやらせる

  • 小さな進歩を重ねているかどうか、適切にチェックする

地方ではなく都心部に住みたい理由

先日飛騨高山に旅行に行ってきました。片道電車で5時間 (新幹線で名古屋までいって、そこから特急に乗って2時間半という立地なので)かかります。 この高山、観光地としては上等で、飛騨牛と古い町並みを武器としており、僕が訪れた時も多くの観光客で賑わっていました。

f:id:libitte:20151122154142j:plainf:id:libitte:20151122154434j:plainf:id:libitte:20151122154503j:plain

飛騨高山はとても素晴らしかったです。 しかしそれは、2泊3日という短期で過ごすという観点で言えば、です。

僕は地方ではなく都心に住んでいるのですが、なぜ高い家賃を支払ってまで都心部に住みたいのか、そのあたりを整理しておきます。

理由は以下の2つです。

自分の業界に近い人が多い

  • 優秀な人とのエンカウント率が高まる
    • 優秀な人からの刺激は自分にとってはモチベーションの源泉です
  • 情報が入ってきやすい
    • Web上にある情報ではなく、もう少しウェットな情報はやはり人から入ってきます

地理的に店が密集しておりオフライン体験の選択肢が充実している

  • ほしいものがあった場合、実際にみて購入することができる
  • 食事処など、選択肢が多く(結果良店も多い)、飽きない

最後に所感ですが、やはりオフライン体験重要だなーと思いました。 理由の一つ目については、自分の業界が例えば製造業などであった場合、むしろ地方のほうが良いということになると思います。 しかし二つ目についてはどうしても地方だと実現が難しいかなと。

Fashion tech meet up #1 で MERY PASS 立ち上げにおける開発プロセスについて LT してきました

かなり遅くなりましたが、先々週 Fashion tech meet up #1 が MERY x iQON のテックミートアップが開催されました。

fashion-tech.connpass.com

ここでLTをちょろっと発表しましたので資料へのリンクをこちらにも掲載しておきます。

www.slideshare.net

LTでは、私が開発を担当した MERY PASS の立ち上げまでの開発プロセスについて話しました。

pass.mery.jp

MERY PASS立ち上げという自分の実経験を基に、特に必要となってくるプロセスを選定し説明しています。

ご興味のある方はご覧いただけますと幸いです。

Error: "Not a valid object name" on deploying with Capistrano 3

deploy 中に下記のようなエラーが発生した.

The deploy has failed with an error: Exception while executing as foo-bar-user@{MY_IP_ADDR}: git exit status: 2
git stdout: fatal: Not a valid object name
tar: This does not look like a tar archive
tar: Exiting with failure status due to previous errors
git stderr: Nothing written

原因はただ単に指定ブランチを間違えていただけだった.

It looks like you might not have pushed your 'development' branch to your remote repository and git is failing trying to archive your local 'development' branch.

stackoverflow.com

Active Record create の戻り値

Creates an object (or multiple objects) and saves it to the database, if validations pass. The resulting object is returned whether the object was saved successfully to the database or not.

http://api.rubyonrails.org/classes/ActiveRecord/Persistence/ClassMethods.html#method-i-create

「The resulting object is returned whether the object was saved successfully to the database or not.」

これは盲点だった。

つまり、以下のように書いてしまうと間違い。

create は save の成功可否にかかわらず、一応結果オブジェクトを返してしまうので、これだと必ず succeeded_path にリダイレクトされる。 失敗している場合、MyModel にレコードは作成されていない。

if MyModel.create(myparams)
  redirect_to succeeded_path and return
else
  redirect_to failed_path and return
end

正しくは、何でもいいが例えば例外を使わないなら、下記のようにする。

my_model = MyModel.new(myparams)
if my_model.save
  redirect_to succeeded_path and return
else
  redirect_to failed_path and return
end

ERROR 2013 (HY000): Lost connection to MySQL server at 'sending authentication information', system error: 32

起きたこと

ローカルマシンから mysql につなごうとしたら以下の様なエラーが発生し繋げなくなった。

$ mysql -uroot
ERROR 2013 (HY000): Lost connection to MySQL server at 'sending authentication information', system error: 32

原因

1 process あたりの許容ファイルオープン数を超えてしまったことが原因の様子。

MySQL 5.6 の innodb_file_per_table オプションはデフォルトで ON になっている。 ON にすると各テーブルのデータはそれぞれのファイルに保存されるようになる。

OSX の場合、1 process あたりの許容ファイルオープン数はデフォルトで 256 となっている。 この数字は通常問題にならないが、 parallel に unit test を実行していたりするとあっという間に達してしまったりする。 今回はこのケースだった。

ref.

stackoverflow.com

superuser.com

MySQL で作ったテーブルに index を貼るべきかどうかの判断基準

tickets テーブルがあると仮定する。 この tickets テーブルには n レコード格納されている。

2分木ソートの場合、ソートにかかる計算量は O(n log n) で、index を配備するのにかかる計算量は O(log n) となるため、 単位時間あたりのソート回数を x, 単位時間あたりの更新回数を y とする(レコード更新のたびに index は更新される)と、 x * n * log n > y * log n もとい、x * n > y が成り立てば index を貼るべきである。

x はキャッシュなどを考慮しつつ、アクセスログなどから算出できるし、y はbatchであったり、管理画面であったり、アプリケーション内のコードなどを見れば算出できる。

ref.

ソート - Wikipedia

nc を用いた Memcached のオペレーション方法

nc を用いた Memcached のオペレーション方法についてまとめておきます。

特定のキーのデータを参照、削除する

memcached に接続するためのツールはいくつかあるが、ここでは nc を用いた方法を採用している。

telnet よりも nc(netcat) を使ったほうがいい理由は http://www.terminalinflection.com/use-netcat-not-telnet-to-test-network-connectivity/ が詳しい。

By default it opens a TCP connection to a nominated port, but this flexible port argument is more of a side effect of its function as an interactive console, and not its real function. So from now on, you should be using netcat – which is executed as nc.

また、nc コマンドのオプションの説明と詳しい使い方については http://www.computerhope.com/unix/nc.htm に綺麗にまとめられている。

memd の host が localhost, port が 11211 だとすると、以下のように接続できる。

nc -C localhost 11211

接続できたら後は memd のコマンドでオペレーションできる。 以下はキー views/10watch.jp/products/35030?part=xxx に対してのオペレーション例。 get でデータを取得し、 delete でそれを削除している。

get views/10watch.jp/products/35030?part=xxx
VALUE views/10watch.jp/products/35030?part=xxx 401
{DOMが表示されます}
END
delete views/10watch.jp/products/35030?part=xxx
DELETED

特定のキーの有効期限を知る

オペレーション手順に入る前に Memcached はデータをどのようにキャッシュしているかについて説明する。

Memcached には Slab Allocation というものがある。 メモリの使用量を最適化したり、データが失効したときのメモリの断片化を防いだりする。 これはどういうものかざっくりと説明すると、 memcached は確保したメモリを予め設定された値(Growth Factor)をもとに固定長のchunkに分割していて、 データをキャッシュする際、そのデータサイズに応じて適切な chunk に割り振っている。

(より詳細な Memory Allocation の説明は http://docs.oracle.com/cd/E17952_01/refman-5.6-en/ha-memcached-using-memory.html などを参照のこと)

これを踏まえると、特定のキーを参照するためには、slabs を取得し、そこから各itemをたどっていく必要があることがわかる。

host を localhost, port を 11211 とすると、 slab 一覧を取得するには、stats slabs コマンドを発行する。

$ echo 'stats slabs' | nc localhost 11211
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 4
STAT 1:total_chunks 43688
STAT 1:used_chunks 43687
STAT 1:free_chunks 1
STAT 1:free_chunks_end 0
STAT 1:mem_requested 3898654
STAT 1:get_hits 14208428707
STAT 1:cmd_set 1164771362
STAT 1:delete_hits 1
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
...

次に、一覧の中から chunk size を目安に slabid を絞込、item数を取得する。

$ echo 'stats items' | nc localhost 11211 | grep "9:"
STAT items:9:number 1747
STAT items:9:age 70
STAT items:9:evicted 21194795
STAT items:9:evicted_nonzero 21194795
STAT items:9:evicted_time 69
STAT items:9:outofmemory 0
STAT items:9:tailrepairs 0
STAT items:9:reclaimed 50329
STAT items:9:expired_unfetched 31246
STAT items:9:evicted_unfetched 20696155
STAT items:19:number 8280
STAT items:19:age 3535
STAT items:19:evicted 942789
STAT items:19:evicted_nonzero 942789
STAT items:19:evicted_time 3533
...

item数が 1747 とわかったので、slab 内のキー一覧から目的のキーで grep する。

$ echo 'stats cachedump 9 1747' | nc localhost 11211 | grep "part=xxx"
ITEM views/10watch.jp/products/35030?part=xxx [427 b; 1435060800 s]

このデータは ITEM {key_name} [{cache_size} b; {expires_at} s] であるため、1435060800 が失効日時とわかる。 unixtime を変換して 2015/06/23 21:00:00 とわかる。

ref.

Webアプリ開発の実装力向上に有効な手段は良い仕様をたくさん学習すればよいのではないか

良い実装ができるようになりたいとする。

良い実装ができるようになるためには良い仕様を策定できることが必要と考える。 良い仕様というのは様々なニーズに対応できるということなので、 どのようなニーズがあるのかを知り、そのニーズに対する良い解決策(=仕様)を学習することで、良い仕様を策定できるようになると考える。

さて、RailsはWebアプリ開発を効率的に行うためのナレッジ集だと考えている。 つまりRailsの提供する機能はWebアプリ開発における効率的な開発を行うための様々なニーズに対応できるものであると思う。

よって、Railsの提供する機能を知ることは、Webアプリ開発における効率的な開発をするための様々なニーズを解消するための仕様を知ることとなるし、 これらの機能はなぜこの仕様なのかを考え理解することは、良い仕様を学習していることにほかならない。

したがって、Railsの提供する機能を満遍なく理解することはWebアプリ開発における良い実装ができるようになることにつながると考える。

なんとなく気持ちの整理をしておく

私は新しいビジネスモデルとか新しい技術とかには興味があって、「なぜ?」というのはすごく気になって調べたりするんだが、 それがある程度わかるとなんとなく興味がなくなってしまう。 それ以上深いところを知りたいというモチベーションが湧かなくなってしまう。 結果、専門性を深めることができないが、なんとなく知っていて、それを使うことは一応できるということになる。 しかし、この状態でそれを使っていても、それほど興味もないためモチベーションも継続しにくく、ひたすら「作業」と感じながらそれを継続することとなる。

きっと今まで勉強してきた知識の中で興味が強いものを選択しそれを深めることが、とりあえず専門性を身につける上で最短距離となるのであろう。

それはわかっているのだが、私はここで経験上、「もしかしたら私には専門性を深めるためのモチベーションがあまりないのではないか」という不安がよぎる。

このような考えは大学院での研究生活の中で生じた。 研究者を目指して大学院に進学したものの、実際に研究生活を送る中私は博士やポスドクの方々と比較して物事を深く知りたいというモチベーションが不足しているのではないかと。

そうはいっても、専門性を身に付けることを諦めてしまうことは人生を、お金のためにひたすらつまらない「作業」続けてなんとか生きていくものとしてしまうと思われるため、諦めてしまうことはどうしても避けたい。

そうすると、「私はまだ本当に興味のある分野をみつけることができていないだけだ」というかすかな仮説にすがることとなる。

それが私の現状である。