株式会社インフィニットループ PHPとスマホアプリ開発を行う札幌のシステム会社

技術ブログ

  1. トップ>
  2. 技術ブログ>
  3. MySQLの記事一覧

2015年12月25日 (金)

著者 : 

2015年 弊社ブログで話題になった記事まとめ

こんにちは、年の瀬に風邪を引いてしまった muramoto です。

2015年も残すところあと少しになりました。インフィニットループの1年を、今年話題になったブログ記事(アクセスが多かったり、はてなブックマークがたくさんついた記事)で振り返ってみました。また記事の執筆者にコメントをもらいましたので、あわせてお読みください!

職場のメンバーで今話題の「炉ばた大将」に参戦してみました

20141219_IMG_2327

(続きを読む…)

2015年11月19日 (木)

著者 : 

MySQL 5.6 の ALTER TABLE と Percona Toolkit の pt-online-schema-change を比較してみた

こんにちわ!みなさん MySQL 使ってますか?インフラの nobuh です。

ゲームなどのサーバーでは、時々サービスを停止していわゆるメンテナンスという作業が行われています。 ゲームをプレイしているユーザーの皆様にはご不便をお掛けして大変申し訳ないところですが、サービスを停止してまで我々アプリ開発やサーバー運用の会社の人たちが何をやっているかといいますと、その理由の大きなものの一つがデーターベースの構造の変更です。

21233325363_bb22dbed87_z

アプリケーションを修正したり、新機能を追加するときはデータベースの構造の変更を行います。MySQL では ALTER TABLE というコマンドを使ってテーブルの構造を変更します。 MySQL が ALTER TABLE の間に内部で何をやっているかといいますと、テーブルを長期間ロックし占有して一気に変更したり、あるいはロックせずに内部的にコピーしながら変更を組み込方法、などの手法を使って構造の変更を行っています。 こうしたデータベースの変更でも多いのが 「インデックスやカラムの追加」 です。

そこで今回は MySQL 5.6 の ALTER TABLE でロックせずにカラムを追加出来る ようになった機能と、複数のクエリ実行でオンラインの変更を行う Percona Toolkit の pt-online-schema-change と、それぞれの動作を比較してみました。

(続きを読む…)

2015年09月11日 (金)

著者 : 

クラウド時代の新常識はこれだ!「MySQL クラウド向け InnoDB チューニング」

こんにちは。インフラエンジニアの nobuh です。

株式会社インサイトテクノロジー様主催の db tech showcase sapporo 2015  が 9月10日、11日の2日間にわたって開催されました 。

今回、弊社も発表する機会を頂きましたので、インフラエンジニアとして日々 MySQL と格闘して培ったノウハウについてお話させて頂きました。その発表で使ったスライドがこちらです。

(続きを読む…)

2015年06月15日 (月)

著者 : 

OSC2015北海道で「これだけみれば大丈夫ーCactiによるMySQLパフォーマンス監視のツボ」という発表をしてきました

こんにちは nobuh です。 昨年の 第四回札幌MySQL勉強会 以降、多忙のためなかなか勉強会を開けていない札幌MySQL勉強会ですが、各メンバーはこつこつとスキルアップを続けていました。

そして今回、日本MySQLユーザー会 様からお話を頂き、OSC2015北海道 にて札幌MySQL勉強会から発表させて頂きました。こちらがそのスライドです。

(続きを読む…)

2013年08月20日 (火)

著者 : 

これだけ見れば大丈夫!ーMySQLパフォーマンス監視のツボ(システム編)

こんにちは nob です。
前編 これだけ見れば大丈夫!ーMySQLパフォーマンス監視のツボ(クエリ編) の記事から1年半が経過してしまいました。ちょっと長いお休みでしたが、その間に蓄えた MySQL パフォーマンス監視の実戦経験を(システム編)としてお届けいたします!

