limitusus’s diary

主に技術のことを書きます

YAPC::Asia 2015レポ

去る8/20,8/21でYAPC::Asia 2015に行ってきました。

2012,2013ではstaff参加し、2014,2015は普通の参加者です。
今年は最後のYAPC::Asiaということで、(個人スポンサーチケットは買えなかったけど)参加してきました。
本当はスタッフ参加できればよかったのだけど、仕事の都合がつかず断念…

ブログを書くまでがYAPC::Asia」ということで、これを公開したら俺のYAPC::Asiaは終了だ!!!

まず会場。ビッグサイト。大きい。
こんなに広いところでやるとは…スタッフ大変だろうなあとスタッフ脳になりながら行ってきました。

聞いたトーク

メリークリスマス!

http://yapcasia.org/2015/talk/show/a636430c-0fbf-11e5-8a02-43ec7d574c3a

今年はLarryが来る年、ということでLarryの基調講演でスタート。
Perl6の話かと思いきや半分くらいが指輪物語の話。読んでないので英語では付いていけない。同時通訳に頼る。
普段英語セッションでもあまり同時通訳には頼っていないんですが、ここだけは頼りました。
ついに今年の年末にはPerl6のリリースがありそう?期待していいのかな?という感じのKeynoteでした。

世界展開する大規模ウェブサービスのデプロイを支える技術

http://yapcasia.org/2015/talk/show/9ec2791c-05e5-11e5-81fa-79c97d574c3a

Miiverseを展開しているはてな任天堂からそれぞれ一人ずつの発表。
個人的には結構興味を持った発表でした。
ポイント

  • AWS複数リージョン
    • それぞれでmaster-slave
    • master同士が円環レプリ
  • デプロイ
    • mackerelでAutoScaleを使ったデプロイ→ もっとスケールできるpull型デプロイへ
    • consul + stretcher で実際に高速なデプロイが可能になっている
Consulと自作OSSを活用した100台規模のWebサービス運用

http://yapcasia.org/2015/talk/show/b335dee0-09ad-11e5-8d7a-67dc7d574c3a

fujiwara組の組長であるfujiwaraさんの発表。
上記トークで使っていたconsulとstretcherの話。
実際にどんなことができるのか、どうやって使っているのか、stretcherの設計思想などを聞くことができました。資料も充実。

うっかりをなくす技術

http://yapcasia.org/2015/talk/show/523b9508-0d77-11e5-8174-67dc7d574c3a

Human error ≠ mistake をベースに「どのようにしてmistake/near-miss」を減らすのか、
そのためにはどのような技術選択をすべきか、という話。

ISUCONの勝ち方

http://yapcasia.org/2015/talk/show/86ebd212-fab3-11e4-8f5a-8ab37d574c3a

ISUCON常連のkazeburoさんの発表。
どのようにISUCONの問題に取り組むか、ということが一通り話されました。
一番印象に残ったのはスライド最後の「勝つのは俺たちだ!」の1枚。

Perl 5.22 and You

http://yapcasia.org/2015/talk/show/3fe49c10-fa67-11e4-9e02-8ab37d574c3a

Perlのプロジェクトマネージャでもあるrjbsの発表。
Perl 5.22で新しく入った構文、逆に削除された構文について紹介されました。
個人的には結構いい感じになったんじゃないかと思っているところ。

ランチセッションB / 空間情報探索基礎論

http://yapcasia.org/2015/talk/show/e34fca9d-2ad1-11e5-aca1-525412004261

モバイルファクトリー提供のランチセッション。
普通ランチセッションって割とライトな発表がされて採用してるよ!ってアピールすることが多いのだけど、このトークはまさかのガチ発表。
地球上のGPS座標を用いた近傍位置情報検索技術についての発表がされました。
GeoHexのエンコード方法、近傍探索の手法が勉強できました。
あ、ごはんおいしかったです。

Perlでゼロから作るコンテナ

http://yapcasia.org/2015/talk/show/268d730e-136c-11e5-ac8f-d9f87d574c3a

実は妻の発表でした。
Dockerはコンテナ技術を様々に組み上げて作られた大きなプロダクトですが、そもそもその基盤にあるコンテナの技術とは?というところが勉強できる発表だったと思います。
namespaceの導入、uid namespaceを用いて実際にコンテナの中のuidを書き換えたりと、やりたい放題やれるコンテナの作り方のトークでした。

Profiling & Optimizing in Go

http://yapcasia.org/2015/talk/show/6bde6c69-187a-11e5-aca1-525412004261

途中から聴講。
Goのプロファイラって優秀なんですね。
実践的なプロファイリング手法がライブ紹介されていました。動画に期待。

全体を通して

新しく知り合いになれた人、久々に会う人、「またお前か」って感じで会う人など、いろいろな人に会えました。
YAPC::Asiaスタッフつながりの人とか、カメラマンの八木さんとかとは本当に1年振りだったりして(全員に挨拶できずすみません)。
同窓会っぽい面があるのもこの会のいいところだなと思います。

