oranie's blog

旧:iをgに変えると・・・なんだっけ・・・

NginxでSSLセッションキャッシュを有効にした際に新規セッションが張れなくなる事象について

多分Nginxでゴリゴリやっている人ならm9(^Д^)プギャーだろうけど、メモっておく。

サーバサイドでSSL処理をする際に少しでもCPU処理を軽くする+レイテンシを下げたい目的で

    ssl_session_cache shared:SSL:128m;
    ssl_session_timeout  300m;

的な設定を入れた所、負荷が高い時間帯に

[alert] 14099#0: *1627571 could not allocate new session in SSL session shared cache "SSL" while SSL handshaking, client:〜省略〜

というログが出た。ソースコードをほげほげ読んでみると
ngx_event_openssl.cのngx_ssl_new_session
で記述されている処理でおそらく

  1. キャッシュ領域に書き込もうとする
  2. 溢れている時は一度古いのを消す
  3. 但し、空けた瞬間に別のリクエストがそこを使ってしまう
  4. もともと空ける処理をしていたところは再度書き込みに失敗する
  5. エラーとなる

という流れっぽい。

その為、CPU負荷も問題が無かったことから一旦キャッシュはnoneで設定するようにした。

【チラ裏】色々あって社内ジョブチェンジでスマートフォンアプリエンジニアになりました。

昨今の殺伐としたインターネットを見ていたら「インフラエンジニア(狭義)は死んだ」というのを発見し、内容にいたく感銘を受けこれではマズイと思ってジョブチェンジしました。



本当の所は深淵なる諸事情とかもあるが「まあアプリ書けたらエンジニアとして良いよね」というノリで、ジョブチェンジする事になりました。
正直サーバサイドの運用担当から離れる事は結構未練や不安はあり、特にこの2年間くらいはCassandra運用に結構専念させて貰っていた(まあCassandraのソースちゃんと読んだりするレベルとかは他のエンジニアが調べたのを教えて貰ってというレベルですが)おかげで、第一人者には程遠いですがCassandra芸人チックなレベルにはギリギリなれた感はあったので、サーバサイドアプリではなく今までの経験があまり活用できないかもしれないスマートフォンアプリに行くことは「本当にキャリアにとっていいんだろうか?」とかは思いましたが、

@riywoさん(運用エンジニアから開発エンジニアになるためにやったこと)や@marqsさんが運用エンジニアから開発も〜という流れを見たりしていたので、「まあ、どう考えても開発も出来る方が良いよね」「他の開発者も同じ人間なんだからなんとかなるだろ」「Cassandraの運用とどっちが難しいのかな」とかを知る意味でもいい機会かなと思いました。ただ、riywoさんの記事を改めて読んで、自分はこういう時の為の準備を全然していない事に気付いて意識の低さを再認識しましたね。記事をブクマはするけど結局何も準備せずにこの体たらくかと。

まあ、「スマホアプリ開発に比べたら分散データストアの運用なんて簡単やったんや!今度は心を入れかえてもっと真剣に運用します!」ってなれば、まあそれはそれで良いのかなと。あとはCassandraがJavaで書かれていることから、結局Java分からないと運用のクオリティが上がらない為、もしまた運用に戻った時も今よりはマシな運用が出来る様になるかなというのもあります。

あとは2年間プラットフォームサービスの運用チームをやっていて、良くも悪くも今のチームでは割りと好き勝手にやらせて貰っていたので、僕がいたせいで優先度を下げられていた事とかが別の人が担当になる事で「いや、ここは改善しないと駄目だろ!前任者クソか!」となり今後は改善されるなどの新陳代謝も期待出来ます。また、Cassandra運用とか進行中の案件もある中、それをほっぽり出して行く事になるのを引き継ぐid:rx7先生やメンバーには感謝しています。きっとこれからはid:rx7ブログにはCassandra記事が量産される事でしょう。僕の生み出した負債を頑張って返済お願いします><

なのでサーバサイドレイヤは一旦お休みで、Android(java)とiOS(Swift若しくはObjective-C)をまずは学び、順調に行けばそれから本格的に開発業務へ・・・という予定。情報収集やらのレベルからまだ勘所分かっていないので、詳しい人は是非「こんな本読むと良いよ」「このイベントや勉強会行くと良いよ」「この人のTwitterやブログ参考になるよ」などの情報を教えて貰えると幸いです。

とりあえずJava関連は

EFFECTIVE JAVA 第2版 (The Java Series)


明解Java 入門編


パーフェクトJava (PERFECT SERIES) (PERFECT SERIES 2)


Effective Android


Androidのなかみ InsideAndroid

辺りを買ったので片っ端から読んで触って行きたいと思います。他にもAndroid系のオススメやiOS関連のオススメあれば教えて下さい(・ω<)


という訳で、一旦お休みではありますがキリの良いところではありますので、oranie datastore summit〜oranieくん Cassandra卒業会〜の幹事とお寿司奢ってくれる人を待っています。
今のところ、開発スキルが全然向上せずついていけなくてリストラされるのが一番の心配です。リストラされたら慰めの寿司をご馳走してくれる人を待っています。