今回の(システム編)で紹介するツボは 4 つです。(クエリ編)のツボに加えて、この4つに注目して頂ければ MySQL のパフォーマンス監視もバッチリです。

  • (ツボ1)Load Average < (1 + (cpu数-1)/3) 
  • (ツボ2)Checkpoint Age が水平線になったら要注意
  • (ツボ3)MyISAM は無いよね監視
  • (ツボ4)万能選手スローログ

なお前編と同様この記事では監視ツールとして CactiPercona MySQL Monitoring Template for Cacti (前編で紹介した better-cacti-templates の後継プロジェクト)を前提にしていますが、Munin やコマンドラインの mysql など、他のツールでも見るべき点は同じですので応用してください。

(ツボ1)Load Average < (1 + (cpu数-1)/3) 

右側の式は後ほど説明するとして、Load Average 監視って当たり前?ですよね。でも実際には Load Average にもいろいろなケースがあります。

  • Disk I/O が増えた場合に Linux カーネルのフラッシュのプロセスが CPU を使ったり、あるいはコンテキストスイッチでLA増加
  • アクセスしているテーブルのデータが殆どバッファープールに乗っている場合には相対的に I/O 負荷が低くなるため、クエリが増えた場合にその分ロック機構で使われるスピンロックなどの排他制御やソート処理で LA 増加
  • インデックスが使われず広範囲に読み込みスキャンするようなクエリを誤ってリリースしたような場合にも LA増加
  • クラウドのインスタンスがホスト側の障害で不良だった場合にも、アクセス数は変わって無いのに LA増加

などがあります。このように CPU, Disk I/O, クエリ負荷、クラウドの不良インスタンスまで、あらゆる状況を総合的に把握出来るのがやっぱり CPU のビジーで、その代表的なグラフが  Load Average です。

load_average_example

このグラフはあるシステムの2日間の Load Average のグラフです。左のグラフの 13:00 付近から Load Average が急上昇しました。これは新しく使われ初めたある機能により、実行回数も多いクエリのジョインやソートの行数が急に増加したため Load Average が上昇したものです。探索行数が多いと I/O が増加するイメージがありますが、実際には OS のキャッシュや MySQL のバッファプールに乗るため I/O は増えずに CPU だけ負荷が増える事があります。この場合も Load Average の上昇で兆候を発見し、まだ問題ない程度のうちに原因クエリを特定し改善することで、夜のピーク時間帯には通常ピーク値(青線)に戻す事が出来ました。

このように監視項目として有効な Load Average ですが、さてしきい値はいくつにしたらよいでしょうか? Linux カーネルのマルチコアでは

  • キャッシュのヒット率やメモリ一貫性維持のオーバーヘッドを考慮し、プロセッサのコアはある程度偏らせて使う
  • プロセス起動時は空いているコアを選択するが、MySQL はプロセス起動はあまり発生しないのでこの分散の恩恵は受けない
  • かなり負荷が高くなるとプロセスを動かしたままコアを移動するマイグレーションがおきるが、滅多に発生しない

という CPU を偏って使う特徴があるので、ググってよく出てくる 「Load Average < CPU数」は適正値にはなりません。とは言えしきい値も必要です。そこで、完全な経験則だけで理論の裏付けはありませんが、MySQL のインスタンスの Load Average のしきい値を出しました。

  • MySQL では Load Average  <  (1 + (cpu数 -1) /3)

です!よくある8コアのマシンですと、LA < 3.3 までが適正値です。ハイ言っちゃいました!

(ツボ2)Checkpoint Age が水平線になったら要注意

Redis や MySQL Cluster など多くのデータ永続化インメモリDBはデータはメモリ上で、HDDのシーケンシャル書き込みは速いのでログはディスク上で、という構造になっています。InnoDB もデータをメモリ上だけに持てるサイズがあり、このサイズまではインメモリDBと同じようにログだけディスクに書いた状態で動作します。このメモリ上に持ったままでよいサイズというのが  innodb_log_file_size です。そしてまだディスクにフラッシュされていないデータのサイズが Checkpoint Age になります。漢のコンピュータ道 でも128M程度までというアドバイスがありますが、一方で、ログファイルサイズを大きくすることで、高い性能を引き出そうというチューニング手法もあります。

