2009年11月27日金曜日

MySQLで最初に見るべきチューニング設定項目

どうも、俺@仕事中です。
わが社ではMySQL、PostgreSQLを良く使っている(というかほとんど)のですが、よくアクセス過多によるサーバチューニングをやっています。
今回はMySQLサーバで負荷対策を行う際の「まず最初にココの設定だけは要Check It Now」というのをメモします。

# vim /etc/my.cnf
または
# mysqladmin variables
または
mysql> show variables;
で、現在の設定の確認ができます。

-- key_buffer_size
mysql> show variables like '%key_buffer%';
MyISAMエンジンテーブルのインデックスを保存するメモリバッファのサイズ。
Key_read/Key_read_requestsでキーバッファミス率を算出し、0.01以下になるように。

-- max_allowed_packet
mysql> show variables like '%max_allowed%';
通信時の1パケット最大サイズ。画像データなど大容量のデータをMySQLへ保存する際には大きくする。

-- table_cache
mysql> show variables like '%table_cache%';
一度開いたMySQLのデータファイルポインタを保存しておくためのキャッシュ。二度目以降のテーブルへのアクセスを高速にする。つまりはサーバのディスクI/Oを減らせる。
mysql> show global status like '%Open_tables%'
の値が大きい場合はテーブルキャッシュの値を増やした方が良い場合がある。
※バージョン5.1.xからはtable_open_sizeに変わってるかも!?

-- sort_buffer_size
mysql> show variables like '%sort_buffer%';
ソートに利用されるメモリサイズ。Order ByとかGroup Byとかで使われる。もしsort_buffer_sizeが1Mでmax_connectionsが1000だった場合、メモリは最低でも1GB必要という事ですよ。

-- read_buffer_size
mysql> show variables like '%read_buffer%';
テーブル読み込み時に利用されるメモリサイズ。INDEXを使わずフルスキャンされる場合に利用。そもそもINDEXを見直すべきでは?!

-- read_rnd_buffer_size
mysql> show variables like '%read_rnd_buffer%';
テーブルをランダムに読み込む場合に使われるメモリサイズ。使用可能メモリより大きなテーブルでGroup By/Order Byをする際は大きめにしておく。ソート後のレコード読み取り速度を上げるかも。要はディスクI/Oの軽減。

-- myisam_sort_buffer_size
mysql> show variables like '%myisam_sort_buffer%';
REPAIR TABLE / CREATE INDEX / ALTER INDEX 時に利用されるメモリサイズ。かなり頻度は低い。

-- thread_cache_size
mysql> show variables like '%thread_cache%';
MySQLコネクションスレッドをプールする数。スレッドを破棄&生成するコストを下げる。

-- tmp_table_size
mysql> show variables like '%tmp_table_size%';
サブクエリなどで一時的に実行結果をテンポラリテーブルに保存されたときのメモリサイズ。このサイズを超えた場合、MySQLはディスクへ一時テーブルへ保存しディスクI/Oが発生してしまう。このサイズを指定した場合はmax_heap_table_sizeも同じ値に設定する。

-- query_cache_size
mysql> show variables like '%query_cache%';
一度発行したクエリ実行結果をキャッシュしておき、二回目以降はクエリを発行することなくキャッシュから結果を返す。もちろん更新クエリなどが走った後はキャッシュはクリアされる。ちなみに
mysql> FLUSH QUERY CACHE;
でキャッシュを強制的にクリアできる。

-- skip-name-resolve
これは有名すぎますがDNS逆引きをしない。この設定をした場合、GRANT構文などでユーザを登録する際にもIP指定にする必要がある。

my.cnfの設定は基本的に上記のものを見直します。
もちろん細かい設定をする場合は、もっと詳細な設定を見直す必要があるのであくまで参考程度に。

あとは、スローログを取得させる。
slow_query_log=mysql-slow // スローログを取得
logn_query_time=1 // 1秒以上かかったクエリを取得


OPTIMIZE TABLE [table_name]を定期的にかける。
mysql> OPTIMIZE TABLE table_name;
更新や削除などが頻繁に行われているテーブルに対してやると効果絶大。デフラグを解消させる。postgreSQLで言うところのvacuumみたいなもの。


あとは、サーバのメモリを増やすだとかサーバそのもののスペックを上げるだとか、アプリケーション側でのチューニングは必ず必要です。
特にスローログに出ているクエリは見直す余地がかなりあると思うので、そちらのチューニングも大切に!


以上でぇぇす。

2009年11月16日月曜日

linuxのssコマンドで利用中ポート一覧

こんちわ、俺@仕事中です。

ふと、ターミナル(zsh)で
[user]$ sl
と打ってしまって
correct:sl -> ss [n y a e]?
と表示されて知ったのですがLinuxには「ss」というコマンドがあるみたいです。
[user]$ whereis ss
ss: /usr/sbin/ss /usr/include/ss /usr/share/ss
見つからない人は、yumで一発インストールできます。

で、このコマンドなのですが、そのサーバが開いているポート一覧を表示してくれます。ちょうど
[user]$ netstat -tpln
したのと同じような感じです。

