モーグルとカバとパウダーの日記

モーグルやカバ(EXカービング)山スキー(BC)などがメインの日記でした。今は仕事のコンピュータ系のネタが主になっています。以前はスパム対策関連が多かったのですが最近はディープラーニング関連が多めです。

長野ディープラーニング同好会 #1

平日夜隔週でGEEKLAB長野さんとこで、ディープラーニングについての勉強会をやることになりました。
ただ、「勉強会」というよりもうちょっとゆるくしたかったので「同好会」としてみました。


長野ディープラーニング同好会 #1 - connpass


プレ回みたいなのを8月末にやったのですが、そこで話し合って、1回ごとや何回かで出来るような小さな課題を決めてみんなで試す、という方針でやってみることにしました。


初回は、ディープラーニングの「Hello World」ということで

  • Google Colab使ってMNIST(数字認識)させてみる

ということをやりました。


Colabを使うので環境構築とかは全くしなくて良いのではまらないだろう、と思っていたのですが、集まっためんつのうち3人がPCではなくタブレットで、Colabだからそれでも問題ないだろうと思ったのですけども、それだとGoogle DriveからColabの呼び出しがうまく行かず、それをどうしたらいいかでだいぶはまりました。

Google Driveをアプリではなく、Webページから入って使うとうまくいくのですが、そのためには一旦Google Driveのアプリをアンインストールしないといけないとか、謎な知見がたまりました。


その後あまり時間がなくなってしまったんで、簡単にバックプロパゲーションとKerasの説明おさらいをして、3層とか4層のバックプロパゲーションで認識ができるようになること、5層でもシグモイド関数だとぜんぜん性能でないことなんかを試しました。

Google ColabでPyTorchを使う

Google ColabはGoogleアカウントさえあれば即時TensorFlowの入ったJupyter環境が使えて、さらになんとめちゃ高いGPUまで使えちゃうという、まあいたれりつくせりで超おすすめです。
が、最近arXivとかで公開されてる論文のソースがPyTorchが使われてることも多く、PyTorchも使いたいなあと思うわけです。
でもGoogle Colab環境にPyTorchは入ってないんですよね。