Checkpoing Age が成長すると緩やかにディスクへのランダム書き込み(チェックポイント)が始まります。チェックポイントと、シーケンシャルなログ書き込みの量のバランスが取れていれば、 Checkpoint Age もバランスが取れ、上がったり下がったりしつつアクセス量と同じようなグラフの形になります。

checkpoing_age_low

使用ディスクが RAID などでシーケンシャル書き込みがランダム書き込みに比べてかなり速い場合は、ログの書き込みの方が多くなりCheckpoing Age が成長します。そして一定の割合(バージョンによる。90%等)を超えると今度は強いチェックポイントが始まります。この強いランダム書き込みとログのシーケンシャル書き込みでバランスが採れていれば、Checkpoing Age は高止まりした波グラフ(下のグラフの青い部分)になります。全力でディスクを使っている状態です。

checkpoint_age_middle

ここからさらにログ書き込み量が上回りCheckpoint Age が上限に達すると、全てのトランザクションを停止してチェックポイントを行うようになります。そして Checkpoint Age が下がりトランザクションが再開されますが、更新が多いのでまたすぐ上限に達します。この動作を繰り返し続けるので Checkpoint Age は下のグラフの様に上限値でほぼ水平線になります。このグラフの形でも全トランザクション停止時間が1秒未満など微視的であれば、上の例と同じく全力運転状態と言えます。

checkpoint_age_high

一方、高速動作を狙って innodb_log_file_size を〜GBというようにバッファプール並みに大きくしてると、全トランザクションをブロックして書き込む量も多くなりますので、停止時間が数分間にも達し大きな問題となる事があります。こうしたトランザクション停止時間は Checkpoint Age のグラフでは読み取ることが難しいですから、Checkpoing Age が水平線になったらトランザクション全停止が発生していないかアプリのログなどで確認するようにしましょう。

ドリコムさんで体験された「ちゅどる」もこの現象になります。(ソーシャルゲーム スケールアウトの歴史 p81 参照)またPercona の Adaptive Checkpointing  はこの「ちゅどる」にならないようにチェックポイントの強さを自動的に調節する機構です。

(ツボ3)MyISAM は無いよね監視

現在は MySQL = InnoDB といっても過言ではないと思います。MyISAM のテーブルは作成していません。それなのに突然 MyISAM Indexes のグラフが急上昇することがあります。大抵はシステムも高負荷になっています。

myisam_indexes

これはジョインやソートのために MySQL 内部に作成されるテンポラリテーブルが、メモリ上には乗り切らず MyISAM テーブルとして作成され使用されている為発生します。MyISAM Indexes のグラフを監視して、発見したら

  • max_heap_table_size  と tmp_table_size をさらに大きな値に変更してメモリから溢れない様にする
  • クエリを見直してテンポラリテーブルの使用量を下げる

などの対応が必要です。

(ツボ4)万能選手スローログ

MySQL パフォーマンスチューニングや監視で、もっとも有効なのがスローログです。理由は単純明快で、あらゆるDBの問題は「遅い」という症状につながるからです。そんな万能選手のスローログですが、完全無欠ではなく注意すべき点が2点あります。

  1. 完了したクエリだけが記録される。デッドロックなどロールバックされたクエリは完了していないため記録されません。記録されているスローログは被害を受け遅延したクエリで、原因となった加害者のクエリが最終的にはロールバックされ記録されていないというケースもあります。あくまでも完了したクエリなんだという前提で読みましょう。
  2. クエリが原因だと先入観を持たない。あるクエリの実行時間が想定以上に長い場合、ついそのクエリの書き方に注意が向きがちですが、先入観を持たずに調査しましょう。例をあげますと、 SELECT MASTER_POS_WAIT(logname, position, 2) という、本来2秒で応答すべきスレーブのマスター追いつき確認関数 MASTER_POS_WAIT の実行に何十秒もかかっていて、 実はインスタンス自体がハングアップしていたのが原因でクエリも MySQL も原因では無かった、というケースなどがあります。

