2011/10/29

App::Prove::RunScriptsで快適テスト生活

App::Prove::RunScriptsで快適テスト生活

公開場所

開発動機

WebアプリケーションのデータストアにMySQLを利用している場合、テストでTest::mysqldを使っていると思います。
しかし、各テストファイル毎にmysqldを立ち上げていると、テストファイルが増加した際に、mysqld立ち上げのオーバーヘッドが問題になります。
これを解消すべく作成しました。

既存の解決策

  1. にひりずむ::しんぷる make test で Test::mysqld を永続化させる方法
  2. Craftworks Tech Blog - Branch Test::mysqld を別ウィンドウで立ち上げたら開発時の prove が快適過ぎる件

問題点

  1. Module::Install::TestTargetは色々と便利なこともできるが、単純にテスト実行前にTest::mysqldを叩くだけには大げさ過ぎる
  2. 裏で先に立ち上げておくのは正直めんどうだし、忘れそう

こんな感じの問題点と普段の開発中はmake testなんて叩かないでproveをメインに使っているということもあり、proveライクに使えるコマンドが欲しいということでカッとなって作りました。

インストール

    $ cpanm App::Prove::RunScripts

使い方

上記コマンドでインストールされたprove_runscriptsコマンドを使用します。proveの薄いwrapperで、before/afterオプションが新規に追加されています。
後は実行したいスクリプトを指定するだけです。複数指定もできます。
xaicronさんの記事にあるsetup_mysqld.plをそのまま利用できると思います。

    $ prove_runscripts --bofore t/scripts/setup_mysqld.pl --state=save -lr t/

2011/10/23

Remedieのニコ動のembedを修正

とりあえず修正したものはgithubにあげてあります。

今月の途中からremedieでニコ動を見ようとすると、以下のポップアップが出てきて閲覧できなくなった。

This video is deleted or does not allow embeds

該当箇所のコードを確認すると、wv_titleの後にfv_autoplay、fv_new_windowを埋め込んでいる模様。
(恐らく)ニコ動側の変更でwv_titleが削除されていたので、wv_idを基準に埋め込むように修正

    diff --git a/lib/Remedie/Server/RPC/Player.pm b/lib/Remedie/Server/RPC/Player.pm
    index 14a959b..37ef936 100644
    --- a/lib/Remedie/Server/RPC/Player.pm
    +++ b/lib/Remedie/Server/RPC/Player.pm
    @@ -42,8 +42,10 @@ sub nicovideo : POST {
         ## Whoa HACK
         my $code = $response->content;
         $code =~ s/document\.write\((.*?)\)/\$("#embed-player").html($1)/g;
    -    $code =~ s/(wv_title.*?)$/$1\n, fv_autoplay: 1, fv_new_window: true/m
    -        or die "This video is deleted or does not allow embeds";
    +    $code =~ s/(wv_id.*?)$/$1\n, 'fv_autoplay': '1', 'fv_new_window': 'true'/m;
    +    if ( $code =~ /isDeleted: true/ ) {
    +        die "This video is deleted or does not allow embeds";
    +    }

         return { success => 1, code => $code };
    }

2011/10/16

YAPC::Asia Tokyo 2011で発表してきました #yapcasia

YAPC::Asia Tokyo 2011で発表してきました

ブログを書くまでが勉強会!

YAPC::Asia Tokyo 2011 公式サイト - http://yapcasia.org/2011/


御礼

まず、私の所属している株式会社アイダックと諸々の支援をしていただいたTマネージャにお礼申し上げます。
旅費と協賛スポンサーの申し込みありがとうございました!


初スピーカー

今回厚かましくもスピーカーとして参加させていただきました。
当日は緊張しましたが、やって良かったなと思っています。

トークに応募するきっかけを作ってくれたHokkaido.pmとそのメンバー、JPAと地方派遣支援で来ていただいたゲストの皆さん、高頻度で自費参加してくださるcharsbarさん、ありがとうございます!


少人数でのWebアプリ開発 CGIからPSGIまでの変遷

現在の部署の歴史が浅いことと私が入社当初、職業プログラマとしてのキャリアがなかったこともあり、
初期の状態は良いとは言えませんでした。
その環境を少しずつ改善し、近代的なプログラミング環境を整える変遷を紹介したものです。

スライドは以下になります。


