ありがとう。また会おう。

ゆるいかんじで。かたのちからぬいて。やってます。

2017-01-20 第4回実践セキュリティ講座

第4回実践セキュリティ講座
https://yume-ed.connpass.com/event/48872/

参加しました。
セキュリティ、CSIRTといったところを今学んでいるところなのでちょうどよい内容でした。

以下、個人的に気になったワードを、断片的に列挙します。

  • 情報セキュリティは経営マター
  • 会社が抱えるリスク→従業員が抱えるリスク
  • 会社経営におけるリスク・・・発生確率とインパクトの2軸で考える
  • ランサムでお金振り込んで戻ってくる確率は54%という統計がある
    • 身代金を払うことは「反社会的勢力への利益供与」にあたるという解釈をする専門家もいる
  • リスクマネジメント・・・回避、低減、移転、保有 「いくら投資するか」
  • 「守れているか、気づいてないか、たまたま運良く被害にあってないだけ」
  • クレジットカード決済は 透過型よりリンク型が望ましい
  • 従業員の過半数が「情報セキュリティ的にまずい」ことに気づけば自然と報告、改善意識が高まる

2017-01-18 「第44回 脆弱性診断ええんやで」参加

第44回 脆弱性診断ええんやで(^^) OWASP Top 10 の歩き方 一歩目 - 脆弱性診断研究会
https://security-testing.doorkeeper.jp/events/55559

初参加してきました。
最近仕事がセキュリティ絡みのことをやっているので
実践的な内容の勉強会でためになりました。
ツールは実際に手を動かして見るのが大事だなと感じました。
本やWebで見ているだけよりも、感覚として掴めるのは大きいかなと。

今回の勉強会では、Top10の本当に触りだけだったので
もう少し突っ込んだところも聞きたかったなと。次回に期待です。

「足し算の順序」アナタは大丈夫?

この記事は MySQL Casual Advent Calendar 2015 の20日目です。

1ヶ月ほど前ですが、こんな記事がネット上で話題になりましたね。
r25.yahoo.co.jp
togetter.com

個人的には、算数(数学)と国語の授業を取り違えてるんじゃないかな・・・と思ってもやもやします。
数学は抽象化して扱うから、様々な定理・公式が使えるというのに
小学生どあたまの教育でこんな風に教えるんじゃ、ますます算数・数学嫌いを増やすんじゃないかと危惧したりするのですが・・・


ところで。
MySQL(に限った話ではないのですが)では、この「足し算の順序」が重要になる場合があります。

AWS上のMySQLであるRDSでは、タイムゾーンの設定がデフォルトでUTCなので、NOW() 関数を使うと 日本の標準時間(JST)とは9時間ずれた日時が出力されます

※サーバシステム時刻を確認

$ date
Sun Dec 20 12:01:54 JST 2015

※RDSに接続し、NOW()関数を出力

$ mysql -u norii -p -h norii-db.************.ap-northeast-1.rds.amazonaws.com
mysql> SELECT NOW();
+---------------------+
| NOW()               |
+---------------------+
| 2015-12-20 03:02:19 |
+---------------------+
1 row in set (0.01 sec)

なので、これを補正するには、9時間ずらす必要があります*1

mysql> SELECT NOW() + INTERVAL 9 HOUR;
+-------------------------+
| NOW() + INTERVAL 9 HOUR |
+-------------------------+
| 2015-12-20 12:02:29     |
+-------------------------+
1 row in set (0.00 sec)

時に、DBにあるデータに対し、「1ヶ月前」の日時が必要になることがあります。
素朴に現在日時に対する「1ヶ月前」を、上記の要領で求めると

mysql> SELECT NOW() + INTERVAL 9 HOUR - INTERVAL 1 MONTH;
+--------------------------------------------+
| NOW() + INTERVAL 9 HOUR - INTERVAL 1 MONTH |
+--------------------------------------------+
| 2015-11-20 12:02:41                        |
+--------------------------------------------+
1 row in set (0.00 sec)