最後に

MySQL パフォーマンス監視のツボ(システム編)としてサーバー運用管理での経験を共有させて頂きました。是非ご活用ください!

2013年06月04日 (火)

著者 : 

MySQL5.6の新機能「InnoDB Memcached Plugin」の分離レベルを検証し、ソーシャルゲーム案件に使えそうか検証してみました

matsuiです。

先日6/1に行われた第四回札幌MySQL勉強会の中で、MySQL5.6の新機能「InnoDB Memcached Plugin」の分離レベルについて調べてみましたので、記事にしてみたいと思います。
 
 

InnoDB Memcached Pluginとは

「InnoDB Memcached Plugin」とは、MySQL5.6から使えるようになった、SQLを使わずMemcachedプロトコルを使ってInnoDBのデータにアクセスするためのものです。

主なメリットはその高速性にあり、Oracleでのベンチマークテストでは、SQL処理の9倍といった性能が出ているとのことです。
このあたりの速度やベンチマークについては、幾つものブログなどで検証されているようですので、今回は対象としませんでした。
 
 

分離レベルとは

それでは何を調査の対象にしたのかというと、それは分離レベルです。
分離レベルとは、トランザクションが複数個平行して行われた場合に、どのような一貫性、正確性で実行するかを4段階で定義したもので、REPEATABLE READとか、READ COMMITTEDとかのアレです。
 
 

検証内容

以下がテストケースです。3つの検証を行いました。

設定されている分離レベルはMySQLデフォルトの「REPEATABLE READ」です。
my.cnfなどの内容も、ほぼ初期値です。
 
 

  1. MySQLでBEGINした後にMemcacheからデータを更新した際、MySQL側からはどのように見えるか
  2. MySQLでBEGIN後にFOR UPDATEで行ロック、Memcache側から参照に制限がかかるか
  3. MySQLでBEGIN後にFOR UPDATEで行ロック、Memcache側からそのレコードを更新しようとしたらどうなるか

【検証用プログラム】

// 定義
$memcache_server = '192.168.3.254';
$db = 'test';
$user = $password = 'root';

// MySQLサーバにmencacheプロトコルでアクセス
$memcache = new Memcache;
$memcache->addServer($memcache_server, 11211);
format($memcache);

// MySQLサーバに普通にアクセス
$dsn = sprintf('mysql:dbname=%s;host=%s', $db, $memcache_server);
$dbh = new PDO($dsn, $user, $password);
$result = $dbh->query('SELECT @@global.tx_isolation;');
foreach ($result as $row) {
	v($row[0]);
}
$dbh->query('BEGIN;');
v('--- 更新前 ---');
readByMemcache($memcache);
readBySQL($dbh);

// テストケースを実行(コメントアウトを手動で切り替えて実行)
testCase1($memcache, $dbh);
//testCase2($memcache, $dbh);
//testCase3($memcache, $dbh);

// 値を読み出し
v('--- 更新後 ---');
readByMemcache($memcache);
readBySQL($dbh);

// ロールバック
$result = $dbh->query('ROLLBACK;');
v('--- MySQLロールバック後 ---');
readByMemcache($memcache);
readBySQL($dbh);



// テストケース1
// MySQLでBEGIN後にMemcache側で更新
function testCase1($memcache, $dbh) {
	v('# テストケース1を実行');
	$memcache->set('mkey1', 'zzz');
	v('# Memcache::set');
}

