ix2015のipsecではまったこと

なんだかんだでかぎ交換が重要。
ikeは鍵交換用のプロトコルだよね
show ike saとか show ike statisticsとか、 show ike ?は何度も確認しよう。

片方が可変のIPアドレスのときは、つなぎにいくほう、可変IPアドレス側にikeのlocal-idを指定しよう。
待ち受け側、固定IPアドレスのほうにはつなぎに行くほうと同じremote-idでidを指定してやろう。
そうしないと ike peer or id configuration not foundっていうのがsyslogに吐かれるよ。
ikeさえつながってしまえばあとは簡単。

HTML5のAudioタグをJavascriptから扱う

audioタグについての説明は省略。
今までの感覚だと、Javascriptで何かしらの動作をさせるには、基本的にはhtml要素がある必要があったけど、どうやらaudioタグについては無くても良いっぽい。
というのは、DOMツリーに

<audio src="audiofile.mp3"></audio>

とかが無くても良いって意味。
じゃあどうやって操作するのか

var obj = new Audio('audiofile.mp3');

obj.addEventListener("canplay", function(){
  obj.play();
});

で、再生可能になった段階で自動的に再生される。htmlにaudioタグを追加してCSSでdisplay: noneとかしなくても良い。
objをconsole.logすると、中身はaudioタグそのもの。だけどDOMツリーには追加して無い。
ただ、videoタグでは表示部分がvideoタグそのものだからか、動かないっぽい。
上のコードの続きで、再生終了したら違うファイルを再生とかなら

obj.addEventListener("ended", function(){
  obj.src = "nextfile.mp3";
});

DB_Tableで利用されているMDB2について

DB_Tableで利用されているMDB2についてのメモ。

DB_TableではバックエンドのコネクションにMDB2を利用することができる。
この辺いろいろ複雑だけどメモメモ。

実際にDB_Tableを利用してselectとか発行すると
DB/Table/Base.phpの

