久々の更新。



とある案件で、PostgreSQLのスキーマ情報を

送ってくれれば良いのに頑固なSEが著作権うんちゃらと

騒いでいるので立会いで作業してみる。



で、やる事は簡単。



PostgreSQLのCreateTableの情報を

スクリプトで吐いて、USBのメモリスティックに

収めるだけの作業です。



【作業環境】

OS:CentOS4

DB:PostgreSQL8.2


※ルート権限でログインしてる事が前提。



① su posygres


  PostgreSQLのユーザにチェンジ



② usr/local/pgsql/bin/pg_dump testdb > test.sql


  pg_dumpコマンドで出力対象DBインスタンスを指定し

  カレントディレクトリにtest.sqlという名前の

  テキストファイルに標準出力。

  ※pg_dumpコマンドの格納先は環境によって違うので

   そこら辺は合わせてください。


③ mount -t vfat /dev/sba1 /mnt/usb


  で、usbをマウントしてやる。

  CD-ROMやフロッピーと同様。

  usbディレクトリが無い場合は作る。



④ cp /usr/local/pgsql/bin/test.sql /mnt/usb


  ②で作成したテキストファイルをusbメモリスティックにコピー。



⑤ umount /dev/sda1


  USBメモリスティックを抜いてアンマウント



以上










mod_rewriteほんの一例。



■PCページで、モバイルからのアクセスはモバイルのページを表示

RewriteEngine On

# NTT DoCoMo
RewriteCond %{HTTP_USER_AGENT} ^DoCoMo [NC]
RewriteRule ^.*
http://hogehoge.ne.jp/i.html [R,L]