// テストケース2
// MySQLでBEGIN後に行ロック、その上でMemcache側で参照
function testCase2($memcache, $dbh) {
	v('# テストケース2を実行');
	$result_lock = $dbh->query("SELECT * FROM demo_test WHERE c1 = 'mkey2' FOR UPDATE");
	foreach ($result_lock as $row) {
		v('# 行ロックを実行: ' . $row['c1']);
	}
	$result = $dbh->exec("UPDATE demo_test SET c2 = 'yyy' WHERE c1 = 'mkey2'");
	v('# UPDATE: 影響を与えた行数: ' . $result);
}

// テストケース3
// MySQLでBEGIN後に行ロック、その上でMemcache側で更新
function testCase3($memcache, $dbh) {
	v('# テストケース3を実行');
	$result_lock = $dbh->query("SELECT * FROM demo_test WHERE c1 = 'mkey3' FOR UPDATE");
	foreach ($result_lock as $row) {
		v('# 行ロックを実行: ' . $row['c1']);
	}
	v('# Memcache::set');
	$memcache->set('mkey3', 'xxx');
}

// 初期化
function format($memcache) {
	$memcache->set('mkey1', 'abc');
	$memcache->set('mkey2', 'def');
	$memcache->set('mkey3', 'ghi');
}

// SQLでデータを読み込み
function readBySQL($dbh) {
	$result = $dbh->query("SELECT * FROM demo_test WHERE c1 IN ('mkey1', 'mkey2', 'mkey3')");
	foreach ($result as $row) {
		v('mysql: ' . $row['c2']);
	}
}

// Memcacheでデータを読み込み
function readByMemcache($memcache) {
	v('memcache: ' . $memcache->get('mkey1'));
	v('memcache: ' . $memcache->get('mkey2'));
	v('memcache: ' . $memcache->get('mkey3'));
}

// デバッグ用
function v($arg) {
	var_dump($arg);
}

 

結果

【テストケース1の実行結果】

$ php memcache_access.php
string(15) "REPEATABLE-READ"
string(17) "--- 更新前 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"
string(30) "# テストケース1を実行"
string(15) "# Memcache::set"
string(17) "--- 更新後 ---"
string(13) "memcache: zzz"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"
string(34) "--- MySQLロールバック後 ---"
string(13) "memcache: zzz"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: zzz"
string(10) "mysql: def"
string(10) "mysql: ghi"

 
 
【テストケース2の実行結果】

$ php memcache_access.php
string(15) "REPEATABLE-READ"
string(17) "--- 更新前 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"
string(30) "# テストケース2を実行"
string(30) "# 行ロックを実行: mkey2"
string(37) "# UPDATE: 影響を与えた行数: 1"
string(17) "--- 更新後 ---"
string(13) "memcache: abc"
string(13) "memcache: yyy"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: yyy"
string(10) "mysql: ghi"
string(34) "--- MySQLロールバック後 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"

 
 
【テストケース3の実行結果】

$ php memcache_access.php
string(15) "REPEATABLE-READ"
string(17) "--- 更新前 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"
string(30) "# テストケース3を実行"
string(30) "# 行ロックを実行: mkey3"
string(15) "# Memcache::set"
PHP Notice:  MemcachePool::set(): Server 192.168.3.254 (tcp 11211, udp 0) failed with:
 Network timeout (0) in memcache_access.php on line 71
string(17) "--- 更新後 ---"
string(10) "memcache: "
string(10) "memcache: "
string(10) "memcache: "
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"
string(34) "--- MySQLロールバック後 ---"
string(10) "memcache: "
string(10) "memcache: "
string(10) "memcache: "
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"

 
 
【まとめ】

  1. データ更新があってもMySQL側からは一貫した読み取りが行えた
  2. 参照に制限はかからない。またコミット前のデータが見えた。ロールバックしても挙動は同じ
  3. タイムアウトとして処理された。

1は想定内の挙動です。

2が致命的ですね。
どうやら分離レベルはREAD UNCOMMITTEDに相当するようです。
確かに、「このあたり」に分離レベルはREAD UNCOMMITTEDに設定しなさい、みたいな事が書かれていました。
 
3の挙動は興味深いですね。不整合は許されない箇所なので、

