kaeruspoon

忍者ツールのリンクがけっこうヒドい

たまたまユルさんのサイトを携帯で見たら、でかでかと出会い系サイトへのリンクがはられていてびっくりした。ユルさんもびっくりしていた。よく見てみると、忍者ツールのカウンターが勝手にリンクを追加していたらしい。PCサイトでは表示されてなかったのでずっと気づかなかったけど。隠しリンクならまだかわいらしいけど、他コンテンツを圧倒せんとする勢いでデカいリンクをはるなんて忍者ツールもけっこうすごい。あまり一緒に仕事をしたくない人たちだ。
すぐにユルさんは忍者ツールをやめたので、代わりのアクセス解析+カウンターツールをつくってあげた。

iPhone SDKのNDA解除。新しい契約はまだかな

iPhone SDKのNDAが解除されるというニュースから、もう十日になろうとしている。NDA抜きの新しい契約はまだなのかな。
クックパッド・カカクコムの共催勉強会での発表だけど、新契約が間に合えば食べログiPhoneアプリについて話そうかなあと考えている今日この頃。Rails2.2の話よりはいいんじゃないかな。
新契約が間に合わなかったら…NDAにかからないようにうまいこと話そうか。そんな器用なことできるんかな。
とりあえずこの連休ではiPhone用の資料をつくることにします。

au Smart Sportsはけっこうすごい

au Smart Sportsを使ってみたけど、けっこうすごいです。
一番いいのは、通ったコースがあとからマップで確認できるところだし、なによりルートの標高もグラフでわかるところ。
情報はサーバに随時送られてるみたいで、帰ってきてからPCサイトでも確認できます。こちらでは通ったルートがなぞって表示されたり標高グラフも同時にポイントされたりして、地図上の位置の標高も一目瞭然。見ているだけで楽しい。
ひさしぶりに見ているだけで楽しいwebサービスです。ハードウェアを組み合わさると、まだまだこんなに楽しいことができるんだなあ。日本の携帯はすごいや。

バイクがへたくそになっていた

ひさしぶりに野上さんの家におじゃましてきました。
そこで野上さんのNC30に乗せてもらったのだけど、全然乗れてなくてびっくりした。バイクに乗るのは3年ぶりくらいだったけど、めちゃくちゃ下手くそになっている。危機感を覚えた。このままではバイク乗りではなくなってしまう。早いうちにバイクを買わねば……。

クックパッド&カカクコム共催・勉強会で発表してきました

あんなに大勢の前で話すのははじめてだったのですが、特に緊張することもなく楽しく過ごすことができました。懇親会ではたくさんの人たちといろいろなお話ができてとても楽しかった。
話してばかりでご飯が食べられなかったので、帰りにカップラーメンとコーラを買って帰りました。風邪ぎみなので土日はのんびりしよう。あと、携帯向けの画像投稿サイトでも作ろうかと思います(おもに自分用)。

実践 Rails -強力なWebアプリケーションをすばやく構築するテクニック: Brad Ediger, 株式会社クイープ: 本

実践 Rails ―強力なWebアプリケーションをすばやく構築するテクニック

「実践 Rails ―強力なWebアプリケーションをすばやく構築するテクニック」を買おうかと思います。自分メモ。

プログラマが若隠居をしたら

今日、若隠居をして喫茶店をやったり農業をしたりしてのんびり過ごしたいというような話をきいた。まったくもって同感である。でもぼくは農業はしたくない。なぜならぼくは子供の頃から祖父の農業を手伝っていたので、もう二度と携わりたくないというのが本心なのだ。喫茶店もやりたくない。人と会うのも話すのもメンドくさい男なので、喫茶店を経営している自分の姿を想像しただけで憂鬱になりそうだ。
もし、プログラマをやめて若隠居するとしたら、のんびりとプログラミングをして過ごしたい。

iPhoneアプリで地図をぐりぐり動かす方法。

