わーくあうと!

日々の作業でためになったことをアウトプットすることで自分の成長につながればなと。

5分で出来るMySQLのお手軽チューニング

こちらのエントリーで書いているのですが、開発用のVPS鯖がメモリ使い過ぎで重くなっていて、mysqlに問題がありそうだったのでサクっと調整しました。
その手順を残しておきます。

MySQLのチューニング項目について説明

MySQLのメモリに関する設定項目はたくさんあります。
それぞれの項目に関しての詳しい情報は下記が参考になります。
http://trackback.blogsys.jp/livedoor/klab_gijutsu2/50860867


ただ、これらを全て把握するのは大変だと思うので、簡単に分類すると以下の2種類があります。

  • グローバルバッファ
  • スレッドバッファ

で、MySQLが使うメモリ量は下記になるわけです。

グローバルバッファ + ( スレッドバッファ * コネクション数 )


それらを踏まえた上で具体的なチューニングに入ります。

MySQLで使っているメモリ量を調べる

こんな便利なものを作ってくれた方がいました。
http://blog.mogmet.com/calculate-mysql-total-memory-sql/trackback/
【MySQL】総メモリー使用量を算出するSQL作ってみた




SQL部分を引用させてもらうと

select
@@GLOBAL.KEY_BUFFER_SIZE + @@GLOBAL.INNODB_BUFFER_POOL_SIZE + @@GLOBAL.INNODB_LOG_BUFFER_SIZE + @@GLOBAL.INNODB_ADDITIONAL_MEM_POOL_SIZE + @@GLOBAL.NET_BUFFER_LENGTH as GLOBAL_BUFFER_SIZE,
@@GLOBAL.SORT_BUFFER_SIZE + @@GLOBAL.MYISAM_SORT_BUFFER_SIZE + @@GLOBAL.READ_BUFFER_SIZE + @@GLOBAL.JOIN_BUFFER_SIZE + @@GLOBAL.READ_RND_BUFFER_SIZE as THREAD_BUFFER_SIZE,
@@GLOBAL.KEY_BUFFER_SIZE + @@GLOBAL.INNODB_BUFFER_POOL_SIZE + @@GLOBAL.INNODB_LOG_BUFFER_SIZE + @@GLOBAL.INNODB_ADDITIONAL_MEM_POOL_SIZE + @@GLOBAL.NET_BUFFER_LENGTH
 + (@@GLOBAL.SORT_BUFFER_SIZE + @@GLOBAL.MYISAM_SORT_BUFFER_SIZE + @@GLOBAL.READ_BUFFER_SIZE + @@GLOBAL.JOIN_BUFFER_SIZE + @@GLOBAL.READ_RND_BUFFER_SIZE) * @@GLOBAL.MAX_CONNECTIONS AS TOTAL_MEMORY_SIZE,
(@@GLOBAL.KEY_BUFFER_SIZE + @@GLOBAL.INNODB_BUFFER_POOL_SIZE + @@GLOBAL.INNODB_LOG_BUFFER_SIZE + @@GLOBAL.INNODB_ADDITIONAL_MEM_POOL_SIZE + @@GLOBAL.NET_BUFFER_LENGTH
 + (@@GLOBAL.SORT_BUFFER_SIZE + @@GLOBAL.MYISAM_SORT_BUFFER_SIZE + @@GLOBAL.READ_BUFFER_SIZE + @@GLOBAL.JOIN_BUFFER_SIZE + @@GLOBAL.READ_RND_BUFFER_SIZE) * @@GLOBAL.MAX_CONNECTIONS)/1024 AS TOTAL_MEMORY_SIZE_kb,
(@@GLOBAL.KEY_BUFFER_SIZE + @@GLOBAL.INNODB_BUFFER_POOL_SIZE + @@GLOBAL.INNODB_LOG_BUFFER_SIZE + @@GLOBAL.INNODB_ADDITIONAL_MEM_POOL_SIZE + @@GLOBAL.NET_BUFFER_LENGTH
 + (@@GLOBAL.SORT_BUFFER_SIZE + @@GLOBAL.MYISAM_SORT_BUFFER_SIZE + @@GLOBAL.READ_BUFFER_SIZE + @@GLOBAL.JOIN_BUFFER_SIZE + @@GLOBAL.READ_RND_BUFFER_SIZE) * @@GLOBAL.MAX_CONNECTIONS)/1024/1024 AS TOTAL_MEMORY_SIZE_mb,