MemcachePool::set(): Server 192.168.3.254 (tcp 11211, udp 0) failed with: Network timeout (0)

のように、タイムアウトとして処理されるようです。面白い。
 
 

結論

設定値を変えて再検証しました。追記欄をご覧下さい。

あわよくばソーシャルゲーム案件のマスターDBの負荷軽減と高速化を目論んでいましたが、何も考えずに使うには難しいようです。
トラブル無く使うには、格納されているデータの内容や処理の流れを意識しながら使わなくてはならないでしょう。

スレイブDBの参照には使えそうですが、その用途であれば今もKVSなどである程度まかなえているでしょうから、それほどありがたみのある使い方とは言えないでしょう。

キャッシュの生存期間の判定が微妙なデータのアクセスに利用したり、いっそMemcachedなどのKVSは捨て、参照はMySQLへの一本化を行うことで、システムをシンプルにするという形では使えそうです。
(そうすると今度は実行コストの比較が必要ですね)

 
 
※勉強会の時間内で確認しただけで、深い検証はしていませんので、ツッコミなどありましたら遠慮なくお願いします。
 
 
【追記】
https://twitter.com/matsuu/status/341766721398521856
innodb_api_trx_level」というパラメータがあるとのアドバイスをいただきましたので、変更して再検証してみたいと思います。
ありがとうございます。
 
 

再検証

my.cnfに「innodb_api_trx_level=2」のように加えて再検証してみました。

テストケース1と3の結果は変わらず。問題だった2番の結果を貼ります。

【テストケース2の再実行結果】

$ php memcache_access.php
string(15) "REPEATABLE-READ"
string(17) "--- 更新前 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"
string(30) "# テストケース2を実行"
string(30) "# 行ロックを実行: mkey2"
string(37) "# UPDATE: 影響を与えた行数: 1"
string(17) "--- 更新後 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: yyy"
string(10) "mysql: ghi"
string(34) "--- MySQLロールバック後 ---"
string(13) "memcache: abc"
string(13) "memcache: def"
string(13) "memcache: ghi"
string(10) "mysql: abc"
string(10) "mysql: def"
string(10) "mysql: ghi"

コミット前のデータが見えるようなことは無くなりました。素晴らしい。
 
 
【改めてまとめ】

デフォルトではREAD UNCOMITTEDだった挙動が変化しており、innodb_api_trx_levelの変更が利いているように見えます。
こちらのドキュメントページ」によると、値は0~3で設定できるため、4つの分離レベル全てで動作するようです。

なお、上記のケースのように行ロックしたデータをMemcacheで読み込んでも、特に参照抑止などはかからないようです。
これは通常のトランザクション中のSELECTも同じ挙動なので特に違和感はありませんが、真に最新の値を取得するようなシビアな用途の場合は、SQLに任せる必要があるということになります。
 
 

改めて結論

innodb_api_trx_levelをセットすることで、普通に案件に使えるレベルとなりそうです。
(アドバイスをくださった@matsuuさんありがとうございます)

他にも、innodb_api_disable_rowlockやinnodb_api_enable_mdlなど気になる設定値がありましたので、折りをみて研究してみたいと思います。

MySQLのInnoDBの分離レベルのデフォルトはREPEATABLE READ、InnoDB Memcached PluginはREAD UNCOMITTED。
ご利用の際には、ここにご注意ください。

2012年08月16日 (木)

著者 : 

【社内勉強会レポート】「Mobageを支える技術」を読む

今回の勉強会では技術評論者から出版されている「Mobageを支える技術」(DeNA著)を読みました。この勉強会は複数回に分けて行われる予定で、第一回目の今回はレプリケーション遅延のページを中心に読みました。

近年急成長し、横浜ベイスターズを買収するなど飛ぶ鳥を落とす勢いのDeNAですが、ソーシャルゲームの運用経験が豊富な同社が著した本ということで、その内容は私たちの期待に十分に応えるものでした。

