イフブロ

イフブロ

インフラエンジニアのブログ

Mem使用率の見方 with HugePage

概要

データベースサーバーでHugePageを有効化して活用している事例があった。 メモリの使用率をグラフで見ていると、全然使われてない様に思ったのだが それは誤解だった。

という事でMemの使用率を追いかける方法を学ぶのから逃げていたが改めて踏み込んでみた。

この記事で書かれている事

  • ps で表示されるMem使用総量と freesar で表示される MemUsedと乖離があったのでその原因を学んだ。
  • つまりHugePageというのがpsからは見えないのでコレ使ってるのだれ!?の追い方を理解した。

事の発端

musql 仕事しろよ (#゚Д゚)ドルァ!! f:id:umisora2:20171219134836p:plain

このサーバー、実はモンスターマシンでして CPU 88コア (論理コア) Mem 528GB?(多分)

なのに

# ps aux | grep mysqld
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mysql       8809 1719  5.8 72607356 31071336 ?   Sl   04:55 9030:04 /bin/mysqld --basedir=/path/to/mysql --datadir=/path/to/mysql/db --plugin-
dir=/path/to/mysql/lib/plugin --user=mysql --log-error=/path/to/log/mysql/mysqld.log --pid-file=/path/to/run/mysqld.pid --socket=/path/to/run/mysql/mysql.sock

RSS31071336 31GB程度しか使ってない。

なんでやーーー!

ps以外の視点から見てみる

  • 全てkb表示
  • 取得タイミングが数十分以上離れているので同一タイミングではない

sar -r

kbmemused めっちゃ使ってる。 393GB psより遥かに大きいのがOS上では usedになっている。

13時45分01秒 kbmemfree kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit
13時46分01秒 135665560 393610140     74.37    427112  42241120  37279952      6.54
13時47分01秒 135584936 393690764     74.38    427168  42305428  37315968      6.54
13時48分01秒 135522612 393753088     74.39    427224  42372292  37284580      6.54
13時49分01秒 135439348 393836352     74.41    427280  42445936  37293728      6.54
13時50分01秒 135377228 393898472     74.42    427348  42510444  37292012      6.54
13時51分01秒 135255300 394020400     74.45    427412  42570252  37353776      6.55
13時52分01秒 135261316 394014384     74.44    427492  42628180  37288768      6.54
13時53分01秒 135155980 394119720     74.46    427536  42699240  37362440      6.55
13時54分01秒 135114304 394161396     74.47    427592  42756336  37325400      6.55
13時55分01秒 135054000 394221700     74.48    427640  42816532  37289736      6.54
13時56分01秒 134983992 394291708     74.50    427684  42874384  37324760      6.55
13時57分01秒 134938996 394336704     74.50    427744  42929996  37297064      6.54
13時58分01秒 134872040 394403660     74.52    427808  42988628  37304812      6.54

vmstat

usedの表記はないものの freeのサイズを物理メモリから引くとやはり 393GB 近いメモリが使われていると見える。 (そこにはcacheやbufferも入ってしまうのでもっと小さい筈であるが)

$ vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
12  2      0 134845840 427836 43019068    0    0   128   356    6    4 10  1 89  0  0

free

こちらも sar と似て usedが遥かに大きい。 350544632RSSに概ねなるはず。

$ free
             total       used       free     shared    buffers     cached
Mem:     529275700  388181752  141093948        432     422640   37214480
-/+ buffers/cache:  350544632  178731068
Swap:     40959996          0   40959996

なんでや。

今回はデータベース・サーバーなのでHugePageを使って大規模メモリを使用している。

Huge Page とは何ですか? これを使用する利点は? - Red Hat Customer Portal

で、HugePageを調べていくとどうやら

  • psでは表示されない
  • 「Usedに入れて表現してしまえ」とusedには乗ってくる

っぽい。 refs: HugePage は free コマンドで見ると used に計上される(2) - ablog

なので sar vmstat free > ps の図式になってしまった。

HugePageの使用状況を見る

HugePageを使用しているプロセスの調べ方

refs Linux で huge page を使っているプロセスを調べる方法 - ablog

/proc/[pid]/smaps で KernelPageSize が 4 kB 以外のプロセス を探して、それのプロセスをpsで調べるらしい。

HugePageの使用率を調べる

pmap

Linux で huge page を使っているプロセスを調べる方法 - ablog

# pmap -x 8809 | head -n 3
8809:   /bin/mysqld --basedir=/path/to/mysql --datadir=/path/to/mysql/db --plugin-
dir=/path/to/mysql/lib/plugin --user=mysql --log-error=/path/to/log/mysql/mysqld.log --pid-file=/path/to/run/mysqld.pid --socket=/path/to/run/mysql/mysql.sock
Address           Kbytes     RSS   Dirty Mode   Mapping
~~~~
~~~~
----------------  ------  ------  ------
total kB       364507192 72607356 31071336 30919932

30934144 30GBがRSS 364507192 が HugePage + RSS + Dirty っぽい? 302653116 302GBが概ねHugePage っぽい?

/prox//smaps

RHEL で hugepage の使用量と、何に使用されているかを確認する - Red Hat Customer Portal

grep -B 11 'KernelPageSize:     2048 kB' /proc/8809/smaps | grep "^Size:"

Size:             135168 kB   <------ HugePage使用量
Rss:                   0 kB   <------ RSS使用量 (HugePageを使っている場合は0になる
Pss:                   0 kB
Shared_Clean:          0 kB
Shared_Dirty:          0 kB
Private_Clean:         0 kB
Private_Dirty:         0 kB
Referenced:            0 kB
Anonymous:             0 kB
AnonHugePages:         0 kB
Swap:                  0 kB
KernelPageSize:     2048 kB   <------ 4kbじゃないのでHugePageを使っている事がわかる

このファイルを美味いことgrep & awkすると

# grep -B 11 'KernelPageSize:     2048 kB' /proc/8809/smaps | grep "^Size:"| awk 'BEGIN{sum=0}{sum+=$2}END{print sum}'
291971072  (kb)

291GB がHugePageっぽい (pmap叩いた時とタイミングが違うので数字がズレてる)

# cat /proc/8809/smaps | grep "^Rss:"|awk 'BEGIN{sum=0}{sum+=$2}END{print sum}'
31071188 (kb)

31GBがRSS

数字の大きさは揃ったので納得。

まとめ

  • free / vmstat / sar -r で見れるメモリ使用率にはHugePageが含まれる
  • ps ではHugePageは表示されない
  • 結果的にプロセス単位のメモリ使用率のグラフを出すとHugePage分が欠けて見える (OSでのメモリ使用率のグラフは正しく表示される)

勉強になりました。