MySQLのslow query logを可視化するnata2が大変便利そう

MySQL Casual #6で@studio3104さんが発表していたnata2を触った。

で、とりあえずローカルにnata2を起動しtd-agentを入れてプラグインを入れてmysqlslapを実行してみた。
動作環境はRuby2.1.2で。1.9系は動かなかった。

手順はgithubにも書かれているが、
https://github.com/studio3104/nata2
https://github.com/studio3104/fluent-plugin-nata2
以下は簡単な流れ。

まずnata2自体の設定。
git clone https://github.com/studio3104/nata2.git
cd ./nata2
bundle install

vim ./config.toml
中身は
dburl = "mysql2://test_user:user_password@127.0.0.1/nata2"
で。

次にMySQL側の設定。
/var/lib/mysql/slow-query.logを出すようにして、
mysql -u root -p
CREATE DATABASE `nata2`
GRANT ALL ON *.* TO test_user@'127.0.0.1' IDENTIFIED BY 'user_passwd';
flush privileges;
exit;
完了したら、再度nata2の設定で
bin/nata2server_init_database
bundle exec rackup

で起動する。

td-agent.confはこんな感じ。

/usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-nata2
でpluginをインスコして、
<source>
  type mysqlslowquery_ex
  read_from_head
  path /var/lib/mysql/mysql-slow.log
  tag slowquery.oranie.localhost
  pos_file /tmp/slowquery.log.pos
  last_dbname_file /tmp/slowquery.log.lastdb
</source>

<match slowquery.**>
  type nata2
  remove_tag_prefix slowquery.
  server 127.0.0.1
  port 9292
</match>

を設定しservice td-agent restartする。
これでちゃんとmysql-slow.logが出力され、fluentdがmysql-slow.logを読めていたら、

mysqlslap \
  --user=test_user \
  --password=user_passwd \
  --host=127.0.0.1 \
  --port=3306 \
  --engine=innodb \
  --auto-generate-sql \
  --auto-generate-sql-load-type=read \
  --auto-generate-sql-add-autoincrement \
  --number-char-cols=3 \
  --number-int-cols=5 \
  --number-of-queries=10000 \
  --concurrency=3 \
  --iterations=10

とかでゴリゴリ負荷を掛けてslowquery logを出すと

な感じでslowquery logの可視化がされていて大変便利ですね。

みんな使って色々@studio3104さんにナタを投げつけてあげると良いと思います!

nginx 1.7系である条件を元にアクセスログの出力を抑制する場合の設定

nginx 1.7系を設定している時に、まあ良くある要望でリバースプロキシの設定をしたいんだけど、アプリ側が静的ファイルを返す時にそれはアクセスログに出したく無いって設定でハマった。
初めはlocationの内部でif文書いてaccess_log offとかでやろうとすると、何故かファイル自体へのアクセスがそもそも404になる。で、じゃあ画像用のlocation切ってやろうとすると、locationの条件に正規表現を使った場合は

nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular expression, or inside named location, or inside "if" statement, or inside "limit_except" block in

こんなエラーになってしまう。

じゃあどうすれば良いかと言うと1.7系ではaccess_logディレクティブに

The if parameter (1.7.0) enables conditional logging. A request will not be logged if the condition evaluates to “0” or an empty string. In the following example, the requests with response codes 2xx and 3xx will not be logged:

    map $status $loggable {
        ~^[23]  0;
        default 1;
    }

    access_log /path/to/access.log combined if=$loggable;

The following parameters configure logging to syslog:

というのが追加されていて、
http://nginx.org/en/docs/http/ngx_http_log_module.html
以下の様な設定を入れる事で設定出来た。

    map $uri $loggable {
        ~.*\.(gif|jpg|png|ico|js|css)$ 0;
        default 1;
    }
    access_log  /var/log/nginx/access.log  ltsv if=$loggable;

そもそも前のエラーになる場合の設定ミスをまだ深く追えていないので行き当たりばったり感たっぷりのメモでした。

色んな会社さんの新人エンジニア研修まとめ

ちょうど今のチームに新卒メンバーが一人配属になり、「何からやっていこうかー」「今年の研修何教わった?」「今までどんな事やった事ある?」とか聞いている段階だった所にドワンゴさんの新卒研修の記事が流れてきたので、せっかくなので公開されている色んな会社さんの新人研修をメモっておく。なお、見たことがあるやつとか、ちょろっと調べてあくまでも自分と同じ職種に近いやつだけセレクトしているので、気の向いた人は「◯◯エンジニア編」とか作ると良いかもですね!
他社さんの充実したメニュー見ているだけじゃなくて、うちのチームの配属になったメンバーが「このチームに配属されて良かった」と思えるような事を僕もやらないとですね。

@okb_mさんのまとめブログ

Web系会社の新卒研修の内容をまとめた(自分の調べた範囲)
既に去年の段階で似たようなまとめを作られている人が。以下かぶっているのも結構あるので、そこはまあお察し下さい。