(@@GLOBAL.KEY_BUFFER_SIZE + @@GLOBAL.INNODB_BUFFER_POOL_SIZE + @@GLOBAL.INNODB_LOG_BUFFER_SIZE + @@GLOBAL.INNODB_ADDITIONAL_MEM_POOL_SIZE + @@GLOBAL.NET_BUFFER_LENGTH
 + (@@GLOBAL.SORT_BUFFER_SIZE + @@GLOBAL.MYISAM_SORT_BUFFER_SIZE + @@GLOBAL.READ_BUFFER_SIZE + @@GLOBAL.JOIN_BUFFER_SIZE + @@GLOBAL.READ_RND_BUFFER_SIZE) * @@GLOBAL.MAX_CONNECTIONS)/1024/1024/1024 AS TOTAL_MEMORY_SIZE_gb
\G

となっており、これを実行すると以下のようになります。

 *************************** 1. row ***************************
  GLOBAL_BUFFER_SIZE: 159399936
  THREAD_BUFFER_SIZE: 9306112
   TOTAL_MEMORY_SIZE: 1564622848
TOTAL_MEMORY_SIZE_kb: 1527952.0000
TOTAL_MEMORY_SIZE_mb: 1492.14062500
TOTAL_MEMORY_SIZE_gb: 1.457168579102
1 row in set (0.38 sec)

この場合、一見GLOBAL_BUFFER_SIZEが大きいように見えますが、問題なのはスレッドバッファです。
何故ならスレッドバッファが使うメモリサイズは 【スレッドバッファ * コネクション数】となるためです。


ちなみにコネクション数を確認するにはmysqlのコンソールで下記を実行します。

mysql> select @@GLOBAL.MAX_CONNECTIONS;
 +--------------------------+
 | @@GLOBAL.MAX_CONNECTIONS |
 +--------------------------+
 |                      151 |
 +--------------------------+
1 row in set (0.00 sec)

151...
9306112 * 151 = 1405222912 byte = 1340.125MB
で、スレッドバッファに1340.125MBも使ってます。

MySQLの設定を修正

何が問題なのかわかったので実際にMySQLの設定を修正していきます。
『/etc/my.cnf』に下記の設定を書きます。

[mysqld]
max_connections = 31

今回はスレッド数が多すぎたので max_connections を 151ー>31 と設定しました。
31という値については各環境で適当に設定してください。


グローバルバッファも設定したい場合は

[mysqld]
max_connections = 31
innodb_buffer_pool_size = 256MB

のように innodb_buffer_pool_size を設定します。
こちらの256MBという値についても各環境で適当に設定してください。


本当はグローバルバッファの設定には他の設定項目もありますが、大部分を占めるのが innodb_buffer_pool_size なので、シンプルに設定するためにこの項目だけにしています。


これだけでチューニングは完了です。
あとはmysqlをリスタートすれば設定が反映されます。

service mysql restart

設定後のメモリ使用量を確認

上のほうで紹介した長い長いSQLを実行して設定後のメモリ使用量を確認した結果、以下のようになりました。

 *************************** 1. row ***************************
  GLOBAL_BUFFER_SIZE: 293617664
  THREAD_BUFFER_SIZE: 9306112
   TOTAL_MEMORY_SIZE: 582107136
TOTAL_MEMORY_SIZE_kb: 568464.0000
TOTAL_MEMORY_SIZE_mb: 555.14062500
TOTAL_MEMORY_SIZE_gb: 0.542129516602
1 row in set (0.00 sec)

トータルメモリ使用量が0.5GBほどにまで下がってます。めでたい。

※メモリは使う量が少なければ少ないほどいいわけではなく、(swapしない範囲で)割り当てが多ければ多いほどパフォーマンスは向上します。今回はApache等も同時に動かしている鯖なので、mysqlのメモリ使用量を抑えたい目的で設定しています。そこは各自の環境に合わせて設定してください。

まとめ

  • max_connections
  • innodb_buffer_pool_size

を調整すればそこそこいい感じになる!


もっと調整していきたい!という方はここから他の細かい設定項目を調整していけばいいんじゃないでしょうか。

近状 20140118

最近ブログ書いてないからなんか書く。
とりあえず頭の整理がてら最近抱えてる仕事をつらつら書こうかなと。