本書を読み、レプリケーション遅延をいかに防ぐかがソーシャルゲーム運営上の重要事項と痛感させられました。中でも画面遷移を頻繁に行うヘビーユーザーはわずかなレプリケーション遅延にも気づくというくだりは驚きでした。こうしたヘビーユーザーでも不満なく遊べるような体制を構築することが、全体の顧客満足度の向上に欠かせないと感じました。

ほかにも、安全なMySQLのバージョンアップの手順や、レプリケーション遅延の防止策など、DeNAと同じくソーシャルゲームを運営する当社にとって参考になる部分が多く、実際の業務に応用できそうなものも多々ありました。

レプリケーション遅延防止策の一つとして、あえてスレーブにスペックの劣るサーバを入れることで、遅延しそうな状態を予測する手法などは非常にうまい方法だと皆感心していました。

ソーシャルゲームの運用を行う方やMySQLを用いて高負荷のサービスを運用している方はこの「Mobageを支える技術」を一読してみてはいかがでしょうか。

 

——————

 

当社ではMySQLに精通した方、高負荷のサービスを運用した経験のある方を募集しています。興味をお持ちの方は当社の求人ページをご覧ください。 → 求人ページ

2012年05月02日 (水)

著者 : 

【社内勉強会レポート】ビッグデータ時代のDB設計入門を読む会(全5回)

こんにちは。新人のlot49です。社内で毎週金曜日に恒例となっている勉強会に参加しましたのでレポートします。

社内勉強会の前回の記事からだいぶ日が経ちましたが、勉強会は休むことなく週一のペースでコツコツやっておりました。

タイトルにありますように今回の勉強会のテーマは週一の勉強会を5回費やして行われるほど、長くて多岐に渡る内容でした。それを今回まとめて紹介します。

今回の資料は『Webエンジニアのためのデータベース技術[実践]入門』(技術評論社)を使用しました。

執筆者はかつてDeNAに所属し、現在Facebookに在籍されており、そしてMySQLに大変精通している松信嘉範さんです。

データベースの現場に近いノウハウが満載です。進行は大きく分けて、データベースの選定基準、テーブル設計、高速化(&性能改善)テクニックでした。

本勉強会は、参加した社員が交代でキリのいいところまで音読し、質問をする者、それに答えられる者がホワイトボードの前に立ち説明を始めるという感じのスタイルで進みました。どんなに不慣れな質問をしてもよいという雰囲気があって、新人&本テーマに関する知識の浅い私にはなによりありがたかったです。

重要なポイントはユーザーからの膨大なアクセス数にどう対応するか。いかに信頼性を高めるか。データ変更の頻度の違いに注目したテーブル設計の指針。(ディスクアクセスを発生させずに)メモリ上で処理を完結させる工夫。レプリケーション遅延対策。サーバー間にまたがるサーバー同士によるデッドロックという古いようで比較的新しいトラブルなどなど。

一通り終えてみて、データベースの基本から飽くなき探究心でMySQLの裏側まで把握した応用まで含まれており、データベースの知識だけでなくプログラマとしての高い志まで感じ取ることができ、大変勉強になりました。

有意義な勉強会でした。みなさんおつかれさまです。

『Webエンジニアのためのデータベース技術[実践]入門』松信嘉範 著

今回は上の書籍を使用しましたが、ちょっと古い雑誌ですが、その中で同じ著者が執筆したよく似た内容のコーナー「特集3:ビッグデータ時代のDB設計入門」がありますので併せて紹介します。

2011年10月22日発売

技術評論社『WEB+DB PRESS Vol.65』

最後にお知らせです。インフィニットループではデータベースに詳しいエンジニアを募集しています。データベースに興味のある方は求人ページで詳細をご覧ください。 → インフィニット求人ページ

  • このブログについて

    このブログは、札幌市・仙台市の「株式会社インフィニットループ」が運営する技術ブログです。
    お仕事で使えるITネタを社員たちが発信します!

    最新の記事