ドワンゴさん

ドワンゴのエンジニア新人研修2014
これがTLに流れてきたので個人まとめ作るきっかけになった。

pixivさん

非エンジニアの新卒にプログラミング研修を行いました
非エンジニアでここまでするんですね。逆にエンジニアでも非エンジニア職の研修とかするのかな。

ペパボさん

ペパボ新卒エンジニア研修 前編
ペパボ新卒エンジニア研修 後編
受講した人の書いた内容ですが、だからどういう所で詰まったとか受ける側の見方が分かりやすいですね。

id:shinsukuさんのブログより「>& STDOUT」

技術の進歩は「螺旋」である。 @t_wada さん社内講演
大変良いお話。

ワザノバ さんの記事 「Quora: 新しい社員の迎え方について」

Quora: 新しい社員の迎え方について
新卒に限らず新しいメンバーを迎えるときのお話。

[追記] 弊社の@79yuukiがやっている研修内容を追記しました。

Node.js で仕事をするための研修を実践してみた

[追記]はてブコメントで指摘貰い、我らがはてなさんのも追加

はてな教科書

適当なまとめ

とりあえず覚えている範囲の奴を思い出しながらググったりその途中で見つけたのを適当に上げておきました。
ツールの使い方とか基礎的な技術研修とかも仕事をする上では大事なんだけど、マインドについて特にみなさん色々と考えられていますね。各社さんとても充実していてそこはやっぱり文化であったり、新しく入る人が戦力になってくれるのがどれだけ大事なのかという事がカリキュラムに出ていたりと恥ずかしながら見ている僕が勉強になります。出来ることなら僕もこの研修受けてみたい。それにしても初めに覚える事が多くて今の人は大変ですね!

Nagiosで監視プラグインにhostgroupで定義しているホスト群のIPアドレスを一気に引数に入れる方法

やりたいこと

例えば10台のサーバでHTTPチェックをして「hostgroupに定義しているホストのうち、n台までNGはアラートはWARN、n台を超えたらCRIT」みたいな事をやりたい時に、監視プラグイン側にチェックする為のIPアドレスを引数に渡したいけど、service定義する箇所でコマンドの引数に全部のIPを書くとかはイケていないのでチラッと本を読んだら書いてあった。

方法

簡単に言うと

$HOSTADDRESS:<hostgroup名>:<デリミタ>$

というオンデマンドグループマクロという物を使えば実現出来る。

check_command    check_nagios_value_test!$HOSTADDRESS:linux_servers: $

こんな感じで定義すると、仮にlinux_serversにhost1,host2が設定されていれば、監視プラグイン側には

host1のIPアドレス host2のIPアドレス

という形で引数に入る。

以上です。

Cassandraでバッチ処理用のクラスタを作る為にsstableloderを使ってみた

まんまです。今までブログにこれで作れるらしいと書いておきながら試していなかったのでやってみた。
経緯としては元のクラスタは台数が多いので、スナップショットをコピーしてそれからあーだこーだわーわーぎゃーぎゃーするにはちょっと辛かったけど、コピー対象のデータは小さいデータだったので丁度いい機会だったのでやってみた。

まず使い方

  1. 流し込み先のクラスタを作成する。
  2. 流し込むデータと同じkeyspace、columnfamilyのスキーマを設定する
  3. sstableloderを使って流し込む

という手順になる。

気をつける所

sstableloderと流し込み先のVerは一致させる必要がある。これはsstableloderが流し込み先のクラスタに接続する際、nodetool ringに相当する処理を実行してクラスタのノード情報(token情報)を取得するが、sstableloderが1.2系、クラスタが1.1系だとnodetool ring自体の処理(この辺はまだ調べていない)が変更されている為にエラーになってしまった。

使い方としてはdatastaxのドキュメント(http://www.datastax.com/dev/blog/bulk-loading)にも載っているが

/usr/local/cassandra/bin/sstableloader -d 192.168.0.1(初回接続先ノード。このノードに接続してringを実行して実際に流し込むnode情報を取得する。「,」区切りで複数指定可能) keyspace/column_family

となるようにしなければいけない。その為、ディレクトリ構造もこれが実行出来るように

/data/keyspace/column_family/sstableファイル群

というような構造にしておき、一度cd /dataをして上記のkeyspace/column_familyという文字列でディレクトリ構造を指定出来るようにしなければいけない。

実際に流し込んだ所、3台のクラスタ(レプリカファクター3)に流し込んだ時で大体20MB/secという速度だった。で、いくつか並列にsstableloderを実行しても合算したスループットは変わらなかった。これは流し込み先クラスタの書き込み限界に達してしまったと思う。(細かいプロファイリングしていないから憶測)

また使った時にbashでfor文でぐるぐる回していると、たまにconnection redusedなどのexeptionが発生した。理由はさっぱり分かっていない。ログから失敗したデータを手動で流し込むと全く問題が無いのでなんでなんや。

こちらからは以上です。