無限コーヒーすごかったですね。今までの会場では提供できなかったものです。どうやったんだろう…

最後のYAPC::Asiaを終えて

2011年から5年連続で参加してきてついに終わってしまうのが残念な限りです。
Opening/Closingでの牧さん、ありがとうございました。
いつも牧さんはボランティアスタッフの貢献を称えてますが、スタッフ経験者としてはやはり牧さんの力が大きかったんじゃないかと思っています。
今回は過去最多で参加者2000人超。そうそう開催できるものではありませんでした。大きなトラブルも(多分?)なく終了できたのはスタッフ全員のおかげです。CONBUのLTでのライブパフォーマンスもすごかったですね。あんなに早く設営、撤収してるのは初めて見ました。
Beaconの際は是非力になれればと思っています。
ということで、また!

うるう秒をテストしたら仮想インタフェースが落ちた話

今月末はうるう秒が予定されていますね。
http://jjy.nict.go.jp/news/leaps2015.html

これについては様々なところで「何が影響を受ける?」「どう対応する?」などが書かれています。

今回はその中でも、「事前に試験環境でうるう秒を入れてみる」ことについてRedHatの記事が書かれていたので、そのお話。
How to clear the Leap Second Insertion flag after it has been received?

この記事の中では leap-a-day.c というコードが公開されていて、簡単に言うと

ということをやってくれます。

これを試験環境で実行したところ、仮想ネットワークインタフェース(IP alias)が落ちたので、再現条件を記録しておきます。
なお、この問題にうるう秒は本質的に関係ありません

続きを読む

Perlからshared objectの関数を呼び出す

今回のお題

foo.so に含まれている関数 void func(void) をPerlから呼び出す。
プロトタイプ宣言の通り、引数は取らないし戻り値もない(あるいは見ない)。

やりかたはいくつかあって、

  • 普通ならXSモジュールを書いて対応する。
    • ただこのシンプルな目的のためにXSモジュールを書くのはいささか大袈裟すぎる。
  • もう少し簡単にやろうと思うと Inline::C を利用する。
    • これでも別に構わなかったのだけど、今回はこのPerlスクリプトをほぼ同時に並列起動する可能性があり、コンパイルが多重に走るのを避けたい。

ということで、ちょっと珍しいアプローチとしてXSモジュールのベースに使われているDynaLoaderモジュールを直接使ってみることにした。

続きを読む

Perlのglobはもうshellを呼ばない

もう10年以上前の話だが、メモ。

IPAのセキュア・プログラミング講座にある4-2. Perl の危険な関数には以下の記載がある。

便利な<> 構文,glob関数であるが,実は内部的にシェルを呼び出している。そのためリスト7の1行目のような文字列を渡した場合,パスワードファイルの内容をメールで送信できてしまう。

が、これはかなーり古いPerlでの話で、pre-5.6.0のみに当て嵌まる話。現在はFile::GlobというXSで記述されたモジュールがよしなにやってくれており、cshを内部でforkすることはない。

このあたりはperldeltaに詳しい。
https://metacpan.org/pod/release/GSAR/perl-5.6.0/pod/perldelta.pod

この記述、加筆修正されないんだろうか…

PerlでGoogle Calendar APIを勉強

アラートのメール通知がきたらGoogle Calendarに記入しておくとあとで振り返るのが簡単なんじゃないかなーと思ったので、まずはお勉強から。

要素

できるようになってから振り返ると、以下の要素を理解する必要があった。

これからそれぞれの要素について書いていこうと思う。
コードはほぼコピペだが、エラー処理(status=200でないとき)の処理は簡単のため省いている。

続きを読む

PerlでTwitter API SSL化に対応するたった1行

手元でTwitterの古いpostを削除するスクリプトをcron実行してるのですが、Twitter APIってSSLのみ対応になったのをすっかり放置してしまっていました。
cron実行に失敗してメール通知が来たので1週間くらい経ってようやく対応。

Net::Twitterを使っているのでバージョンを上げて、アプリ側では1行追加するだけ。

    my $nt = Net::Twitter->new(
        traits => [qw/OAuth API::RESTv1_1/],
        consumer_key => $config->{consumer_key},
        consumer_secret => $config->{consumer_secret},
        access_token => $config->{access_token},
        access_token_secret => $config->{access_token_secret},
        ssl => 1,  # ここを追加
    );
    if (!defined $nt) {
        die "Authentication Failed: $!";
    }

無事動きました。

Parallel::Fork::BossWorkerAsyncがいい感じ