iPhoneアプリは数多しれずだけど、デフォルトのマップアプリのように地図を表示して動かせるアプリは意外にも少ない。その理由は単純で、マップに関するクラスが用意されていないからだ。
iPhoneアプリの開発に入る前は、マップクラスのようなものが用意されていて(UIMapViewみたいな)、簡単に地図をぐりぐり動かせると思っていたのだけど、そうは問屋が卸さなかった。そんなものないのだ。
で、アプリで地図を動かそうとすると、なかなかにメンドくさいことをやらないといけない。
ぼくが今のところ考えている方法はふたつあって、ひとつはUIWebViewを使ってgoogle Map APIを利用する方法。もうひとつはタイル状の地図のイメージを周囲の移動時のバッファ分も含めて取得しておく方法。ぼくが実際に採用したのは前者の方法だ。

1.UIWebViewで、表示領域いっぱいに地図を表示するように設定したweb上のページにアクセスする(UIWebView自体はイベントを無視するようにしておく)。
2.タッチパネルのイベントをキャッチして、その動きを実現するようにJavascriptのコードを生成し、UIWebViewに投げてあげる。
3.地図上のピンや、ボタンなどは、iPhone側のオブジェクトとして配置する。

この方法で実装した地図は、iPhone Simulator上ではストレスなく気持ちよく動く。まったく問題ない。しかしiPhone実機上ではレスポンスの悪い動きになってしまう。アクションにワンテンポ遅れて地図がついてくるのだ。さらに拡大・縮小がとても遅い。拡大・縮小に関しては仕方なくそれ用のボタンを配置したけど、はっきりいってカッコ悪い。
レスポンスを求めるなら、二番目の方法を試してみたほうがよさそう。だれかもっとうまいやり方を持っていたら教えてほしいな。

MySQLコンファレンス2008 2日目に参加してきました。

MySQLコンファレンス2008に参加してきました。同時通訳というものをはじめて経験したけど、けっこう理解しにくいものですね。ふつうに英語を聞いていたほうがよかったかも(英語もよく理解できないけど)。ところどころ、頭が混乱してしまってよくわからなかったところがありました。
仕事があったので2日目だけの参加でした。

ぼくが聞いてぼくなりに理解した内容だったり(またはよく理解できていない内容だったり)するので、事実とは異なるところもあるかもしれません。

1.MySQL Performance Tuning 1
ボトルネックとなる箇所をさぐることが大切
スロークエリログ
 ・基本
 ・十分詳細ではない
 ・どこが非効率なのかまではわからない
 ・時刻(時間帯による環境の影響は?)、ユーザ(どのアプリ?)を確認
 ・実行時間、問題のクエリを確認する
 ・mysqldumpslowでスロークエリログの統計をとれる(5.1で若干のバグあり。修正予定)
 5.1からの新機能
  ・テーブルにもログをはける
  ・マイクロ秒単位で記録
  ・long-query-timeをゼロにできる(すべて記録)
Explain
 ・select_typeでの DEPENDENT は注意
 ・typeでの index はインデックスをすべてチェックしている(limitで回避できるかも)
 extra
  ・using where : インデックスだけでなく他の条件でも
  ・using temporary : 前のステップのrowがtemporaryに入る
  ・using filesort : 取得中のrowをsortしている。実際にファイルを使っているわけではない。
  ・using index : インデックスのみを使用
 mk-visual-expla
  ・このツールでExplainをビジュアル化
  ・www.maatkit.orgを参照
クエリキャッシュ
 ・クエリをハッシュ化してキーとしている
 ・そのため同じ結果が返るクエリでも一文字異なるだけど別物として扱われる
 ・DATE()など、毎回結果の異なる関数などが使われているとキャッシュされない
 ・show global statusの com_select(キャッシュミスの数)とQcache_hits(ヒットした数)
 ・キャッシュサイズを大きくしすぎると頻繁にパージが走る
 ・パージが走っているときは他の動作がすべてとまる(パフォーマンス低下)
 ・クエリキャッシュ自体がボトルネックになる可能性も