大きなものをあげると以下の3つ。

  • 合コン斡旋サービス作る
  • 居酒屋ホームページ作る
  • GoogleAnalyticsのログをいい感じに使う


これらについて詳しく書いていくと

合コン斡旋サービス作る

詳しいサービス内容はリリースしたらブログに書くとして、先月中頃に「一緒になんかサービス立ち上げようぜ!」って誘いを頂いたのでとりあえずWeb側のシステム作ってる。


Webシステムは8割方完成(プログラム・デザイン共に)
レスポンシブデザインで構築してるからスマホ用ページを作る手間がなくていい感じ。
Ajaxも容赦なく使って、操作してて楽しいしいい感じ。


あとはサービスの説明とか求人とかの文言どうしようかってところ。
そのへんは打ち合わせしつつ詰めていきたい。


あー、あとドメインも取ってないし本番鯖も用意してない。とりあえずAWS使う予定。


あと実際に運用するようになったら誰がどんな事すんのとか、結構勢いで進めてきたけどこのサービスほんとに大丈夫なの?とか、、スピード感持って進めていきたい所だけど、ここからが意外と長いんだろうなぁ。


それと合コン斡旋について思考実験繰り返しているうちにもっと良さそうなビジネスモデル浮かんできてそっちにときめいたりもしちゃってる。
軸がブレてあっち行ったりこっち行ったりで前に進まないような事にはならないよう注意しつつ、そのへん含めて次回の打ち合わせで提案してみよう。


問題はまだまだあるし、これから大きなトラブルに直面する事もあるだろうけど何かサービス運用してみたいと思ってたから、これはやってて結構楽しい。
どうにかしよう。

居酒屋ホームページ作る

請負でホームページ制作。
請負の仕事とかあまりノリ気ではなかったけれど、昔からの知り合いの頼みだったので引き受けた。


これに関してはお金稼ぎたいというよりも無事に終わってくれればそれでいいかなと思う。
作業としても目新しいモノも無くてそんな楽しくなさそうだし、自分の時間をあまり割きたくないのでcrowdworksにでも投げてみようかとも考えてる。

追記 - 居酒屋ホームページは結局自分でサクッと作ってS3に静的コンテンツとして上げて公開した。制作費ももらったけど写真撮影用にデジタル一眼を買ったので大した利益にはなってない。
まあ、長く使えるものだし(震え声)


GoogleAnalyticsのログをいい感じに使う

Google先生APIを使ってページ毎のアクセス数を取って、それをゴニョゴニョするやつ。
まぁ、うん。
やったこと無いことだし自分の経験値になるはず。がんばろう。


他にもやってみたい企画がモリモリあるので今後少しづつ実現していきたいなぁ。
(今確認したら72個あった...絶対全部やれないでしょ...)

ローカルストレージを使った問い合わせフォームを作った

ちょっと必要になったのでローカルストレージを使ってメアド入力が不要な問い合わせ機能を作った。


今までのような

  • ユーザーがメールアドレスを入力して問い合わせし、お店の人がそのメアド宛に返答する。

という流れではなく

  • ブラウザ上で問い合せを送ってお店の人がそこに返答する。

といった、LINEのような掲示板のようなチャットのような流れになっています。


あくまでデモ版なので2重投稿対策などは行っておりません。
(このまま運用で使うのはオススメしません)


肝心のユーザーID周りは、
まだ生成されていなければ一意のIDを生成 → ローカルストレージにぶっこむ
となっています。

抽選してばばーん!と結果がでるルーレット作った

会社のLT大会で必要になりそうだったので作った。

ルーレット
http://nickworks.net/products/roulette/


一応Githubにもコード上げておいた。
nickworks-net/roulette · GitHub


もし必要な人がいたらぜひ使ってください。

よし寝よう。

nginxでバーチャルホスト設定

前回nginxとFastCGIいれたけどバーチャルホストの設定もしたかったので設定した。

前回の記事:CentOS6.4にnginxとFastCGI入れる - わーくあうと!

設定ファイルを作る

vhost.confというファイルを作って

vi /etc/nginx/conf.d/vhosts.conf 

中身はこんな感じにした