その他雑感

  • 941さん、色々とお世話になりました。ありがとうございます!
  • 同じHokkaido.pmのあきやまさん(@akiym)のトークが裏番組だった
    YAPC::Asiaは大規模なので、そこまで気にしてられない状態だったと思いますが、これは残念でした。
  • 今年はお昼ご飯の時間が設けられててグッド
    去年は20分しか隙間がなかったので大変だった
  • 東京のPerl Mongerは実は優しい
  • 地方からきている人が思った以上にいた
  • Parumon面白いよ!拡張パック希望
    懇親会で遊んでくれた人、ありがとうございます。次のHokkaido.pmの開始前とかに遊びたい

2011/10/08

全文検索エンジンgroongaを囲む昼下がり@札幌に行ってきました

全文検索エンジンgroongaを囲む昼下がり@札幌


最初の自己紹介のまとめ


  • ここにきている人だけあって、groonga使ってる人が多い
  • Senna, tritonnもちらほら
  • 中の人が札幌に来たので勢いで開催



Groongaの中の人、森さんによる概要


ざっくり概要


  • 全文検索エンジンが出発点
  • データストア能力が強化されてきた
  • 特徴
    • 転置索引
    • 即時更新
    • カラムストア

なぜ転置索引か


  • searchのスループットを重視
  • 転置 > Suffix Array > Signature > 線形
  • indexingは遅い傾向がある

即時更新


  • CGM等ですぐ検索できないと使いづらい
  • groongaではここを頑張ってる
  • リアルタイムに強いということを今日は覚えてかえる

カラムストア


  • 普通のRDBではレコード毎に保存
  • filter, sort, group byは大体必須な機能なので、高速化したい



groongaの使い方とかとか


  • Cのライブラリがある
  • groongaコマンドで操作
  • HTTPもあり。レスポンスはJSON
  • gqtp - groonga query transfer protocol
    • HTTPよりも効率はいい
  • memcachedプロトコルも話せる

SennaとGroonga


  • Senna
    • アイルトン・セナが速いから付けた
    • 他のRDBと組み合わせて使う
  • Groonga
    • MySQL, PostgreSQLと使うこともできる

森さんがいろいろ


  • Cライブラリで直接扱うと速い
  • MySQL経由だとSQLのうんぬんがあるので、それほど早くないかも
  • ひとつのDBに対してMySQL, HTTP, Cライブラリからなど同時にアクセスできる

MySQL + Sennaの不満


  • MyISAM
    • メンテが大変
  • 5.0
  • 更新しながら、検索さくさくできない
    • MyISAMは書き込み時にreadもブロックしちゃうよね

MySQL + Groongaでは


  • Groongaでも更新せな!っていうのを頑張ってる
  • プラガブルストレージエンジンに対応
  • データストアがそもそもあり



休憩




Groongaの構造とデータの流れ


資料を見た方がいい

http://www.clear-code.com/blog/2011/10/5.html


ちょっとだけメモ


  • パトリシアトライ
    • トライ(Trie) <- retrieval
  • lexicon
      - 転置索引がゼロになっても、こっちは消さない
    • テーブル構造にしているのは今後拡張できるように
    • トークンのポジションも保存するかどうか選べる
    • 重みも記録できる



質問タイム


  • Groongaのこれからやっていきたいこと
    • 性能を良くする
      • インデックス構築はまだ早く出来る
    • versioned indexをいれたい
      • あまり使わないのはコンパクトにしたりとか
    • トランザクションは検討したい
  • スケールアウト
    • MySQL + Spider + Groonga が現状はいいかも
  • MySQL InnoDBの全文検索とGroongaどっちが速いの?(森さん)
    • 都合よくデータでてきた!
    • MySQL + Groonga (storage mode)の方がindexsingがやっぱり速い
  • 事例とか
    • 書いていいかわからないのでカット
  • 文章数はどのくらいまでいれたことがあるか
    • twitterのデータを入れたときが多かった
    • 1nodeで1000万レコード。まあ扱えている感じ
  • gqtpのバイナリプロトコルのドキュメントはあるのか
    • ないようです
    • source読んでね
  • データベースファイルをmvすると問題あるような?
    • rubyのライブラリからmvしたやつを使うと怪しい

2011/09/30

DOZENS(ダズンズ)にネームサーバを移行しました

先日引越したのですが、その際にちょっと手違いで1週間弱固定回線が使えない期間ができてしまった。
普段はemobileで大丈夫だけど、自宅サーバで管理していたネームサーバが利用できないのは不便です。

Amazon Route 53を使おうか悩んでいたところ、DOZENSのtwitterアカウント @dozens_jp に営業をかけられたので使ってみることにしました。