先日 id:hirose31

  • 並列処理はParallel::ForkManagerとかParallel::Preforkが定番だけど、もうちょっと効率よくやりたいこともある
  • P::ForkManagerはタスクごとにforkするので負荷の分散は綺麗にできるが、タスクの数だけforkが発生して効率がよくない
  • P::Preforkだとfork回数は並列度分だけだが、タスク開始前にタスクの分配を完了させないといけない
  • Cでmultithreadならmaster-workerモデルでmasterにqueue持ってmutexでロックするような練習問題とかある
  • けどPerlでmultithreadやりたくないし、実現するとすればsocket経由でタスクを渡していく感じにしないといけないか
  • 誰かCPANに上げてるんじゃないかなー
  • なければ作るかー

的な話をしていました。

で、metacpanを漁っていたところ、それっぽいのを見付けました。Parallel::Fork::BossWorkerAsync

計算モデル

このモジュールは事前に1個のbossとk個のworkerプロセスをforkし、masterが都度タスクを生成して登録していきます。
workerはただただwork_handlerで与えられたsubを実行していき、計算結果をreturnします。
workerの計算結果が帰ってくるとmasterではresult_handlerで与えられたsubが呼び出されます。(たとえば結果を集めるオブジェクトに登録する)
最後にshutdownを呼び出すとbossと全workerが終了します。

プロセスツリーとしてはこうなります。

  └─perl,18371 bwa.pl # アプリケーション
      └─perl,18372 bwa.pl # boss
          ├─perl,18373 bwa.pl # worker
          ├─perl,18374 bwa.pl # worker
          ├─perl,18375 bwa.pl # worker
          ├─perl,18376 bwa.pl # worker
          └─perl,18377 bwa.pl # worker

bossプロセスは各workerとアプリケーションとタスク/結果のやりとりをするためにひたすらselect(2)を呼んでいるプロセスです。
workerプロセスはbossからタスクを受け取って処理したらbossに結果を返します。
アプリケーションプロセスはbossとだけ直接通信し、タスクを投げて結果を受け取ります。

利用例

大したものではないですが、podに書かれていないようなモデルでの利用例。

workerは単に1秒sleepし、自分のjob idを返します。
masterは返されたjob idを配列に追加していって最後にdumpします。
それだけ。

この例ではk=5としていて、最初に5プロセスが生まれた後はプロセスの交代は起こっていません。
タスク供給はちょっと不定期な感じにするために、17個ずつ供給し、終了次第次の17個を供給してます。
53 / 17 = 3あまり2
17個のタスクを5並列でやると4秒かかるので、
4 * 3 + 1 = 13秒で実行が完了します。

#!/usr/bin/env perl

use strict;
use warnings;

use Parallel::Fork::BossWorkerAsync;
use Data::Dumper qw(Dumper);
use Time::HiRes qw(gettimeofday);

my @Finished_Jobs = ();
my $PARALLELISM = 5;
# sleep time
my $NUM_WORKS = 53;
my $WORKS_AT = 17;

# この時点でworkerがforkされた
my $bw = Parallel::Fork::BossWorkerAsync->new(
    work_handler => \&work,
    result_handler => \&rhandler,
    worker_count => $PARALLELISM,
);

my $thrown_work = 0;
while($thrown_work < $NUM_WORKS) {
    my @tasks;
    for my $i ($thrown_work .. $thrown_work + $WORKS_AT - 1) {
        push @tasks, { id => $i, sleep => 1 };
        $thrown_work++;
        if ($thrown_work >= $NUM_WORKS) {
            last;
        }
    }
    # タスク集合はここでディスパッチされる
    $bw->add_work(@tasks);
    # 実行完了待ちタスク数が得られる。この関数はblockしない
    while($bw->pending) {
        # "return"されたオブジェクトをそのまま受け取る。以下のように単に呼び出すとblocking
        my $ref = $bw->get_result;
        # P::F::BossWorkerAsyncのレイヤでエラーがハンドルされた場合は ERROR というkeyにメッセージが入ってくる(タイムアウトを指定した場合など)
        if ($ref->{ERROR}) {
            print STDERR "ERR: ". $ref->{ERROR};
        } else {
            print $ref->{job} . "\n";
        }
    }
}

# workerプロセスを終了させる
$bw->shut_down;

print Dumper \@Finished_Jobs;

# worker側で各タスクに対してcallbackされる
sub work {
    my ($job) = @_;
    my $id = $job->{id};
    my $t0 = gettimeofday;
    print "$t0 start $id\n";
    sleep $job->{sleep};
    my $te = gettimeofday;
    print "$te end $id\n";
    return { job => $id };
}

# master側でタスク終了時にcallbackされる
sub rhandler {
    my ($result) = @_;
    my $job = $result->{job};
    push @Finished_Jobs, $job;
    return $result;
}

内部的にData::Dumperを使ったシリアライズをしているらしく、データの区切りに決め打ちのバイト列を指定する必要があります。そこはStorable::nfreeze/thawした方がいいんじゃないかな?と思ったりはします。
P::ForkManagerP::Preforkに比べると記述は増えますが、用途によっては便利なのでは?