[user]$ ss -an
State    Recv-Q Send-Q    Local Address:Port    Peer Address:Port
LISTEN    0   0            *:3333           *:*
LISTEN    0   0            *:6666           *:*
LISTEN    0   0            *:21            *:*
LISTEN    0   0            *:22            *:*
LISTEN    0   0        127.0.0.1:5431           *:*
LISTEN    0   0            *:5432           *:*
ESTAB     0   0      192.168.60.215:22     192.168,.60.29:1515
ESTAB     0   0      192.168.60.215:22     192.168,.60.29:1764
と、こんな感じです。
オプションもnetstatと似てます。
[user]$ ss -h
Usage: ss [ OPTIONS ]
    ss [ OPTIONS] [ FILTER]
-n, --numeric don't resolve service names サービス名に変換せずにポート表示
-a, --all dispaly all sockets 全てのソケットを表示
-t, --tcp display only TCP sockets TCPプロトコルのソケットを表示
-u, --udp display only UDP sockets UDPプロトコルのソケットを表示
-4, --ipv4 display only IP version 4 sockets ipv4のIPでのみ表示
-6, --ipv6 display only IP version 6 sockets ipv6のIPでのみ表示
-r, --resolve resolve host names ホスト名を名前解決する
主なオプションはこんなもんでしょうか。

以上でーーす。

2009年11月11日水曜日

jqueryでポップアップウインドウ

どうも、俺@仕事中です。

mixiのPC版で絵文字入力するときに「絵文字」アイコンをクリックするとポップアップが出て絵文字入力ってありますよね。
今日はあんなポップアップの作り方の勉強です。

まず表示部分。
<html>
<title>
<script type="text/javascript" scr="js/jquery-1.3.2.js">
<!-- ドラッグできるように -->
<script type="text/javascript" scr="js/ui.core.js">
<!-- ドラッグできるように -->
<script type="text/javascript" scr="js/ui.draggable.js">
</title>
<body>
ポップアップ
<hr>

<!-- ポップアップ -->
<div id="popup">
ココにポップアップ表示
</div>
<!-- ポップアップ以外をクリックすれば、ポップアップが消えるように -->
<div id="delete"></div>

</body>
</html>
htmlはこんな感じにしておきます。
<div id="popup"></div>の中にポップアップさせたい内容を書きます。

次はCSS。
div#popup {
position: absolute; /* 移動できるように */
z-index: 99; /* z-indexは高く */
}
div#delete {
position: absolute; /* absoluteで! */
z-index: 0; /* div#popupより低く! */
display: none; /* 初期は非表示 */
}
CSSはこんな感じ。

ではjavascript部分(jQueryを使います)
$(function() {
// パレットをclickでbind()しておく
$("div#popup").bind("click", $(this), popup);

// パレット以外の部分をクリックすると消えるように
$("div#delete").bind("click", function() {
$("div#popup").hide(); // パレットを非表示
$(this).hide(); // 自身も非表示
});
});

function popup(e) {
// パレットを表示
$("div#popup").css({"top":e.pageY-100,"left":e.pageX+50}).show().draggable();

// パレット以外の部分をクリックすると消す部分(mask)の処理
var height = $(document).height();
var width = $(document).width();
$("div#delete").css({"width":width,"height":height,"top":0,"left":0});
$("div#delete").show();
}
こんな感じです。


簡単にサンプルを書きましたが、後はお好みで変えてやればOKです。
ちなみに↑のサンプルソースは動作確認していませんので、もし間違いがあれば連絡くだされ;;


以上でえぇぇぇす。

2009年11月10日火曜日

php5.3のクロージャー(無名関数)を使ってみる

どうも、俺@猛仕事中です。

新規案件にphp5.3.0を入れてみた。
せっかくなので5.3からの新機能「Clouser(クロージャー)」を使ってみる。

やりたい事は、絵文字データを内部コードに変換してDBへ保存し、それを表示する際に絵文字画像に変換して出力したいという事。
絵文字画像というのは、<img src="xxx">に変換するって事ね。
※絵文字内部コードは[[MG:001]]~[[MG:999]]のフォーマット
<?php
1 // プログラムは適当に書き換えています。
2 function convertToImg($text) {
3 // 変換テーブルを配列で取得
4 $emoji_map = file("emoji_map.txt");
5
6 $converted = preg_replace_callback("/\[\[MG:([0-9]{3})\]\]/",
7 function ($match) use ($emoji_map) {
8 if (isset($emoji_map[$match[1]])) {
9 return "<img src='./img/emoji/".$emoji_map[$match1]].".gif'>";
10 }
11 return $match[0];
12 },
13 $text
14 );
15
16 return $converted;
17 }
てな具合です。

preg_replace_callback()関数の7行目~10行目までで無名関数を使っています。
$text内で /\[\[MG:([0-9]{3})\]\]/ にマッチした最初の([0-9]{3})を、配列$emoji_mapのキーに指定しています。

使う事ないだろうと思っていた、preg_replace_callback()関数とクロージャーを使う事になるとは。。


以上、自分でいろいろやってみてねー。