DOZENSとは

DNSのホスティングサービスです。コントロールパネルからぽちぽち設定するだけでレコードの設定ができます。

Google Apps用の簡単設定機能もある(らしい)


料金

  • 12レコード 無料
  • 24レコード 100円/月
  • 36レコード + TTL変更 1000円/月
  • 192レコード + TTL変更 5000円/月
  • 612レコード + TTL変更 10000円/月

* 2011/09/30時点での料金です


ドメイン数やクエリ数での課金ではなく、レコード数によるのがちょっと面白い。

100円/月までのプランに収まるなら、VPS等で自分でネームサーバを運用するより安くつくかも

NSレコードは自動で設定されるため、レコード数のカウントには入らない模様。


レコードの設定方法

シンプルで使いやすい管理画面があるので、Web上からさくさく設定して終わりです。


  1. レジストラの管理画面でDOZENSで管理したいドメインのネームサーバを以下に設定する
    • ns1.dzndsn.com
    • ns2.dzndsn.com
    • ns3.dzndsn.com
    • ns4.dzndsn.com
  2. DOZENSの管理画面から[Add a domain]をクリックして管理したいドメインを設定
  3. 追加されたドメインの[EDIT]を押す
  4. [Add a record]を押してポップアップに下記の項目を入力して、[create]をクリック
    • レコード名
    • レコードタイプ
      • A, AAAA, CNAME, MX, TXTの選択式
    • TTL
      • 安いプランでは2時間固定
    • Priority
      • MX以外は大体いらないはず
    • Content
      • IPアドレス等を記載

まとめ

Route 53だとドメイン毎とクエリ数で課金されるので最低でも1ドル/月かかるので、レコード数が少ないならDOZENSが良い感じです。

後、使用者がいるのかわかりませんが、 REST API が用意されています


最後に

下記のリンクから登録していただくと、私とあなたの両方に3レコード追加されます。使ってみたいと思った方はよろしくお願いします。

http://dozens.jp/i/ulWIxq

2011/09/23

Jenkins勉強会 札幌のメモ

Jenkins勉強会 札幌


CI概論 @cactusman


CI


  • 頻繁にビルドしろ
  • ナイトリビルド、デイリビルドの延長線上
  • 自動ビルド、自動テストを推奨

広まらない理由


  • SCM必須
  • テスト必須
  • CIサーバ
  • チームメイトの理解

あるといいもの


  • BTS
  • インスペクション
  • XFD (eXtreme Feedback Device)

CIは最近流行ってきている


  • EC2, VPS
  • XPの浸透
  • Jenkinsなどのツール類の発展
  • ノウハウ

問題やパターン


スローテスト問題


  • テスト実行に時間がかかりすぎる
    • テスト実行数の増加
    • 非効率なテスト
    • 依存関係
    • システムテスト的なもの
  • ビルド自体も同様

解消方法


  • テスト自体のパフォーマンスチューニング
    • TDD的なテストは捨てる
    • DBなどはモック化、インメモリ化
  • 実行単位のスケジュール
  • 実行単位の細分化して、並列性をあげる
  • スケールアップ
  • スケールアウト

狼少年問題


  • テストが通らない、インスペクションでの警告が常用化
  • OSSでも割とある

解消方法


  • 状態を把握する
    • テストの失敗や警告の増減に注目
  • テストの最小化
    • やる必要があるかどうか常に考える
  • 問題のあったところ、デグレードしたところを重点的に
  • インスペクションで問題のない箇所はレビュー後にignoreにする

Pre-Tested Commit


  • コミットする前にテストを実行するパターン
  • CIサーバに差分を送って、テスト等を行う
  • オールグリーンならコミット、レッドならコミットできない
  • TeamCity(IntelliJ IDEA)で機能あり
  • Jenkinsでも要望がある
  • DVCSで代用することも可能?



Jenkins概論 @cactusman


Jenkins


  • OSSのCIツール
  • 簡単、手軽、親切
  • プラグインで機能拡張
  • 各OSごとにインストーラがある
  • CIのデファクト?

Jenkisの役割


  • チェックアウト
  • ビルドスケジュールの管理
    • 1時間間隔とか
  • 通知
  • レポーティング
  • ログの保存

よくある誤解


  • JenkinsがJavaだから、Javaしか扱えないんでしょ
  • Java知らないです

誤解への回答


  • Javaの知識はなくてもいい
  • ビルドにsh, batを使える