2.MySQL 5.1で押さえておくこと
テーブルのパーティショニング
 ・パーティションの最大数は1024
 ・アプリ側で意識する必要はない
 ・ハッシュパーティショニングはプライマリキーを対象にする(それ以外を使うとパフォーマンスが落ちる)
 ・リストパーティショニングはマップされていないものは最後に入る
 ・階層化も可能
 ・InnoDBのバッファプールが適切に働いている環境ではあまり効果はない
 ・desc partitionsで詳細情報
XMLとXpathの採用
 ・SQLの中でXPathが使える
 ・XML自体はblobとして格納
 ・特別な型があるわけではなく、XMLであることを使用者が意識しておく必要がある
MySQL Cluster
 ・ディスクベースも可能に
 ・クラスタまるごとレプリケーション可(別のデータセンタとか)
行ベースのレプリケーション
 ・ステートメントベースと比較して、insertのコストは一緒
 ・updateで対象行が増えるほど行ベースはコストが高くなる
 ・行が多いと予測されるときはステートメントベースに設定すればいい
 ・InnoDBのパフォーマンスがあがる(ロックが走らない)
 ・クエリの対象行が少なければ採用したほうがよい
Eventの採用
 ・タスクスケジュール
alter table と add(drop) indexの高速化
興味があったらdev.mysql.comへ

3.@Niftyブログサービス「ココログ」PostgreSQLからMySQLへのマイグレーション事例
概要
 ・six apartが開発
 ・月間PVは数億
 ・ユーザ数はもうすぐ80万
 ・ユーザは無料会員のほうが多いが、実際に記事を書いているのは有料会員のほうが多い
 ・mysql5.0 + InnoDB
 ・memcached
 ・The Schwartzでジョブ管理
PostgreSql時代
 ・MySQL採用前はずっと1DB
 ・DBが各アプリと密結合
 ・DBリソースのコントロールが難しくなってきた
 ・memcached、API経由とすることで結合度を下げた
 ・データ100GB以上(うち40%はインデックス)
 ・VACUUM処理が必要
 ・文字コードによって不良データとして扱われ、insertはできるのにdump-restoreができない)
DB Partitioningへ
 ・DBを複数台用意し、意味によってデータを振り分け。
 ・移行作業に数ヶ月かかった
MySQLに移行して
 ・レプリケーションはバックアップのために使用
 ・クラスタはHA cluster使用
 ・ディスクはFiberChannelでSANに
 ・order by なしの結果がPostgreSqlと違う
今後
 ・コメント、トラックバックなどはジョブにより反映するように

4.MySQL Performance Tuning 2
ベンチマーク
 ・計測時はログをすべて止める
 ・クエリキャッシュもオフに
 ・メモリバッファは十分大きくする
MyIsam、MyIsam with INSERT DELAYED、InnoDB、Archiveのinsertの性能をテスト
 ・MyIsamは64connection以上で低下
 ・INSERT DELAYEDは64から横ばいに
 ・InnoDBも64以上で低下
 ・Archiveは256connectionでも上昇
 チューニングポイントを探る
  CPUの状態を確認
   ・MyIsamではやはり64connection以上で下がっている
   ・他のEngineはOK
   ・理由はMyIsamのテーブルレベルのロック
   ・ArchiveはいつでもCPU性能をフルに引き出す
  ディスク使用率を確認
   ・InnoDBは利用率が高く、64connectionでピーク
   ・他Engineは少ない
   ・InnoDBはトランザクション処理があるため
時刻を記録する処理の性能をテスト
 ・timestampカラムの使用が一番はやい
 ・triggerを使用する方法がもっとも遅い
Index Mergeの性能をテスト
 OR条件のクエリ
  ・Index Mergeとそれぞれの条件のクエリのunionで比較
  ・クエリのunionよりもIndex Mergeのほうがはやい
 AND条件
  ・Index Mergeとマルチカラムインデックスの比較
  ・マルチカラムインデックスのほうがはやい
  ・柔軟性はIndex Mergeのほうがある