# バーチャルホスト用の設定.
# 基本的には /var/www/nginx/vhosts/ の下にホスト名のディレクトリ作るだけでOK.
server {
    listen       8080;
    server_name  ~^(.*)?;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    # ↓ホントはホスト毎にアクセスログ分けたかったが $host が効かないようなので諦める。
    # mainのログフォーマットに $http_host を付けたからgrepすれば見れるし。
    #access_log /var/www/nginx/vhosts/$host/logs/access_log main;

    root /var/www/nginx/vhosts/$host/html;

    location / {
        index  index.html index.htm index.php;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        #root   /var/www/nginx/html;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME  /var/www/nginx/vhosts/$host$fastcgi_script_name;
        include        fastcgi_params;
    }
}

これであとは /var/www/nginx/vhosts/ の下にホスト名のディレクトリ作っていけばバーチャルホスト増やせる。
例)/var/www/nginx/vhost/hoge.domain.com

うん、シンプル。

CentOS6.4にnginxとFastCGI入れる

借りてるVPS鯖にnginxとFastCGIいれたのでメモっておく

FastCGI入れる

インストール
# yum install --enablerepo=epel spawn-fcgi

epelリポジトリから入れます。
epelリポジトリいれてない場合は頑張って入れてください

php-fastcgiの起動スクリプトを作成
# vi /etc/rc.d/init.d/php-fastcgi

#!/bin/sh
#
# spawn-fcgi   Start and stop FastCGI processes
#
# chkconfig:   - 80 20
# description: Spawn FastCGI scripts to be used by web servers
 
# Source function library.
. /etc/rc.d/init.d/functions
 
RETVAL=0
SPAWNFCGI="/usr/bin/spawn-fcgi"
PHPFCGI="/usr/bin/php-cgi"
FCGIPORT="9000"
FCGIADDR="127.0.0.1"
PHP_FCGI_CHILDREN=5
PHP_FCGI_MAX_REQUESTS=1000
ALLOWED_ENV="PATH USER"
USER=nginx
GROUP=nginx
PIDFILE=/var/run/phpfcgi.pid
 
ALLOWED_ENV="$ALLOWED_ENV PHP_FCGI_CHILDREN PHP_FCGI_MAX_REQUESTS FCGI_WEB_SERVER_ADDRS"
 
case "$1" in
  start)
        PHPFCGI_START=$"Starting ${NAME} service: "
        echo -n $PHPFCGI_START
 
        # clean environment
        E=
        for i in $ALLOWED_ENV; do E="$E $i=${!i}"; done
        daemon $SPAWNFCGI -a ${FCGIADDR} -p ${FCGIPORT} -u ${USER} -g ${GROUP} -P ${PIDFILE} -C ${PHP_FCGI_CHILDREN} -f ${PHPFCGI}
        RETVAL=$?
        ;;
  stop)
        echo -n "Stopping php-fcgi: "
        killproc -p $PIDFILE phpfcgi
        echo
        RETVAL=$?
        ;;
  *)
        echo "Usage: $0 {start|stop}"
        exit 1
esac
exit $RETVAL

これをコピペする。

php-fastcgiをサービスに登録
# chmod 755 /etc/rc.d/init.d/php-fastcgi
# /sbin/chkconfig --add php-fastcgi
# /sbin/chkconfig php-fastcgi on
# /sbin/service php-fastcgi start

これでFastCGIはOK。

nginx入れる

nginx公式リポジトリを追加
# rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

Centos6系以外の場合は公式ページからリポジトリのURLを探してきてください。

ドキュメントルートにするディレクトリ作成
# mkdir /var/www/nginx
# mkdir /var/www/nginx/html
設定ファイル編集

/etc/nginx/conf.d/default.conf
デフォルトで

server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

↑こうなってる内容を