高度な機能


  • トリガー
  • plugin
    • wikiを見てから聞け
  • Jobのチェーン
    • A -> B -> C, B -> D
  • CLI
  • クラスタリング
    • マスタ/スレーブ形式
  • RESTのAPI

QA


  • サーバの移行は?
    • .jenkinsを固めて、転送する



Trac + Jenkinsで始めるCIのある開発 @shuji_w6e


自己紹会


  • @shuji_w6e
  • Blog やさしいデスマーチ

Jenkinsと私


  • 2009年末に個人的に導入
  • 2010年夏ごろ、社内開発環境で導入

現代のソフトウェア開発の特性


  • 複雑性
  • 短納期
  • 超大規模または超小規模
  • 開発手法の変化

現代ソフトウェア開発の3本柱


  • バージョン管理
  • テスティング
  • 自動化
  • (チケット管理システム)

導入の手順


  • バージョン管理
  • チケット
  • テスト
  • 自動化

バージョン管理とテスティング


  • 効果的な自動化に必要な要素
    • 継続的なテストとフィードバック
    • テスト != 品質保証
  • その他の自動化
    • ビルド、パッケージング、デプロイ
    • 静的解析、ドキュメンテーション

導入事例


開発の流れ


  • tracで作業を洗いだしてチケット化
  • Eclipse等でコードを書く
    • 可能なかぎりユニットテストを行う
    • TDDとペアプロ
  • Subversionにコミット
    • CIでテストが通るか確認する
  • Tracのチケットをクローズ

開発の流れ 自動化部分


  • Subversionにコミット
  • JenkinsCIにコミットを通知
  • Mavenによるビルド・テストの実行
    • 成功時はパッケージを作成
    • ビルド/テスト失敗時は、IRC/メールに通知

変化したこと


  • Tracの活用により作業漏れが減った
    • ファイルサーバのExcelは見ない
  • コミット間隔が細かくなった
  • ユニットテストを実施している部分の品質があがった
  • JenkinsCIが常に監視しているので、問題が起きた場合にすぐ解るようになった
  • 開発に集中できるようになった

導入まで


  • 「よく解らない」に対する抵抗
  • メリットが説明・理解させにくい
    • やってみれば解る
    • 効果が出るまで時間がかかる
  • ある程度は強引に導入

導入に失敗しないため


  • 導入失敗時には「次」はない
  • 同調できる仲間を作っておく
  • ノウハウを勉強会や書籍で勉強する
    • 実際に手を動かして使ってみる
  • 導入経験のある人を巻き込む

導入事例まとめ


  • 開発スタイルは「文化」
    • 内部の「文化」は変えられる
  • メンバーの半分の意識が変われば自然に変われる
    • 1/6から2/6は大変
    • 3/6から4/6はそうでもない

構成事例


TracからJenkinsへ


  • HudsonTracPlus プラグイン
    • タイムラインにビルド結果を通知
    • Jenkinsのビルドページへのリンクとかwikiフォーマット

JenkinsからTracへ


  • Trac プラグイン
    • コミットログからTracへのリンク

Windowsサーバの場合


  • Trac Lightning

Google Code


  • バージョン管理、チケットはGoogle
  • VPSでJenkins

Maven


  • Javaはつかないので省略

デモ中の質問等


  • Jenkins自体で256MBくらい
  • ジョブは別プロセスで動かすのでオーバーヘッドがあるかも
  • CPUはそこまでいらないかも



Jenkins Plugin開発、ハック(@cactusman)


core, pluginのハックの前に


  • shell script等で対応できないか
  • 今ある機能でなんとかなるか
  • coreよりもpluginでいいのではないか
    • 拡張ポイントを見てから

Jekinsのビルドとハック


  • 必要なもの


    • jdk6
    • Maven
  • ビルド


    • git clone hogehoge
    • cd jenkins
    • mvn install -Dskip-test-harness的ななんか
    • 詳しくはwiki
  • IDEでの開発


    • NetBeans(6.7+)
    • Eclipse
    • IDEA
  • URLマッピングはStapler

  • ViewはApache Jellyによって記述
    • GroovyやJRubyが使用可能

Pluginの作り方


  • 公式Pluginを参考にする
  • チュートリアルがwikiにある https://wiki.jenkins-ci.org/display/JENKINS/Plugin+tutorial

オススメぽいPlugin


  • Task Scanner Plugin
    • XXX、TODOとか攫ってくれる
  • Change Log History Plugin
    • Jenkinsの設定を変更した時に変更履歴を見れる