自己結合なクエリ
 ・where句でサブクエリ → かなり遅い
 ・サブクエリの結果とjoin → はやくなる
 ・viewを使う → joinの場合とかわりなし
 ・実テーブルを作ってjoin → もっとはやい
Explainよりもくわしくクエリを確認
 ・新しいコネクションでクエリを実行後に show session status like 'hand%';

5.MySQLデータベースレプリケーションを理解する
一般的なレプリケーションの動きの説明
MySQL Cluster
 ・shared nothingなど
 ・メモリ上で動く(5.1からはディスクベース)
 さまざなクラスタ構成の説明

6.インデックスを使いこなす
・資料公開予定
・ディスクI/Oを意識することが大切(CPUやメモリに比べて遅いため)
・SSDがディスクの10倍程度の速度があるので今後に期待
インデックスの処理
 ・ルート->ブランチ->リーフ->データ
 ・ブロック単位で読み込まれる
 ・ルート、ブランチは必ずキャッシュされると考える
 ・実際にI/Oが発生するのはリーフとデータファイルの読み込み
InnoDBのインデックスは
 ・主キーのインデックステーブルはキーとすべてのカラム値をもっている
 ・セカンダリキーは主キーへの参照をもっている
 ・MyIsamと比較してインデックスまわりの処理はInnoDBのほうがはやいことが多い
 ・できるだけ主キーのみで、しかも小さいサイズのものにする
範囲選択
 ・リーフから複数のエントリをとってデータファイルを読む
 ・ディスクI/Oはブロック単位なので、近接しているデータなら一度のreadでOK
 ・データファイルは順不同なのでエントリの数だけreadが必要
 ・通常、readの数は1+Nになる
 ・大量のデータを取得するときはデータファイルのI/Oが大きくなりすぎるので、フルテーブルスキャンになる
  ・インデックスを使用するよりもはやい
  ・データファイルをブロック単位で読み込むのでI/Oが減るから
  ・先読み機能があればもっとI/Oは少なくなる
  ・10%~15%以上のデータを取得するときはフルテーブルスキャンのほうがはやい
Covering Index
 ・インデックステーブルだけを使用するクエリ(Explain で Using Indexと表示)
 ・リーフだけ読めばいいので相当はやくなる。I/Oが一回ですむことも多い
 ・発生条件は、select句とwhere句がすべてインデックス(select * はだめ)
 ・マルチカラムインデックスをねらう
 ・Explainで type が rangeやindexのときは、Covering Indexをねらうのがチューニングのポイント
マルチカラムインデックスは
 ・それぞれのキーがAND条件のとき使われる
 ・I/Oは二回ですむ
 ・Coverring Indexにするために不要なカラムもあえてインデックスにする
Index Merge
 ・それぞれのリーフの検索結果をマージしている
 ・I/Oは三回以上。
 ・マージのオーパヘッドもあり
 ・AND検索ならマルチカラムインデックスがいい
 ・でもIndexMergeはORでも使える
where order by
 ・テーブルの状態とどこのキーが使われるかの組み合わせで結果が大きく変わる
 ・MySQLで最適なものが選択できる保証がない
 ・FORCE INDEXやIGNORE INDEXを使って最適化する
インデックスは昇順になるように
 ・キーが昇順になるようにinsertすればリーフの断片化が起こりにくい
 ・リーフの断片化が起こるとキャッシュされにくくなったり、I/Oが増える結果に
  ・selectの性能にも影響を及ぼす
 ・キーはできうるならばauto incrementがよい
  ・InnoDBはロックが発生するため負荷が高くなると性能が劣化していた(MySQL5.1で解決)
 ・緩衝サーバを用意してindexなしでそこにinsertし、昇順にした上で正規のサーバにinsertする方法もある
 ・Q4Mなど