となります。ここで、「+ INTERVAL 9 HOUR」と「- INTERVAL 1 MONTH」の順序を入れ替えてみます。

mysql> SELECT NOW() - INTERVAL 1 MONTH + INTERVAL 9 HOUR;
+--------------------------------------------+
| NOW() - INTERVAL 1 MONTH + INTERVAL 9 HOUR |
+--------------------------------------------+
| 2015-11-20 12:02:48                        |
+--------------------------------------------+
1 row in set (0.00 sec)

NOW() 関数通してるので秒は実行のタイムラグの分ずれてますが、基本的には同じ日時を指し示しています。

ですが、この計算式は、実行する日時によっては、等値になりません。

たとえば、このSQLを 日本時間の 12月1日 1:00 (UTC では 11月30日 16:00)に実行したとしましょう。
(以下ではNOW()関数ではなく、日時をリテラルで渡しています)

mysql> SELECT '2015-11-30 16:00:00' + INTERVAL 9 HOUR - INTERVAL 1 MONTH;
+------------------------------------------------------------+
| '2015-11-30 16:00:00' + INTERVAL 9 HOUR - INTERVAL 1 MONTH |
+------------------------------------------------------------+
| 2015-11-01 01:00:00                                        |
+------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT '2015-11-30 16:00:00' - INTERVAL 1 MONTH + INTERVAL 9 HOUR;
+------------------------------------------------------------+
| '2015-11-30 16:00:00' - INTERVAL 1 MONTH + INTERVAL 9 HOUR |
+------------------------------------------------------------+
| 2015-10-31 01:00:00                                        |
+------------------------------------------------------------+
1 row in set (0.00 sec)

と、なんと1日ずれてしまいました。

まぁ考えてみれば当たり前の話で
1ヶ月の日数は、月によって異なるので
上記のSQLで、先に9時間足すと、日付またいで12月1日なるので、その1ヶ月前で11月1日になる
先に1ヶ月減算すると、10月30日になって、そこに9時間足すことになりますが、10月はもう1日ありますから、10月31日になると。

Webアプリケーションで集計組む場合は、プログラム側から日時を渡せばいいですが
ストアドプロシージャでこのような日付周りを扱う場合は、地味にハマるかもしれません。