2011/08/20

札幌MySQL#1に行ってきました

札幌MySQL勉強会

箇条書きですがメモを載せておきます

MySQL MHA

目的

  • SPOFをなくしたい
  • マスターのSPOFをなくすのは難しい

障害対応の課題

  • レプリケーションは非同期
  • どのスレーブが最新か判断する必要がある
  • スレーブ間のズレを修正する
  • これを全自動でやる

アーキテクチャ

  • Pure Perl
  • MySQL 5.0以降
    • binary logのformat versionの都合で5.0から
  • MySQL-MasterHA-Manager
    • Config::Tiny, Lod::Dispatch, Parallel::PreforkManager, DBD::mysql
  • MySQL-MasterHA-Node
    • DBD::mysql

内部的な動作

  • SQLスレッドが実行を終えるまで待つ
  • 会心スレーブのリレーログのヘッダを解析して各スレーブに適用する

特徴

  • マスターの稼働監視からフェイルオーバーまでを自動でできる
  • フェイルオーバーが秒単位で可能
  • 非同期レプリケーションでもスレーブ間の同期が取れる
  • 任意のスレーブを新マスターにできる
  • いくつかの箇所から外部スクリプトを呼ぶ昨日がある
    • 電源OFFやIPアドレスのフェイルオーバーなどに使う
  • インストール/アンインストールにあたり現在のmysqldプロセスやレプリケーションを止める必要がない
  • MHA自体は追加の負荷をかけない
  • ストレージエンジンに依存しない
  • バイナリログのフォーマットに依存しない
    • statementでもrawでも大丈夫

拡張ポイント

ケーススタディ

  • DeNAのサービスに対してMHAを導入
  • MySQLは滅多にクラッシュしないけど、OS、H/W障害によって落ちる
  • OSダウンによるフェイルオーバーには、ダウン検知に10秒、フェイルオーバーに4秒
    • マスターの生死判定
    • フェイルオーバー可否判定
    • フェイルオーバー処理

デモ

  • 3台構成 Master1 Slave2
    • master centos6-1
    • slave centos6-2
    • slave centos6-3
  • 設定ファイルでスレーブの中からマスターになる候補を決められる
  • masterha実行時にどのサーバーがmasterか自動検知

既存のソリューションに対する優位性

  • マスター障害でも整合性をたもってレプリケーションを再開できる
  • スタンバイサーバがいらない
  • フェイルオーバー時間が高速
    • アクティブ/スタンバイ構成のDRBDでは1分単位
  • MySQL Cluster/Galeraに対する優位性
  • MySQL-MMMは怖い

その他の特徴

  • 任意のスレーブを新マスターにできる
  • フェイルバックをするのが面倒
  • 準同期レプリケーションを併用することで、データ消失をほぼ防げる

サービスの増強と縮退

  • ゲームタイトルの人気を正確に見積もることは困難
  • 想定外の人気が出た場合
    • スレーブを追加
    • 水平分割でマスターを増やしていく
    • マスタのH/Wを増強する

マスターを別マシンに移行したい

  • マスターを別マシンに移す
  • メンテナンス時間を設ければ簡単
  • ダウンタイムなしでマスターに切り替えるのが理想
  • 0.5から3秒くらいでできれば多くの場合は許容範囲

書き込みブロックをどうするか

  • アプリケーションのユーザをdropする
    • 新規だけエラーになる
    • 接続済みはエラーにならない
    • 接続済みのセッションが終了しない限り、更新がおわらに
  • set global read_only = 1
  • OSCのときは3秒で切替だったけど、最適化して1秒くらいになった

MHAでの高速マスター切替

  • masterha_master_switchで手動切替もできる
  • 切替前と切替後の構成を表示して、確認がある
  • webアプリなら一回エラーになっても、もう一回クリックして動けば許される雰囲気
    • 今のところ苦情はきてない

質問

  • slaveの昇格の設定
  • MasterHA自体が落ちた場合は
    • pacemakerとかでMasterHA自体をHAする

MySQL開発者向けチューニング

ディスクI/O性能を常に意識する

  • HDDは遅い

一部のクエリだけが問題を起こす

  • 1%の法則
  • 代表的な悪い例
    • 大量のレコードをスキャン
    • 個々の実行効率は悪くないが大量に実行される
      • スロークエリにはでない
      • 何かツールを後で紹介
    • 長時間ロックを保持