(追記)
Colabの「コードスニペット」から「Install [pytorch](http://pytorch.org/)」を選択して実行すればできるようになっていました。
そちらをおすすめします。


で、Google ColabでPyTorch 0.4使うためにどうしたらいいかを調べたところ、下記内容でばっちり動かせるようになりました。

Pytorch 0.4.0 on Google colab - PyTorch Forums


下記コードをコードセルの最初に貼って実行すればOKです。
ランタイムGPU使うようにしてあれば、ちゃんとGPU使えるようになります。
pipでpytorchのインストールから行うことになりますが、そこまでは時間かかりません。

from os import path
from wheel.pep425tags import get_abbr_impl, get_impl_ver, get_abi_tag
platform = '{}{}-{}'.format(get_abbr_impl(), get_impl_ver(), get_abi_tag())

accelerator = 'cu80' if path.exists('/opt/bin/nvidia-smi') else 'cpu'

!pip install -q http://download.pytorch.org/whl/{accelerator}/torch-0.4.0-{platform}-linux_x86_64.whl torchvision
import torch
print(torch.__version__)
print(torch.cuda.is_available())

出力セルにこんなふうに表示されたらOKです。
もし最後の行がFalseになってるときはGPU使えてない状態です。

tcmalloc: large alloc 1073750016 bytes == 0x5bd9a000 @  0x7fb18556f1c4 0x46d6a4 0x5fcbcc 0x4c494d 0x54f3c4 0x553aaf 0x54e4c8 0x54f4f6 0x553aaf 0x54efc1 0x54f24d 0x553aaf 0x54efc1 0x54f24d 0x553aaf 0x54efc1 0x54f24d 0x551ee0 0x54e4c8 0x54f4f6 0x553aaf 0x54efc1 0x54f24d 0x551ee0 0x54efc1 0x54f24d 0x551ee0 0x54e4c8 0x54f4f6 0x553aaf 0x54e4c8
0.4.0
True

NSEG勉強会#101

先月末6/30(土)に「メールとコミュニケーションツール」というお題でNSEG勉強会が開かれて参加してきました。

勉強会は参加エントリ書くまでが勉強会、と思ってるのにずっと放置してしまってました…


NSEG 勉強会 #101 / メールとコミュニケーションツール - connpass

NSEG 第101回勉強会 / メールとコミュニケーションツール #nseg - Togetter

NSEG 101 - YouTube


今回、bounceHammerやSisimaiという、エラーで返ってきたメール(バウンスメール)を解析するオープンソースのツールを開発されてる @azumakuniyuki さんと、DebianUbuntuのメンテナなど色々と活動されてる @henrich さんが遠方から来られたため、@suno88 さんとともに前日から歓迎の飲み会&次の日も午前中からお昼すぎまで観光やら温泉やら巡るなどして、大変楽しく交流することができました。


あずまさんの講演「Email is Slack」は、メールやバウンスメール解析ツールSisimaiの開発を実例としつつ、どんな開発コンセプトでサービスやツールを作るべきか、というお話でした。
「Email is Slack」のSlackは、チャットサービスのほうのSlackではなくて「活気がない」「ゆるい」という元の英語の意味の方の話です。
メール以外のSNSだとかのコミュニケーションツールは伸びてて、メールは伸びてはいないものの停滞しているということが資料から説明されました。
そして本業のエラーメールのバウンスメール解析の話につながり、バウンスメールの形式が雑でゆるいために、いろんなものがあるということでした。
そこから、現在のバウンスメール解析ライブラリであるSisimaiへの歩みがどんな感じだったかの話になりました。
そしてそこが本題で、最終的にはUNIX哲学にしたがって、小さく、堅く、一つのことだけを速くやる、というツールにしたほうが、結局使いやすい良いものになる、という話でした。
これが最初に紹介のあった本「UNIXという考え方」につながるわけですね。
あずまさんはLTもお話いただいて、実は長野すごい来てるんだってことがわかりました。


やまねさんのLT「Let's look into debootstrap」は、いかにしてdebootstrapのバグフィックス等改善していったか、という事例を話すことで、オープンソースへの取り組み、貢献をどうやって始めたり続けたりするのか、という話になっていたと思います。
僕はこの話を聞くまで、debootstrapのこと知らなかったのですが、すごい面白いツールで、特にdocker環境とかで有用だろうなと思いました。
で、動機だったdocker環境で動かしたい件についてどうなったのか、が最後のオチに出てきます。


とみたさんのLT「メールの文字化け」は、流石「文字化けソムリエ」だけある内容でした。
特にMIMEが絡んだエンコーディングのつらみがなんで起きるのか、RFC通りには実装されてないものデコードしないといけないこととか、メールならではの問題と絡んだ理由で説明され、とても楽しめました。
最初のタイトルへの持ってき方がずるいくらい面白い。


鍋太郎さんのLT「LINE の bot を作ってみた」は、LINEに通知を流せるbotを作るために、どんな(LINEに対しての)手続きやコードが必要かを実際の例から説明するものでした。
地区の連絡用に必要に迫られて、というのが良い感じです。
直接の実用性という意味では一番参考になると思いました。


自分は「スパム対策お焚き上げ」という題で、自分が以前考案して運用しているtaRgreyというスパムフィルタ手法と、そのログから最近のスパムがどのような状況となっているか、を説明する内容となっています。

スパム対策お焚き上げ

これ前半は、8年前にNSEG #10で話した下記内容を一部簡略化したものがベースとなっています。

taRgreyでコストを掛けずにスパム削減

僕にとっては実はちょっとせつない内容なんですが、そこそこウケてもらえたかな〜と思っています。
これは後でエントリー化したいと思っています。

PHP5.3からPHP7への移行で出たエラーと対応方法

最近は結構だいぶひまで、あまりネタがないので小ネタです。


新規サーバ移行に合わせPHP5.3からPHP7へ移行したいという話で、そのテストをしてたときにでたエラーとその対応についてまとめました。


まず、これはPHPの話じゃないんですが、Apacheのバージョンが新しくなったせいで、一部ページで文字化けが発生してたのの対策。
apacheのデフォルト文字コード指定がUTF-8になってると、S-JISとかEUCのページがあったときに化けるのでコメント化します。


Apache 文字化け対策 AddDefaultCharset – CentOSサーバ構築術 文具堂

/etc/httpd/conf/httpd.conf

#AddDefaultCharset UTF-8


「Parse error: syntax error, unexpected 'new' (T_NEW)」というエラーが出ていた件対策。
PHP7ではオブジェクトの参照渡し代入ができなくなっている(というか普通に代入すればよい)ため。


Parse error: syntax error, unexpected ‘new’ (T_NEW) in | ホームページ制作部ブログ | 中央区日本橋 しろくまシステムズ

PHP5

$my_query =& new WP_Query


PHP7

$my_query = new WP_Query


「Uncaught Error: Call to undefined function split()」というエラーが出ていた件対策。
splitが不用意に正規表現使われちゃうので関数名が変わった。正規表現の必要ないときはexplode使えと。


PHP5.6からPHP7.1にしたら出たエラー|Never catch a cold.

PHP5

split('/,/', $text)


PHP7

explode(',', $text)


「Fatal error: Call to undefined function mysql_connect()」というエラーが出ていた件対策。
mysql_*系はなくなりmysqli_*系になったので色々と置き換えが必要。


PHP7で、mysql_connect()が無いと怒られる件 (undefined function mysql_connect)

PHP5

mysql_connect(...)


PHP7

mysqli_connect(...)

NSEG勉強会#100

NSEG http://nseg.jp/ の勉強会が100回の節目の会で参加してきました。


NSEG 勉強会 #100 / 第 31 回フリーテーマプレゼン大会 - connpass https://nseg.connpass.com/event/86278/

Togetter https://togetter.com/li/1231435

YouTube https://t.co/xSjt6YLHJk


今回は、前半のプレゼン部分と、NSEGについての座談会部分と、で大きく2パートとなっていました。
特に後半部分は色々と議論があり、有意義な話がされたのではないかと思います。(後半の議論が盛り上がったので、前半の印象が薄れてしまった感じすらある)
今後も新しい参加者を得ながら継続していくにはどうしていったらいいか、について話をしました。


自分は最初、発表予定なかったんですが、前とその前に参加したとき、発表した内容がどちらもネガティブな話で、非公開にさせていただいたという経緯があり、せっかく100回の記念だから夢のある話をしてネガティブイメージを払拭しようと、勉強会中にささっと書いてみました。


シンギュラリティはくるの? https://www.slideshare.net/stealthinu/ss-99124068


この手のことを僕みたいな素人が無責任にしゃべると、都会の勉強会だとマサカリが飛んできそうですが、NSEGならよいかなと。
自分にとってはその「ゆるさ」がありがたい勉強会です。

htaccessでBASIC認証掛けてあるが特定ファイルのみアクセス許可する

apache上のWordpressで管理画面ディレクトリにBASIC認証が掛けているのですが、テーマから wp-admin/admin-ajax.php を呼ばれているため除外する必要がありました。


これを普通に.htaccess

<Files admin-ajax.php>
    Order allow,deny
    Allow from all
</Files>

と追記しても、結局BASIC認証のほうで引っかかってしまうためうまくいきません。


BASIC認証で特定のファイルを除外する方法を調べました。

.htaccessで特定のファイルやディレクトリのみBASIC認証を解除する | ザ サイベース

この場合「Satisfy any」指定を追加して、この条件のみでもallowするようにすればうまくいくようです。

<Files admin-ajax.php>
    Order allow,deny
    Allow from all
    Satisfy any
</Files>


ちなみにこの設定は、そのままWordPressの公式にも案内がありました。

ブルートフォース攻撃 - WordPress Codex 日本語版


あと余談ですが「allow,deny」の間にスペース入れるとエラーになるんですよね。
ちょっとハマりました。

Order指示子のdenyとallowをカンマで並べる時、間に空白を入れてはいけない。 - ぐらめぬ・ぜぷつぇんのはてダ


このへんのSatisfyとかallow,denyの順番のこととかは、下記ページにまとまっていて大変参考になります。

Apacheのアクセス制御をちゃんと理解する。 - こせきの技術日記

ダウンローダでダウンロードのリクエストが二重に出ていた理由

CMS用に独自のダウンローダが作ってあり、なぜかダウンロードのリクエストが毎回二重に行われる(そして大きなファイルだとそのせいで負荷が増えてしまう)という問題がありました。


非常に謎な動作だったのですが、理由は

  • Rangeには対応していないのにAccept-Range付けていた
  • Edgeのバグ

という2つの理由でした。理由も二重と。

Rangeには対応していないのにAccept-Range付けていた

HTTPではリクエストで「Range」ヘッダを指定すると、ファイルを部分的にGETすることができます。

例えば

Range: bytes=1000-2000

のように指定すると、該当ファイルの1000byteから2000byteを取得できます。
つまり分割ダウンロードが可能になっています。


ただこれは下記のように、レスポンスの「Accept-Ranges」ヘッダに「bytes」が指定されていて、ファイルが部分的GET可能であることが示されている必要があります。

Accept-Ranges: bytes


このダウンローダでは分割ダウンロード(部分的GET)に対応していないのに、この「Accept-Ranges」が設定されてしまっており、それを見てブラウザが分割ダウンロードをしようとしてきていました。
複数のGETにはそれぞれ「Range」が指定されていたのですが、ダウンローダ側は対応していないため、毎回大きなファイルを全部返してしまっていた、というわけです。


たぶん、ダウンローダを書いた人が参考にしたコードはRange対応になっていたのでしょうが、「Accept-Ranges」の意味を確認せずにそのままコピーしてしまってしまったのではないか、と思います。

Edgeのバグ

EdgeだとPDFのダウンロードリクエストが二重に出てしまう件について、バグらしいということが報告されていました。

https://stackoverflow.com/questions/31850624/microsoft-edge-pdf-inline-issue-same-issue-again

  • Probelm with Edge and ContentType="application/pdf" And content-disposition "inline;filename=report.pdf" | Microsoft Connect

https://connect.microsoft.com/IE/feedback/details/1621308/probelm-with-edge-and-contenttype-application-pdf-and-content-disposition-inline-filename-report-pdf
https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7045462/

https://stackoverflow.com/questions/30918543/microsoft-edge-pdf-inline-issue


簡単にまとめると

  • EdgeでPDFのファイルをダウンロードしようとすると二重にリクエストがくる
  • 二回目のダウンロードではヘッダにGetContentFeatures.DLNA.ORGが付いてる
  • 一度直った(build 10158 2015/7頃)が再発(build 10240 2016/3頃)した

ということだそうです。

ESXiのブラウザコンソールで「:」とかが入力出来ない問題

ネットワーク含めたテスト環境を構築するため、ESXiでネットワークとVMの環境を構築していました。
そこでVM上で動かしてるCentOSの設定ファイルを、ブラウザコンソールからviで編集している時、「:」がどうしても入力できなくてはまりました。
入力される文字からし英語キーボードとして認識されてるのはわかったのですが、どうやって抜けたものか…


実はブラウザコンソールウィンドウの右上に、国旗のアイコンがあるのですね。
英語キーボードだとアメリカ国旗になっています。これをクリックするといくつか国旗が出てくるのでそれを日本の国旗を選べばOKです。


ただ、これだとデフォルトのキーボード設定は変わらないので、VM毎に設定しないといけないと思います。
ESXiのウインドウ上部に「root@192.168.0.1」みたいに今ログインしているアカウント情報を表示しているところがあり、ここをクリックするとESXiの設定を変更出来るところがあります。

設定→コンソール→キーボードレイアウト→英語

となっているところを「日本語」を選択すると、デフォルトで日本語キーボードになります。

「SQLアンチパターン」読書会スペシャルに参加しました

1/27にGeeklab長野で行われた「SQLアンチパターン」読書会スペシャルに参加してきました。

「SQLアンチパターン」読書会スペシャル - connpass


内容や感想については @thinkAmi さんの

「SQLアンチパターン」読書会スペシャルに参加しました #nseg #glnagano #sqlap - メモ的な思考的な

が超まとまっていておすすめです。


ので、とりあえず自分はtogetterでtweetまとめました。

「SQLアンチパターン」読書会スペシャルまとめ - Togetter

勉強会の雰囲気をつかめるかと思います。


詳細については@thinkAmiさんのまとめ参照してもらうとして、twadaさんのお話で自分が一番感銘受けたのは、こういった機会に書かれている内容を現在の状況に合わせて見直されているというところでした。
例えば2.4章で、RDB木構造を表現する時ナイーブツリーはアンチパターンとなっていますが、CTEが使えれば使ってもよく(これは本書のアンチパターンを用いても良い場合にも元々書かれている)以前は利用できなかったMySQLSQLiteでも新しいバージョンではCTEが利用できるため、今後はアンチパターンから外すべきだろうとのことでした。


これは本の内容についての話ですが、システム開発でも、本来修正した方が良いところの構造を変えず、古い旅館よろしく継ぎ足し継ぎ足しでなんとか拡張延命させていくと、気がついたときには時代遅れのもう誰も根本的改善のできない恐竜システムとなってしまうことがあります。
そんなシステムは、使わされるユーザも、作らされる開発者にとっても、誰も幸福にならないと思います。
日々改善、リファクタリングをしていけるシステムを作りたいものです。

EC2でのMeltdown/Spectreパッチでの性能低下

AWS EC2で動いるシステムが、1月4日のMeltdown/Spectreパッチ適用以降すごくパフォーマンスが落ち、その影響でシステム障害が発生しました。
そのとき、twitterFaceBookで情報いただいた件を簡単にまとめます。


EC2(m1.medium)上で動いている非常にDBヘビーな商用CMSがあり、年明け後そのCMSMySQLへのセッション数が溢れてしまうことが原因でシステム障害が発生していました。
調査すると1月4日以降、MySQLで域値を0.1sに設定してあるslow-queryの発生数が何倍にも増えていることがわかり、少なくともMySQLのパフォーマンス低下があることがわかりました。
1月4日にはEC2の計画再起動が行われており、これはMeltdown/Spectreパッチ適用によるものでした。


そのため、パッチ適用前と後のDB処理速度を数値的に比較できるものがないか探してみました。
MySQLのslow-queryのログに、毎日定期で重いバッチクエリのものが出ていたため、この処理時間の変動である程度比較できるのではと考えました。
そこで以下のように、4つの重いバッチクエリに対して、パッチ適用前後5日のクエリ処理時間平均を算出しました。

   適用前   適用後   倍率
A  226.26s  375.06s  1.66倍
B  110.09s  210.94s  1.92倍
C   30.68s   56.83s  1.85倍
D   23.18s   74.56s  3.21倍

1.6から3.2倍となっており、少なくともこれらのクエリについては2倍弱は遅くなっている感じがわかりました。


この結果から、twitterFaceBookで同様の状況になっている方がいないか聞いたところ、何人もの方から同じような状況だったり、そのためにインスタンスタイプを変更されているとのお話をうかがいました。

どうもEC2の旧世代PV方式インスタンスのものだと、特に今回のMeltdownパッチの影響を大きく受けるようで、少なくとも20%程度、RDBだとそれ以上の速度低下があるようです。
Auroraでは6割から7割程度までにパフォーマンスが下がっているというレポートもあり、それはこの障害で出ている状況とも感覚的に一致していました。
ただt2インスタンスなど、新しいHVM方式のものだと性能も上がっているうえ、パッチの影響によるパフォーマンス低下も少ないため、問題が起きないようです。


(参考)

MeltdownとかSpectreとか騒ぎがあったので、Amazon Aurora(MySQL互換)R4インスタンス再テスト(mysqlslap) - Qiita
Auroraでのパフォーマンスが63%〜73%程度に落ちていることがレポートされています。

投機実行の脆弱性修正、Haswell世代以前では性能への影響大 〜I/O集中型アプリケーションを利用するサーバーは慎重な選択を。AMDはほぼ影響受けず - PC Watch
Haswell世代以前の古いCPUのほうが影響を受けることが指摘されています。


ただし、AWSの公式見解としてはMeltdown/Spectreでの性能低下はほとんどなかった、という立場のようです。

AWSもSpectreとMeltdownの対策完了を報告。対策後、Amazon EC2で性能の低下は見られないと − Publickey


そのため、インスタンスタイプを

m1.medium → t2.medium

に載せなおすのが最善策ではないかという結論になりました。


PV方式のインスタンスからHVM方式のインスタンスへの載せ替えについて、下記エントリ

AWS EC2のインスタンスが新年早々各地で起動しなくなる可能性がある件 - 株式会社アクシア

に、EBSをほぼそのまま付けなおして移行する手法が、ある程度詳しく書かれていました。
HVM方式が始まったあたりにPV→HVMへの移行について書いてあるものは、変換が必要だったりともっと手数が掛かって大変なものが多いので、この手法が良さそうに思います。
ただ、bootのコピーなどの詳細までは書かれていないので、多少実験して経験を積んでから行ったほうが安全そうです。


先日twitterFaceBookで情報やアドバイスいただいた皆様、ありがとうございました。