# Vodafone Type C
RewriteCond %{HTTP_USER_AGENT} ^J-PHONE/2 [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^J-PHONE/3 [NC]
RewriteRule ^.*
http://hogehoge.ne.jp/v_typec.html [R,L]

# Vodafone
RewriteCond %{HTTP_USER_AGENT} ^J-PHONE [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Vodafone [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^Softbank [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^MOT- [NC]
RewriteRule ^.*
http://hogehoge.ne.jp/v.html [R,L]

# au
RewriteCond %{HTTP_USER_AGENT} ^UP\.Browser [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^KDDI [NC]
RewriteRule ^.*
http://hogehoge.ne.jp/ez.html [R,L]



UAを判定してキャリア毎のページを表示するさんぷる。




前回まででoracleプロセス数増加に伴う
パラメタのチューニングを記しました。


忘れてはいけないのがOSカーネルパラメタの
確認も行う必要があります。

セマフォ < oracleプロセス数 の場合・・

セマフォ > oracleプロセス数 に変更する必要があります。


1.現在の設定を確認
 # sysdef | grep SEM

100 semaphore identifiers (SEMMNI)
1014 semaphores in system (SEMMNS) ← ここ
30 undo structures in system (SEMMNU)
1004 max semaphores per id (SEMMSL) ← ここ
10 max operations per semop call (SEMOPM)
10 max undo entries per process (SEMUME)
32767 semaphore maximum value (SEMVMX)

2.現在の設定をバックアップ
# cp -p /etc/system /etc/system.YYYYMMDD

3.設定ファイル修正
 # vi /etc/system

  (変更前)
   set semsys:seminfo_semmsl=1004
   set semsys:seminfo_semmns=1014
  (変更後)
   set semsys:seminfo_semmsl=1504
   set semsys:seminfo_semmns=1514

4.設定変更確認
 # diff /etc/system /etc/system.YYYYMMDD

5.サーバ再起動

6.リブート後の設定確認
  # sysdef | grep SEM

100 semaphore identifiers (SEMMNI)
1514 semaphores in system (SEMMNS) ←確認
30 undo structures in system (SEMMNU)
1504 max semaphores per id (SEMMSL) ←確認
10 max operations per semop call (SEMOPM)
10 max undo entries per process (SEMUME)
32767 semaphore maximum value (SEMVMX)




サーバ監視をしてみます



といっても、

定期的にシェルをキックして

サーバの状態を特定のメールアドレスに送る、

という簡易な内容です。



#!/bin/sh
# ---------------------------------------------------------
# sarコマンドメール送信シェル
#
# ※起動タイミングはcron側に依存
#
# ---------------------------------------------------------

# 初期設定(メール送信宛先、件名、コマンド)
address="mugen@hoge.jp "
subject="sarコマンドの結果"


cmd="sar 1 1"

# 件名の文字コードをJISに変換


subject=`echo $subject | nkf -j`

# メール送信(コマンド結果はSJISに変換)
mail -s $subject $address << HONBUN
`$cmd | nkf -s`
HONBUN

# 終了
exit


sarコマンドの結果を

メールの本文に差し込むサンプルです。


後は、cronからお好みで起動。




Oralceメモリチューニング第2弾です。


SGA + PGA + (同時ユーザアクセス数 × 1.5MB)

の公式で5.6GBの範囲(8GBの70%)においてメモリを調整。

で、前にOracleのメモリチューニングに
お決まりはない、と書いたように日々の運用の中で
最適なメモリ領域の確保を行う必要があります。



現状の設定は以下の通り

------------------------------------------------------
 ・SGA
  sga_max_size → 3.5GB
  db_cashe_size → 3GB
  shared_pool_size → 200MB
  log_buffer → 1.9MB

 ・PGA
  pga_aggregate_target → 2GB

 ・processes(同時アクセス数)
  1,000processes想定
  1processあたり1.5MBのメモリ領域をアサイン
-------------------------------------------------------

 Oracleの統計情報を調査。
 (Oracleインスタンスを起動してから現稼動までの統計。)

 ① V$LICENSEから最大接続数の確認を行う。
   SESSIONS_CURRENT(現在接続中のユーザ) → 579
   SESSIONS_HIGHWATER(同時接続数最大) → 990

   processesが1,000に設定しているので
   現状かなり危ない数値です(※1)。

 そこでprocessesが1,500でも大丈夫なように
 SGA、PGAの利用可能はメモリサイズの調整行う。

 ②V$SYSSTATからデータベース・バッファキャッシュヒット率を
  調べて見ると99.6%。
  充分な数値である事が分かる。

  db_cashe_sizeが3GBとかなり多めに取っているので
  このサイズを減らします。

 ③V$PGASTATからPGAの最大メモリ使用量を見てみると733MB。
  PGAのメモリ使用量は現状2GBなので、
  こちらのサイズも減らします(※2)。

 ※1. 同時接続数が1,000を超えた場合はOracleがエラーを返すので
    アプリ側からは接続できなくなる。これはかなり致命的。

 ※2. アクセス過多でPGAの最大サイズを超えた場合は、
    Oralceインストールディレクトリにディスク空き領域に
    仮想メモリを作成しに行く。
    当然ディスクI/Oが発生するのでパフォーマンスは低下する。
    空きディスクが無くなるとOracleが応答しなくなる。


 以上を踏まえた上でメモリチューニングは・・

------------------------------------------------------------
・SGA
  sga_max_size → 2.5GB
  db_cashe_size → 2.0GB
  shared_pool_size → 200MB
  log_buffer → 1.9MB

 ・PGA
  pga_aggregate_target → 0.9GB

 ・processes(同時アクセス数)
  1,500processes想定
  1processあたり1.5MBのメモリ領域をアサイン(約2.2GB)

------------------------------------------------------------


この設定はあくまで机上での計算になります。


後日、検証環境で負荷測定を行いますが、

パフォーマンスが低下した場合、

アプリケーション側から発行されている

クエリのチューニングに移ります。






運用中のサーバが重いなあ、
と感じる事があると思います。


その際に最初に何を確認するか
明確になってない開発者も多いと思います。


以下はLinuxで何がボトルネックになってるか
1時切り分けの手段をまとめてみました。


1. CPU使用率
2. メモリ使用量
3. ディスクI/O
4. TCPコネクション数


この4点いずれかが異常値を取った場合は
システム全体が重くなったりします。



■「top」,「w」,「free」コマンドで
  CPU、メモリ使用率を調べる


まずtopコマンドを

----------------------------------------------------------------------------
---------------
# top
151 processes: 150 sleeping, 1 running, 0 zombie, 0 stopped
CPU0 states: 0.4% user, 0.5% system, 0.0% nice, 98.1% idle
Mem: 513596K av, 442136K used, 71460K free, 0K shrd, 77992K
buff
Swap: 1044184K av, 14120K used, 1030064K free 208420K
cached
----------------------------------------------------------------------------
---------------


で、最初に確認するのがidle。
値が98%以上(2%未満)なのでCPUは正常。


次にwコマンドを

----------------------------------------------------------------------------
---------------
# w
12:08pm up 171 days, 1:20, 1 user, load average: 1.22, 1.02, 1.97
----------------------------------------------------------------------------
---------------

load averageは処理待ちの平均プロセス数。
3以上の場合はかなり重たい状態となります。


次にメモリ使用量。


上述したtopコマンドの結果を見ると
一見開き領域がないように見えます。


Linuxでは空きメモリがあると
それをすべてCacheにまわすらしい。
それがtopに出てくる数字。


Cacheに回された分を差し引く必要があるので
freeコマンドを実行します。


----------------------------------------------------------------------------
-----
# free
total used free shared buffers cached
Mem: 513596 443556 70040 0 78340 209196
-/+ buffers/cache: 156020 357576
Swap: 1044184 14120 1030064
----------------------------------------------------------------------------
-----

この場合は実際使用している
メモリが156MBで余裕がある状態です。


次にディスクI/O。
ここではvmstatコマンドで確認します。


$ vmstat 2
procs -----------memory---------- ---swap-- -----io---- --system--
----cpu----
r b swpd free buff cache si so bi bo in cs us sy id
wa
1 0 4268 21500 161164 546304 0 0 3 2 3 3 32 3 65
0
6 0 4268 22204 161164 546304 0 0 2 108 0 624 80 6 14
0


見る箇所はbi/bo。
アプリ側で過大なメモリを要求した結果、
仮想メモリを使用して処理を捌こうとします。
つられるようにswapも上昇し
最終的にサーバが応答しなくなります。


最後にTCPコネクション数。
netstatコマンドで確認します。


-------------------------
# netstat -an | wc -l
3050
-------------------------

ポートは65535個しかないので
数万個のTCPコネクションが
あった場合はサーバを分散化する
等の対応が必要になります。


※これらはあくまで負荷状態を把握する
 一時切り分けなので実際の対応は
 サーバの増設するなり、
 アプリケーションを見直すなりの
 対応が必要となります。


 まずはサーバがどういった状況か
 「知る」事が大切という訳ですな。



Oracle奥深くて面白いなぁ~。


という事で現場で色々チューニングしてます。


アクセス数がありえないくらい凄いので


どうしようか未だ検討中ですがね。



■Oracle調査 (同時接続コネクション増加方法)


  ・前提


   OS:redhatlinuxEnterpriseES4

   Ver:Oracle9.2i

   メモリ:8GB。すご・・

   フロントWeb/APサーバ:20台

    


   適切なメモリ割り当てについては

   日々の運用から検討していく必要あり。
   バッファサイズを小さくする事により、

   OSのスワップ、ページングの頻度が減少する為。

   1セッションで数ギガByteのデータを検索するシステムと、
   10セッションで数メガByteを参照するシステムでは、
   どちらがメモリを必要とするか
   セッション数では判断つかない。

   
 ①PGA:プログラムグローバルエリアは,
SQLなどの作業領域として使われるメモリ領域。
  
  1.PGA_AGGREGATE_TARGET
   PGA自体の上限値。 
   
   ※OLTP(On-Line Transaction Processing)頻繁に

    発生する場合はOracleで利用する場合は

    メモリの20%程度割り当てるのが妥当。


  2.WORKAREA_SIZE_POLICY
   パラメータPGA_AGGREGATE_TARGETの有効/無効を決める


 ②SGA:システムグローバルエリアはOracleインスタンスそのもの。


  Oracleを起動した際に割り当てられるメモリのサイズ。

  1.SHARED_POOL_SIZE(共有プール領域)
   ・ライブラリ、ディクショナリキャッシュを指す。

    ライブラリキャッシュ:SQL解析、ストアド、PL/SQL
    ディクショナリキャッシュ:テーブルの列、属性等

    以下の2つのクエリでキャッシュヒット率を調査し、
    アサインするメモリのサイズを増やす必要がある。
    
    [本番サーバで確認するクエリ]
    SELECT A.RATIO "LIBRARY CACHE HIT RATIO",
DECODE(SIGN(A.RATIO - 0.99),1,
'ライブラリキャッシュのヒット率は十分です',
'SHARED_POOL_SIZEを増やしましょう') "notes"
 FROM (SELECT SUM(PINS - RELOADS) /SUM(PINS) RATIO
FROM V$LIBRARYCACHE) A;

    SELECT A.RATIO "ROW CACHE HIT RATIO",
DECODE(SIGN(A.RATIO - 0.95),1,
'ディクショナリキャッシュは十分です',
  'SHARED_POOL_SIZEを増やしましょう') "notes"
  FROM (SELECT SUM(GETS - GETMISSES) /SUM(GETS) RATIO
FROM V$ROWCACHE) A;

    ※ライブラリキャッシュヒット率99%以上で計算
     ディクショナリキャッシュヒット率95以上で計算

 
  2.DB_CACHE_SIZE(DBバッファ)

   
   V$DB_CACHE_ADVICE ← の内容から設定内容を調整
   ※DB_CACHE_ADVICEパラメタをONにする必要あり


  3.LOG_BUFFER(REDOログバッファ)

   
   REDOログ:データに対して行われたすべての変更履歴を記録するファイル。

    [本番サーバで確認するクエリ]   
   SELECT A.RATIO "REDO SPACE WAIT RATIO",
DECODE(SIGN(A.RATIO - 0.01),1,
'LOG_BUFFERを増やしましょう',
'LOG_BUFFERは十分です') "notes"
FROM (SELECT R.VALUE / W.VALUE RATIO
FROM V$SYSSTAT R, V$SYSSTAT W
WHERE R.NAME = 'redo log space requests'

   ※REDOログバッファの待機割合は1%以下で計算



つづく




えと、今、週2でお邪魔している現場で

かなりのアクセス数を捌く方法論を勉強してます。



で、中々使えそうなのが

2つあるので少しずつ

勉強した内容を公開したいと思います。



① OpenNMS


 正式名称はオープン・ネットワーク・マネジメント・システム

 サーバの負荷を監視する運用管理ツール。



② mod_rewrite

 

 用途は様々。

 URLを書き換えたり、負荷分散設定も可能。

 かなり奥が深いと思われる。




このあたりが頭に入ってると

大規模システムでの問題切り分けに

一役買えそうなので勉強、勉強です。





HTMLをロード(表示)した際に

Webサーバに設置しているテキストファイルを

非同期に読み込んで表示する

分かり易いサンプルを。



■前提
以下に記載する3つのファイルのWebサーバ上の設置場所は
同一ディレクトリとします。   



① サーバにmsg1.txtという名前でファイルを設置。

   中身は適当に「test1です」とでもしておきます。



② 前回作成したjslb_ajax.jsを設置。



③ 以下の内容でsample.htmlという名前で設置


※HTMLタグの記述は省略してます。



<!-- ここから -->

<script Language = "JavaScript" src="./jslb_ajax.js" charset="utf-8"></script>
<script>



// HTTPリクエスト送信 ・・・ ①
sendRequest(onloaded,'','GET','./msg1.txt')



// レスポンス受信 ・・・ ②
function onloaded(oj){


alert(oj.responseText)


}

</script>


<!-- ここまで -->



① sendRequest

 HTTPリクエスト送信。

 起動トリガはHTMLがサーバから出力された時。
 onClickやonChange等でも引っ掛けられます。
 
 ・アーギュメント解説
  第1引数(onloaded):レスポンス受信時のコールバック関数を指定。
  第2引数(GET):HTTPリクエストアクション
  第3引数(./msg1.txt):読込むファイルを指定。
 


② onloaded

 HTTPレスポンス受信

 sendRequestの第1引数で指定している
 onloaded関数が呼出されます。
 onloadedの引数にmsg1.txtの内容が
 オブジェクトとして返却されるので
 その内容をポップアップで表示。



とまあ基本は、こんな感じです。



次回はもう少し突っ込んだサンプルと
何でも出来てしまうアーキテクチャなので
無限が思う設計思想について書きたいと思います。


※実業務で実装していないので何ともですが、

 何でも出来てしまう反面、

 サーバ側に負荷が掛かる仕様なので。