tcpdumpとmk-query-digest

  • スロークエリログが有効になっていなくても実行頻度の高いクエリを取れる

クエリの実行計画に注意する

  • EXPLAINの読み方を習得する
  • MySQLのオプティマイザが判断を謝ることがあるので気をつける
    • とくにsortが絡む場合
      • FORCE INDEXを使う
    • コストベースなので、テスト環境と本番環境で実行計画が異なることがある

計算量とランダムアクセスを意識する

  • SELECT xx FROM t WHERE xxx LIMIT 100000, 20

スレーブの性質を理解して使う

  • スレーブはシングルスレッド
    • CPU効率の悪い更新処理はスレーブ遅延を招く
    • innodb pluginの圧縮とか
    • 長時間かかる処理はその実行時間分だけレプリ遅延になる
  • テンポラリテーブルとの相性がわるい

トランザクションを意識する

myslowtrancaptureで遅いトランザクションを特定する

  • githubにある
  • 実行に一定時間以上かかったトランザクションを探し出す
  • 誰がロックしているかも表示する

データサイズに常に気を配る

  • 必要以上に大きなデータ型を使うべきではない
    • datetimeよりtimestamp
    • varcharよりint
    • intよりもsmallint
  • 古いデータをメインテーブルから削除する
  • index

INDEX

  • ルート→ブランチ→リーフ→実データ

範囲検索を注意して使う

  • データを削除するとき
    • delete文で削除されるものをslaveで空読みして、メモリに載せてから実際にdeleteしてレプリ遅延を防ぐ

Covering Index(インデックスだけを使う検索)

  • SELECT key1 FROM th1 WHERE key1 IN (1,2,3)
  • explainでusing indexになっていればOK

マルチカラムインデックスと範囲検索

  • カーディナリティに注意

Covering Indexに帰着させる

  • SELECT a,b FROM tbl WHERE secondary_key < 100;
  • a, bをindexにしておく
    • indexを安易に増やすのがいいのか考える

INSERT性能とメモリ量の関係

  • リーフブロックにもうエントリーが入らなくなると、追加のブロックが確保される
  • ランダムINSERTは虫食い状態になりやすい
    • indexサイズが増える
    • ディスクI/Oが増える
  • インメモリでINSERTを完結させる
    • 10000rows/s超える
  • 高速ストレージでも実は状況はさほど改善しない
    • insert buffer? ランダムinsertでも毎回readしない
    • FusionIOでも5000rows/s程度
  • 時系列データはレンジパーティション
    • indexはパーティション毎に作られる

データブロックがどのように読まれるか

  • 全体の3%しかアクセスしなくても、ブロック単位で読み込むので思ったよりも多くメモリが必要
  • 剰余ベースは効率がわるい
  • 範囲ベースの振り分けは効率がいい

Blogテーブルの扱いを考えてみる

  • タイトル、本文
  • 大抵の人は一覧しかみない!
  • 長いBLOB/TEXTは全クエリを遅延させる
    • 本文が別ブロックにはいってしまうことがあるから
  • 本文を別テーブルに切り出す 1:1関連

ロック競合

  • ロックは必要になるまで確保せず、不要になったらすぐにCOMMIT/ROLLBACKで解放する
  • ロックを確保した後に、何秒もかかる可能性のある処理をしない

Version Numberデザイン

  • 楽観ロック
  • テーブルにVERSION列を追加

SELECT *を多用しない

  • 必要な列だけ返すこと

省スペース化

  • JSONデータ等でkeyを小さくするとか

データ型の指針

  • FLOATを使わない
  • NOT NULLを使う
  • TEXT/BLOBを使わない 
  • UNSINGEDを使う
  • INT(1)は1バイトじゃない

EXPLAINを見る

  • type=indexかつ「Extra: Using index」ではないクエリは使用不可
  • 巨大LIMITはダメ
  • covering indexにする

LEFT OUTER JOINしない

ストレージエンジンを混在させない

  • キューサーバとしてQ4Mを独立して用意するのはあり

重複したインデックスを持たない

  • INDEX(c1), INDEX(c1,c2)

LOAD DATAを使わない

  • レプリケーション遅延を招く
  • LOAD中にマスターがクラッシュすると、フェイルオーバーできないことがある

複数マスター間でのデッドロックに注意

  • 異なるmysqldでのデッドロックは自動検出されない
  • アプリ側でIDのソート順にロックをかけることで回避できる

履歴系データはレンジパーティション