// get the result
if ($this-&gt;backend == 'mdb2') {
$result = $db-&gt;extended-&gt;$method($sql, null, $params);   // この辺
} else {
switch ($method) {

この辺が呼ばれる。
これの$db->extendedって MDB2/Extended.phpで、

function getAll($query, $types = null, $params = array(),
$param_types = null, $fetchmode = MDB2_FETCHMODE_DEFAULT,
$rekey = false, $force_array = false, $group = false)
{
$db =&amp; $this-&gt;getDBInstance();
if (PEAR::isError($db)) {
return $db;
}
settype($params, 'array');
if (empty($params)) {
return $db-&gt;queryAll($query, $types, $fetchmode, true, $force_array\
, $group);
}

この辺が呼ばれる。getDBInstance()はMDB2.phpにあって、

function &amp;getDBInstance()
{
if (isset($GLOBALS['_MDB2_databases'][$this-&gt;db_index])) {
$result =&amp; $GLOBALS['_MDB2_databases'][$this-&gt;db_index];
} else {
$result =&amp; MDB2::raiseError(MDB2_ERROR_NOT_FOUND, null, null,
'could not find MDB2 instance');
}
return $result;
}

こんな感じ。
で、グローバル変数の$GLOBALS[‘_MDB2_databases’]とかってある。
ほんでこの$dbを使ってqueryAll()を呼び出してる。
queryAllはExtended.phpにあって、

function queryAll($query, $types = null, $fetchmode = MDB2_FETCHMODE_DEFAUL
T,
$rekey = false, $force_array = false, $group = false)
{
$result = $this-&gt;query($query, $types);
if (!MDB2::isResultCommon($result)) {
return $result;
}

$all = $result-&gt;fetchAll($fetchmode, $rekey, $force_array, $group);
$result-&gt;free();
return $all;
}

// }}}
}

こんな感じ。
そんで$this->queryはMDB2.phpにあって

function &amp;query($query, $types = null, $result_class = true, $result_wrap_class = false)
{
$offset = $this-&gt;offset;
$limit = $this-&gt;limit;
$this-&gt;offset = $this-&gt;limit = 0;
$query = $this-&gt;_modifyQuery($query, false, $limit, $offset);

$connection = $this-&gt;getConnection();  // このへん!
if (PEAR::isError($connection)) {
return $connection;
}

$result =&amp; $this-&gt;_doQuery($query, false, $connection, $this-&gt;database_name);
if (PEAR::isError($result)) {
return $result;
}

$result =&amp; $this-&gt;_wrapResult($result, $types, $result_class, $result_wrap_class, $limit, $offset);
return $result;
}

で、これの”このへん!”のところでgetConnection()してるけどコイツがMDB2.phpの

function getConnection()
{
$result = $this-&gt;connect();
if (PEAR::isError($result)) {
return $result;
}
return $this-&gt;connection;
}

これで、$this->connect()がMDB2/Driver/mysql.phpとかにあって

function connect()
{
if (is_resource($this-&gt;connection)) {
//if (count(array_diff($this-&gt;connected_dsn, $this-&gt;dsn)) == 0
if (MDB2::areEquals($this-&gt;connected_dsn, $this-&gt;dsn)
&amp;&amp; $this-&gt;opened_persistent == $this-&gt;options['persistent']
) {
return MDB2_OK;
}
$this-&gt;disconnect(false);
}

$connection = $this-&gt;_doConnect(
$this-&gt;dsn['username'],

このへんにありますよ!ってお話!

疲れたー。

第三回クラウド勉強会(NoSQL)

第三回クラウド勉強会(NoSQL)に参加中です。

スライドは未発見。LTは話がおもしろくてテンポがよくて、メモする余裕がありませんでした。

最初のスピーカーはさくらインターネットの大久保 修一さん

  • マルチテナントKVSについて。
  • KVSってmemcachedとかをバックエンドに持っているNoSQLの一つ
  • このKVSをホスティングする  <– でも、おたかいんでしょう?
  • 実はMySQLのホスティングもしてますよ
  • Flareを使います。
  • flareはサーバが三つ必要、インデックスサーバ、ストレージサーバ、プロキシサーバ
  • これ三つもサーバ必要なんだけど、これらをクラウドのサービスとしてホスティングするにはどうしたらいいか
  • 名前空間で分離すると、オーバーヘッドはなくなるけどソフトウェアの改変が必要で大変
  • 複数プロセスだとさっくりできて、オーバーヘッドはそこそこだけどちゃんと分けれるね
  • 仮想マシンとVLANでそれぞれのマシンを仮想化すると独立性が高いけどオーバーヘッドが無視できない
  • そとからの接続はロードバランサを通す。プロキシサーバがLB機能も持ってる。
  • ストレージサーバ間はパーティションが切ってあるけど、必要に応じて隣に聞きに行く
  • LVS、DSR使って直接LBを介さず返答。
  • テストユーザ募集中
  • kumo FSに比べて、Flareは
  • 高速。デバッグが簡単 -> memcachedプロトコルが流れてるから、らしい <– memcachedプロトコルって見やすいのかな
  • 高速な理由
  • setが完了してもメモリに書かれているだけなのでディスクに書かれていない。
  • ストレージサーバ間でのハッシュの散らばり具合が均一じゃない、結構偏って各サーバに散らばる。
  • インデックスサーバが冗長化できない。
  • flush_allコマンドはレプリケーションコマンドがきかない <– memcacheとかでも・・・
  • telnetのみしか接続できない
  • クラウドに乗るPaaSとしてNoSQLを検討している。

二人目はGREEの藤本さん。

  • クラウドからNoSQLになってますよね
  • SQLで高度にjoinとかさせるとshardingとかできないからシンプルなsqlになっていくよね。
  • 200台以上クラスタが動いてる!
  • CAS – 多くのNoSQLではトランザクションがないのでバージョン番号を振ろう(mvccみたいな)
  • 単体でパフォーマンスがめっちゃ出る
  • いろいろとでっかくするとdisk i/oに引っかかる。
  • ネットワークの上限にかかることがあるよ
  • でっかいデータを気軽においてしまうとまずいかもしれないよ。
  • たとえば100kのデータを10k qpsすると1GB/sになるよ。
  • fullmeshな通信だとまずいよね、ノードが増えるとプロキシサーバを利用してfullmeshな通信をしないように。
  • crlfがデリミタになってるので、インジェクション食らうよ <– memcache系とか特に
    flushall

三人目は神戸デジタルラボの岩瀬さん

  • distributed kvs
  • memcachedはdistributedじゃないらしい
  • phpで動くsimplecacheっていうkvsあるらしい。
  • okuyamaについて。
  • 全部javaで作ってる
  • memcached, httpもサポートしてるよ
  • 10000クライアント問題
  • nioっていうjavaのキューイングモデルを参考に、多段queueを実装
  • 連鎖ダウン 80% 80% 80%だと一台落ちたとき120% 120%になってまずくね?
  • ストレージの保存方法は4種類
  • バーチャルメモリ
  • keyだけメモリに書いたりするらしい <– キーだけ保存するだけでも全然違うのかな、検索かな
  • 一貫性で三種類の一貫性がある <– これの仕組みがおもしろそう、あとで調べてみよう
  • key+valueにさらに+tagしてる。タグで行を取れたりする
  • okuyamaで
  • get 480万回/min 8万回/sec
  • set 290万回/min 4万回/sec
  • これぐらいの性能
  • hdfs

四人目は楽天の西沢さん
ROMAというNoSQLDB

  • リストをサポートしたNoSQL
  • プラグイン機能があってユーザ拡張が結構できるNoSQL
  • でっかいデータもはいるけど基本的には1k-5kぐらいのデータを。
  • 断片化されたHTMLとかセション情報とか閲覧情報とかを入れてね
  • プラグインを書くためのDSLがあるよ。
  • flagオプションあるよ、CASいけるよ
  • consistent hashing
  • sha-1 <– えすえいちえーわん じゃないのか・・・ しゃーわん
  • ROMAはリング型で横のつながりがあるよ。各ROMAのプロセスは他のリングの位置とかを知ってるよ。
  • memcachedプロトコルをベースに作られているので、memcacheクライアントが普通に使えるよ
  • dslはruby構文ですよ
  • dslによててコマンドプラグインを拡張できますよ。
  • ROMAは楽天のいろいろなところで使われていますよ

DB_Tableを利用しながらコネクションを切ったらどうなるか調べてみた

DB_Tableを利用しながらコネクションを切ったらどうなるか調べてみた。

立ち上げっぱなしになるデーモンでは、インスタンスの生成にコストがかかるので、mysqlのコネクションを張りっぱなしでやっていた。

でもそうなるとさすがに待ち受け側でコネクション数がかなりいっぱいになってしまうので切ってやらないといけない状況に。

某所で、”LL(Lightweight Languagage) なんて再接続のコスト安いんだから、javaみたいにコネクションプーリングとか考えずに毎度毎度つないじゃえばいいんだよ”、というアドバイスを小耳に挟んだ物で。

で、利用していると、DB_Tableでは最初に突っ込んであげたMDB2のインスタンスがdisconnect()されてても、なんか適当につなぎ直してくれるらしい。

そこでまずは再接続にどれぐらいのコストがかかるか検証してみた。

$dsn = 'mysql://dbuser:[email protected]/db';
$conn =&amp; MDB2::connect($dsn);
$tbl = new hoge_DBTable($conn, 'db.hoge', 'safe');

define('MAX_COUNT', 10000);
$starttime = microtime(true);
for($i=0; $i &lt; MAX_COUNT; $i++){
$sql = array('select'=&gt;'data');
if(PEAR::isError($rows = $tbl-&gt;select($sql))){
die;
}
//var_dump($rows);
}
echo ($res1 = microtime(true) - $starttime)."\n";
$starttime = microtime(true);
for($i=0; $i &lt; MAX_COUNT; $i++){
$conn-&gt;disconnect();
$sql = array('select'=&gt;'data');
if(PEAR::isError($rows = $tbl-&gt;select($sql))){
die;
}
}
echo ($res2 = microtime(true) - $starttime)."\n";
echo $res2/$res1 . "\n";

で、これの結果


5.72950482368  // つなぎっぱなしで10000回
111.679533958 // 切りまくって10000回
19.4920045266 // 時間的な比率

かなり時間がかかってしまった。

とくにクライアント側ではなくてサーバ側の負担が大きくて、CPU使用率が50%を超えてる状況。場合によってはこれがサーバの負担になることも十分考えられる。

アットマークでエラーを抑制したときのオーバーヘッドについて検証してみた with php5.3三項演算子

アットマークによるエラー抑制を行った時のオーバーヘッドが大きいと聞いたので検証してみた。

アットマークを使うとコードがきれいに書けたりするけど、それでオーバーヘッドが大きくなったんじゃ困るなぁ、ってことで。

今回はphp5.3から導入された、三項演算子の省略形についてテストしてみた。

この省略形、三項演算子を利用し始めたころから常々、こんなのでないかなーって待ちわびてた。だって同じ変数を二度書く、そしてそんなのがアチコチにあるのなんて耐えられない!(マクロ関数あれば・・・、ね)

&lt;?php
define('MAX_COUNT', 10000000);
$time_start = microtime(true);
for($i=0; $i &lt; MAX_COUNT; $i++){
$hoge = @$unk ?: true;     // &lt;-- コイツを検証1
}
echo $test1 = (microtime(true) - $time_start)."\n";

$time_start = microtime(true);
for($i=0; $i &lt; MAX_COUNT; $i++){
$hoge = $unk ?: true;     // &lt;-- コイツを検証2
}
echo $test2 = (microtime(true) - $time_start)."\n";

echo $test1 / $test2;

結果


%php atmark.php
0.111232042313  // アットマークあり (100,000回)
0.0561020374298 // アットマークなし
1.98267384589 // (倍)

%php atmark.php
1.11259889603// アットマークあり (1,000,000回)
0.561910867691 // アットマークなし
1.98002736733 // (倍)

%php atmark.php
11.166533947 // アットマークあり (10,000,000回)
5.58266806602 // アットマークなし
2.00021455959 // (倍)

およそ二倍の差があることが判明。試行回数に対してきれいに比例し、アットマークのあり、なしではこちらもきれいにおよそ二倍の比率をキープした。

今回の環境ではcpuにxeon X3330(4core 2.66GHz)を利用した。他には大してアクティブなプロセスがない状況。この環境ではアットマークによるエラー抑制のコストは1回あたり0.000006秒、6マイクロ秒と見られる。正直大したことないかも。

もちろんコストがかかることを気にせず、バンバンどこの箇所にでもアットマークを打つのはよろしくないことで。

ついでに今回は比較されるべき書き方があったので、そちらの書き方ともコストを比較してみた。

今回の事の発端となったのは、undefined variable(Undefined index)がNoticeで発せられていたことである。で、isset()を利用すべきか、@を利用すべきかで悩んでみた。

define('MAX_COUNT', 10000000);
$time_start = microtime(true);
for($i=0; $i &lt; MAX_COUNT; $i++){
$hoge = @$unk ?: true;     // &lt;-- コイツを検証1
}
echo $test1 = (microtime(true) - $time_start)."\n";

$time_start = microtime(true);
for($i=0; $i &lt; MAX_COUNT; $i++){
$hoge = isset($unk) ? $unk : true;     // &lt;-- コイツを検証2
}
echo $test2 = (microtime(true) - $time_start)."\n";

echo $test1 / $test2;


%php atmark.php
11.0903561115 // アットマークあり (10,000,000回)
1.57850503922 // isset()で逃がした
7.02586044133 //(倍)の開き

なんと性能に7倍もの開きが。ちょっとびっくり。でも一回あたりのコストはかなり小さいけどね。

まとめ

  • アットマークのエラー抑制はコストがかかる
  • でもそれって6マイクロ秒とかで1つのフローのなかでは無視できる値かも
  • ただしforループとかでガシガシ使われるようなところだとまずそう
  • 個人的には$hoge = @$unk ?: @$pokemon;好き。マジカッケーッス。
  • そもそもNoticeだとデフォルトで出力されないとか、php.ini-productionとか普通の本番環境だとwarningだってdisplay_errorsで出てこないよ、とか。

mysql casual talks #1

mysqlについて

  • IPAの調査でshareがPostgreSQLを超えた。一位は圧倒的なOracle、次いでSQL Server
  • top20でいっぱいつかわれてる。
  • oracleがmysql対応になるよ。
  • 5.5って聞けば聞くほど使ってみたいな!でも性能が落ちてやめた経緯が。releaseされたらもう一度挑戦してみよう。
  • mysqlの認定資格とか研修とかもあるらしい!

mysql casual talks #1 オンラインスキーマチェンジ

nhayashi || n_hayashi

  • DeNAの方。
  • Online Schema Change  facebookで使われてるらしい。
  • もともとphp。
  • 普段DeNAでテーブル変更は、 三種類
  • alter打つとテーブルロックがかかる。これをよしなにしてくれる。 -> テーブルロックかかります。
  • verbose=1するといっぱいsqlがでてくる。
  • binlogは出さないようにしよう。
  • 手元ではうまくうごいているらしいです。

mysql casual talks #1 MySQLデータ分割入門

DeNA の@xaicronさんによるMySQLデータ分割入門。

  • shardingってPkeyのmoduloでわけましょう。
  • shardingの注意点について。シーケンスを外だしする必要がある。 -> どゆこと? ->
  • メモリに乗り切らないデータが載るようになる。これが最高!
  • partitioningについて
  • 特定の条件でテーブルのデータ自体を分割して管理することができる。
  • 刈り込み特定のパーティションだけにsqlを走らせる、ので早くなるよね。
  • twitterなら日付ごとに分けるといいよね -> 考えてみれば過去のデータは即時取り出すわけではないし、理にかなってる。すごいなぁ。
  • alter talbe talbe  drop partition
  • shardingとpartitioningは併用できます!