server {
    listen       8080;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;

    root /var/www/nginx/html;

    location / {
        #root   /var/www/nginx/html;
        index  index.html index.htm index.php;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        #root   /var/www/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        #root           html;
        fastcgi_pass   127.0.0.1:9000;
        #fastcgi_index  index.php;
        #fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

↑このように編集した。

確認用のファイル作る
# touch /var/www/nginx/html/index.php
# echo "<?php phpinfo(); ?>" > /var/www/nginx/html/index.php
起動&確認
# /etc/init.d/nginx start
# wget localhost:8080

これでindex.htmlをダウンロード出来ればOK。


あとはバーチャルホストの設定もしたいな

CentOS6.4のPHPを5.4にアップグレードしようとしてやめた話

借りてるVPS鯖のPHPのバージョンが5.3(普通にyumで入れた)で、せっかくなので5.4にでもしようかなと下記の記事を参考に入れてた

CentOS6.4にサードパーティレポジトリを追加して、PHP5.4とかいれてた - otukutunの日記


要はremiやらepelやらのサードパーティリポジトリ追加してそこから入れるんだけど、よくよく考えたらあとからphpのモジュール追加するときも

yum install --enablerepo=remi php-なんちゃら

とかしないとだめなんだよなぁと思ってやっぱ5.3に戻した。
後々絶対忘れる自信があったので。。

デフォルトで使うリポジトリサードパーティ製のものにすれば解決っちゃ解決だけどそれも微妙だし。

というお話でした。

pm2のインストールでこける件

node.jsをデーモン化するにはforeverよりpm2のほうが高機能でいいよという噂を耳にしたのでpm2を入れようとしたら失敗した。

$npm install -g pm2
〜省略〜
> usage@0.3.9 install /root/.nvm/v0.10.22/lib/node_modules/pm2/node_modules/usage
> node-gyp rebuild

gyp ERR! build error 
gyp ERR! stack Error: not found: make
gyp ERR! stack     at F (/root/.nvm/v0.10.22/lib/node_modules/npm/node_modules/which/which.js:43:28)
gyp ERR! stack     at E (/root/.nvm/v0.10.22/lib/node_modules/npm/node_modules/which/which.js:46:29)
gyp ERR! stack     at /root/.nvm/v0.10.22/lib/node_modules/npm/node_modules/which/which.js:57:16
gyp ERR! stack     at Object.oncomplete (fs.js:107:15)
gyp ERR! System Linux 2.6.32-358.2.1.el6.x86_64
gyp ERR! command "node" "/root/.nvm/v0.10.22/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /root/.nvm/v0.10.22/lib/node_modules/pm2/node_modules/usage
gyp ERR! node -v v0.10.22
gyp ERR! node-gyp -v v0.11.0
gyp ERR! not ok 
npm ERR! usage@0.3.9 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the usage@0.3.9 install script.
npm ERR! This is most likely a problem with the usage package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node-gyp rebuild
npm ERR! You can get their info via:
npm ERR!     npm owner ls usage
npm ERR! There is likely additional logging output above.

npm ERR! System Linux 2.6.32-358.2.1.el6.x86_64
npm ERR! command "/root/.nvm/v0.10.22/bin/node" "/root/.nvm/v0.10.22/bin/npm" "install" "-g" "pm2"
npm ERR! cwd /var/www/chat-server
npm ERR! node -v v0.10.22
npm ERR! npm -v 1.3.14
npm ERR! code ELIFECYCLE
npm http 200 https://registry.npmjs.org/keypress
npm http GET https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz
npm http 200 https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /var/www/chat-server/npm-debug.log
npm ERR! not ok code 0

こんなエラー。
makeが無いとか言ってるけど、まぁとりあえず Development Tools 入れてみるかーと思い以下をインストール

$ yum groupinstall "Development tools"

それで

$ npm install -g pm2

したらインストール成功した。

CentOSにnode.jsをnvmでインストール

自分の開発VPS鯖にnvmでnode.js入れたけど忘れそうなのでメモっておく。

nvmのインストール

$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh

nodeのインストール

$ nvm install v0.10.22

確認

$ which node
/root/.nvm/v0.10.22/bin/node
$ which npm
/root/.nvm/v0.10.22/bin/npm

自動読み込み設定

~/.bash_profile に追記。.bash_profileが無ければ作る。
これが無いと一回サーバーからログアウトするとnodeコマンドが見つからなくなる。

source ~/.nvm/nvm.sh
nvm use "v0.10.22"


途中足りないものがあれば適宣 yum install 〜 とかしてもらえれば。

nodeのインストール方法をググると古い情報が多くてソースコードからインストールするような方法とか紹介されてるけど今ならnvm使ったほうが楽だしバージョンアップも簡単にできそうで便利そう。

LINEの通知音が鳴らない件

数日前からLINEの通知音がならなくて困ってた。
通知音はないけどホーム画面には通知がきてるっていう。。


iPhone & LINE の設定確認したりPC側のLINEの設定を確認したり iPhone再起動してみたりしたけど直らなくて、iPhoneの復元でもしてみようかと思ってたら原因がやっとわかった。


iPhoneがおやすみモードになってただけだった。


設定からおやすみモード解除したら直った。