・・・というか、地味にハマったんでこのエントリ書いたんですけどね(´・ω・`)
なんで素直な順番で書けばなんにも問題ないのにわざわざ順番変えちゃったんだろう。。。

*1:Webアプリケーションから扱う場合は、MySQLのNOW()関数などは使わず、アプリケーション側で日時リテラルを組み立てて渡すべきです

12/13 Symfony Meetup #7 & 「Symfony2入門」読了

もうひとつ12月に参加したイベント。Symfony Meetup #7

symfony.doorkeeper.jp

久々にあまり知り合いのいないイベント参加で若干緊張しました。
そういえば久しぶりの六本木ヒルズでした。昔は毎日通ってたってのが信じられないw(通勤距離的な意味で)

発表資料や当日の様子はきっと誰かがもう書いていたり
Twitterハッシュタグ #symfony_meetup をみればわかると思うので省略して。

Symfonyは今業務でバリバリ使っているのですが
体系だてて勉強したわけではなく、必要に迫られて必要なところを調べる、みたいな形で知識をつけてしまったので
今ひとつちゃんと使いこなせてないんですよね。
(しかも、自分が設計したシステムではなく、今のプロジェクトに途中からジョインしたので)

で、ここで聞いた話や、後述しますが、「Symfony2 入門」を読んでいて
ほんとまだまだ全然便利な機能使いこなせていないなぁ、というのを痛感しています。

@hidenorigoto の発表だったか質疑応答のときだったか
ちょっと記憶が曖昧なのですが
フレームワークの選定の話で
それなりに大きなシステムを組もうとすると
きちんと設計できるのはSymfonyかZendくらい、と言っていたのが印象的で。
というのも、自分もそれなりに今までいろんなフレームワーク触ってきたのですが
CakePHPやCodeIgniter、FuelPHP は、そのあたり難しいってのは同意で。
もちろんそれに向いたシステムってのもあるので、どちらが優れているか劣っているかという話ではなく
そのビジネスで解決したい課題に適した道具を使いましょう、ということではあるのですが。

で、SymfonyやZendが大きなシステムに向いているってのは、ひとえにDB関連がActiveRecordではなく
Data Mapper 使っているところだと。
(Doctrineも1の頃はActiveRecordでしたけど、2はData Mapperになったので)
Data MapperはActiveRecordの手軽さはないですが
その代わりビジネスに要求されるような複雑な要件を、適切にモデリングして扱う上では
やはりこちらの方式のほうが素直に組めるんですよね。
ActiveRecordだとどうしても無理しなきゃいけないところが出てきてしまう。

このあたりは、PofEAAの知識があると腹落ちしやすいと思うんですが
ちょっと初学者には敷居が高いってところが、学習コストなのかなとか思っていたりします。

で、ちょっと時間に余裕があればLTできるかなとおもって、現場で仕込んでみたのですが時間切れだったのでスライドだけ上げました。

www.slideshare.net

これ、実際業務に使ってるんですが
最初その問題を解決するのに、Twigのドキュメント見て、この関数使えそうじゃん!って思い
Google先生を引いてみたんですけど、びっくりするほど情報無いんですよね。公式ドキュメント以外。
かといって、使うとヤバイ的な話もないし。
単にあまり光があたってないのかな、と思ったので話題にしてみました。

発表できずに終わるのも悲しいので
なんか別の機会があれば、これともう少し話を肉付けして、どこかでしゃべろうと思います。


で、もうひとつの話題の「Symfony2 入門」

基本からしっかり学ぶ Symfony2入門

基本からしっかり学ぶ Symfony2入門

Symfony2は今まで専門書籍、という意味ではあまりなかったんですよね。
効率的なWebアプリケーションの作り方 ~PHPによるモダン開発入門 には触れてる部分あることはあるんですが
体系的に学べる、という意味では初の書籍かと。

で、端的に言って、今業務でSymfony扱っている人は必携の本ではないかなと思います。
理論の部分と実践の部分がうまく融合されていて、
とてもわかりやすくまとまっています。
特にSymfonyは今まで初学者には敷居が高い、学習コストかかるという印象があったと思うのですが
この本1冊読み進めていけば、きちんと基礎力つくと思います。

自分もこの本を読んでいていろいろ発見があって。


あと、7章のAPI Docの生成とかもいいなぁと。今あるプロジェクトでも隙をみていれたいな、と思ったり。

SymfonyはWebのリソースが豊富なので
今までは事実上それがドキュメントだったわけですが
体系的に学べる本が出版されたというのは本当に大きいと思います。

自分のエンジニア魂に火がつくような、素晴らしいイベント&書籍でした。

12月7日 GLT(Genesis Lightning Talks) Vol.49 で話してきた

最近は年末の風物詩?となった、「GLT Vol.49」にてLTしてきました。スライドは以下。

www.slideshare.net

GLTはここ最近、年1開催だったので
どうしても同窓会ノリで近況報告になってしまいがちで、これもまぁそうなんですが。

ネタの発端としては、昨年のGLT Vol.48 にて、懇親会の時に彼女の話になって
こっちの話のほうがLTのネタになるじゃん、みたいなことを言われていたので
じゃあ1年越しにそれをネタにしようかと。
・・・というのがネタフリで、いかにも喋るような体にしておきながら
実際は弊社絶賛エンジニア募集中だよ!って言いたいのを延々喋って、ちょうど5分時間切れになる、という
最近ではこの手の落ちも使い古しではありますが、「時間切れ狙い」というオチでした。
(最後のほうのスライドで、スーパーマリオの絵があるのは、以前のGLTは1分前にマリオのhurry up音
 時間になると、1 down音が流れる仕様だったので、それにあわせてのネタ)

で、スライドの本題の方は、ここでわざわざしゃべるつもり無いのですが(笑)
(それこそどこかの懇親会でツッコんでください)
エンジニア募集の方は、ほんとに真面目に募集しています。

事業ドメインとしてはなかなか手堅いところを抑えていて
まだまだ事業拡大中という状況で、
その一方、エンジニアは今超売り手市場なので、なかなかいい人材と巡り合うのが難しいんですよね。
ましてや弊社も特にエンジニア界隈では全然無名な方だと思うので
(あまり外の勉強会に積極的にでることもなかったので)
そこは自分がある程度スポークスマンになって、動こうかなと思っており。

技術的には、超最先端を常に追っていきたいとか、一発勝負出て大儲けしたい、という人には向かないですが
堅実に末永く腰据えてエンジニアリングに取り組みたい方
特に、音楽系、最近はスポーツ系も取り組み始めているので、そのあたりに興味ある方であれば
とても向いてると思っています。

なので、このブログで改めてという感じで
こういったビジネスのシステム開発・運用に興味あるなぁという方は
TwitterでもFacebookでも構いませんので、お気軽にお声がけください。

そうそう、GLTもいよいよ次回で50回!なんですね。
このイベント自体が発足した当時を知るものとしてはなかなか感慨深い。
もう、あの当時あの会社にいた人もすでに別の場所で活躍してる人も多くなりましたが(というか、残ってる人がいない・・・か?)
これだけ継続している事自体、コミュニティの力はすごいなと思います。
GLTがなければ出会うこともなかった人もほんと多いですし。

会場提供いただいたドワンゴ様、運営担当の皆様、ありがとうございました。

レコードがなかったらINSERTして返すみたいなのをもっと確実にやる

元ネタ

レコードがなかったらINSERTして返すみたいなのを確実にやる | おそらくはそれさえも平凡な日々
http://www.songmu.jp/riji/entry/2014-03-02-find-or-create-surely.html

このソースコードの処理だと

# エラーが発生していて重複エラーだったら取り直す

# ロックかけたいときは取り直す

の処理の間に、該当レコードがDELETEされてしまうと
空行にFOR UPDATEしてしまい、ギャップロックの悪夢再び、になってしまうかと。

どうしても確実にやりたい、でも、ON DUPLICATE KEY UPDATEも
INSERT IGNOREも、(元ネタには言及ないけど)REPLACE INTOも嫌!ってことなら
「ロック専用テーブル」を作るのがいいのではないかなと。

処理をかけたいテーブルと同じPKを持つテーブルを作る。(複合キーなら同じく複合で)
このロック専用テーブルには他のカラムは要らない。

で、トランザクションの最初に、
ロック専用テーブルにこれから処理しようとしているデータのPKをINSERT。

本来やりたい処理(レコードがなかったらINSERT)を行う

ロック専用テーブルにINSERTしたデータを削除してからコミット

こうすれば、いけるんじゃないかしら。
並行スレッドは、処理をしようとしても、最初のロック専用テーブルのINSERTに失敗するから
処理できないはず。
一方、ロック専用テーブルにはPKを直接指定してINSERTしてるので
このケースの時はネクストキーロックはかからないんじゃなかったかな。。。ちょっと記憶が曖昧。
実際動作確認したわけじゃないので
嘘書いてたらごめん。

まぁ、このためだけに、一見何も入ってないテーブル
トランザクション開始時にINSERTして、コミット直前にDELETEしちゃうから)
を作らなきゃいけないってのがうざいので
許容できる状況なら ON DUPLICATE KEY UPDATEがおすすめかな。

退職のご挨拶

2014年8月末で、現職の株式会社トライフォートを退職することになりました。
本日(8月25日)が最終出社のため少し早いですが、退職エントリーを書きます。

トライフォートでは最終的にはサーバサイドエンジニアを束ねる部門
インフラエンジニア束ねる部門、2つの部門長という肩書で活動をしておりました。
身に余る光栄であるとともに、短期間で会社を去る決断をしたことについては
関係各位にはご迷惑おかけすることをお詫び申し上げます。

トライフォートに入社したのが、2013年の9月で、ちょうど在籍は1年ということになります。
終わってみれば、たった1年だったのですが
1年だったのか!?と自分でも思ってしまうくらい
この1年はとても勉強することも多く、実りも多く
自分の職歴では最短の在籍期間となったものの、得たものは本当にたくさんあった
充実した1年間であったと思っています。

サーバおよびインフラ部門の長として
マネジメントとして心がけていたことが2つあります。

1つは、書籍「Team Geek」に取り上げられている「HRT」です。
Humility(謙虚)
Respect(尊敬)
Trust(信頼)
現場のメンバーと謙虚に向き合い、尊敬し、信頼する。
言葉で言うのは簡単ですが、実践するのはなかなか難しい。
時には「これ自分がやった方が早えし」とか「ちょwおまw」と思ってしまうこともあるんですが
できるだけそこは堪えて、
皆の心(Heart)に届くマネジメントをしてきたつもりです。

もう1つは、「情報の共有、アウトプット」です。
トライフォートのエンジニアは、技術レベル高い人が揃っていると
贔屓目にみても思ってはいるのですが
ただ、情報を共有する場があまりなかったり、アウトプットを積極的にする文化がまだ足りないと感じていて
そこは力を入れて仕組み、仕掛けをいろいろしてきました。
「社内Lightning Talks」なんてのも始めて
普段は人前で発表しない人にも、強制的に発表する場を仕掛けたりもしました。
正直最初は反発もあるかな…と危惧していたのですが
初めて見ると、意外とみんなそれぞれにアイデアをだして良いネタを披露してくれて
この人はこういうところに興味が向いてるんだなという発見もあったりで
始めた当初の想像以上に、良い効果が出てるんじゃないかなと自負しています。

ただ、アウトプットに関して言うと、やりきれなかった部分として
社内にとどまらず、社外に発表できるレベルまで引き上げたかったな...というところが心残りです。
というか、内容的には社外に発表しても問題ないものも多いのですが
恐らく文化的な部分で、社内向けだからということで
ちょっと詰めの甘い部分があったり
あとは社内PJに関する情報が多くて、公表できないだけ、というのもあり
それはもうちょっとエッセンスを抽出すれば、公表して、
それもまた一つ会社のバリューにも、そのエンジニアのバリューにもなると思うのですが
そこまで組織力を持ちあげられなかったのが、自分の力不足を痛感している次第です。

ほんとはもう少し有休残ってたので
のんびりできたらという気持ちもあったのですが
諸々事情があって、休暇も取れず、この時期になってしまったのですが
8月25日に最終出社というのは、ちょっと思うところもありまして。
25日なので、給料日なんですよね。
事情あって、退職公表から最終出社まであまり時間がなかったので
せめて、最後の給与明細くらいは、部門長としてきちんと手渡したいなという気持ちもありました。
(何人かは夏休み中で叶わなかったのですが)
きょうび、給料明細なんて、単なる記録でしかないので
特別な思い入れなんか無い人が多いのかもしれないですが
やはり現場のみんなが尽力してくれた上でのお給料ですので
今までの感謝の気持ちを込めて最後の明細をお渡ししたかった
・・・そんな思いもありました。

退職理由については、退職エントリとしてはもはや常套句ですが
「音楽性の違い」とだけ記載しておきます。
(それにしても便利な言葉だw これ最初に退職エントリで言ったの誰だろう... 起源を知りたい)

次の職場でも、相変わらずサーバサイドのエンジニアはしています。
ただ、ここ半年くらいはほぼマネジメント寄りだったので
手を動かすってことに対してちょいと鈍っているので、勘を取り戻せるかが若干不安だったりもしますが...
まぁ、なんとかなるでしょう(笑)

株式会社トライフォートの皆様、および業務にて関わった皆様、本当にありがとうございました。