Linuxの経験が少しある人からの洞察は、IOシステムで役立つでしょう。ここに私の話があります。
最近、Ceph経由でファイルを提供するために6つのDell PowerEdge rx720xdsのクラスタを立ち上げました。これらのマシンは、2つのnumaゾーンと70個の奇数ギガバイトのメモリを備えた2つのソケット上に24コアを備えています。ディスクはそれぞれ1つのディスクのRAIDとしてフォーマットされています(他の方法で直接ディスクを公開する方法はありませんでした)。ネットワーキングは、mellanox infiniband IP over IBによって提供されます(IPパケットは、ハードウェアではなくカーネルランドでIBに変換されます)。
SASドライブは次のようにマウントされています。
# cat /proc/mounts | grep osd
/dev/sdm1 /var/lib/ceph/osd/ceph-90 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdj1 /var/lib/ceph/osd/ceph-87 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdu1 /var/lib/ceph/osd/ceph-99 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdd1 /var/lib/ceph/osd/ceph-82 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdk1 /var/lib/ceph/osd/ceph-88 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdl1 /var/lib/ceph/osd/ceph-89 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdh1 /var/lib/ceph/osd/ceph-86 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdo1 /var/lib/ceph/osd/ceph-97 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdc1 /var/lib/ceph/osd/ceph-81 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdb1 /var/lib/ceph/osd/ceph-80 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sds1 /var/lib/ceph/osd/ceph-98 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdn1 /var/lib/ceph/osd/ceph-91 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sde1 /var/lib/ceph/osd/ceph-83 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdq1 /var/lib/ceph/osd/ceph-93 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdg1 /var/lib/ceph/osd/ceph-85 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdt1 /var/lib/ceph/osd/ceph-95 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdf1 /var/lib/ceph/osd/ceph-84 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdr1 /var/lib/ceph/osd/ceph-94 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdi1 /var/lib/ceph/osd/ceph-96 xfs rw,noatime,attr2,inode64,noquota 0 0
/dev/sdp1 /var/lib/ceph/osd/ceph-92 xfs rw,noatime,attr2,inode64,noquota 0 0
IOこれらのマシンを通過すると、数百MB /秒でバーストしますが、ほとんどの場合、多くの小さな「突っ込み」でかなりアイドル状態です:
# iostat -x -m
Linux 3.10.0-123.el7.x86_64 (xxx) 07/11/14 _x86_64_ (24 CPU)
avg-cpu: %user %Nice %system %iowait %steal %idle
1.82 0.00 1.05 0.11 0.00 97.02
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.11 0.25 0.23 0.00 0.00 27.00 0.00 2.07 3.84 0.12 0.61 0.03
sdb 0.02 0.57 3.49 2.28 0.08 0.14 77.18 0.01 2.27 2.99 1.18 1.75 1.01
sdd 0.03 0.65 3.93 3.39 0.10 0.16 70.39 0.01 1.97 2.99 0.79 1.57 1.15
sdc 0.03 0.60 3.76 2.86 0.09 0.13 65.57 0.01 2.10 3.02 0.88 1.68 1.11
sdf 0.03 0.63 4.19 2.96 0.10 0.15 73.51 0.02 2.16 3.03 0.94 1.73 1.24
sdg 0.03 0.62 3.93 3.01 0.09 0.15 70.44 0.01 2.06 3.01 0.81 1.66 1.15
sde 0.03 0.56 4.35 2.61 0.10 0.14 69.53 0.02 2.26 3.00 1.02 1.82 1.26
sdj 0.02 0.73 3.67 4.74 0.10 0.37 116.06 0.02 1.84 3.01 0.93 1.31 1.10
sdh 0.03 0.62 4.31 3.04 0.10 0.15 67.83 0.02 2.15 3.04 0.89 1.75 1.29
sdi 0.02 0.59 3.82 2.47 0.09 0.13 74.35 0.01 2.20 2.96 1.03 1.76 1.10
sdl 0.03 0.59 4.75 2.46 0.11 0.14 70.19 0.02 2.33 3.02 1.00 1.93 1.39
sdk 0.02 0.57 3.66 2.41 0.09 0.13 73.57 0.01 2.20 3.00 0.97 1.76 1.07
sdm 0.03 0.66 4.03 3.17 0.09 0.14 66.13 0.01 2.02 3.00 0.78 1.64 1.18
sdn 0.03 0.62 4.70 3.00 0.11 0.16 71.63 0.02 2.25 3.01 1.05 1.79 1.38
sdo 0.02 0.62 3.75 2.48 0.10 0.13 76.01 0.01 2.16 2.94 0.99 1.70 1.06
sdp 0.03 0.62 5.03 2.50 0.11 0.15 68.65 0.02 2.39 3.08 0.99 1.99 1.50
sdq 0.03 0.53 4.46 2.08 0.09 0.12 67.74 0.02 2.42 3.04 1.09 2.01 1.32
sdr 0.03 0.57 4.21 2.31 0.09 0.14 72.05 0.02 2.35 3.00 1.16 1.89 1.23
sdt 0.03 0.66 4.78 5.13 0.10 0.20 61.78 0.02 1.90 3.10 0.79 1.49 1.47
sdu 0.03 0.55 3.93 2.42 0.09 0.13 70.77 0.01 2.17 2.97 0.85 1.79 1.14
sds 0.03 0.60 4.11 2.70 0.10 0.15 74.77 0.02 2.25 3.01 1.10 1.76 1.20
sdw 1.53 0.00 0.23 38.90 0.00 1.66 87.01 0.01 0.22 0.11 0.22 0.05 0.20
sdv 0.88 0.00 0.16 28.75 0.00 1.19 84.55 0.01 0.24 0.10 0.24 0.05 0.14
dm-0 0.00 0.00 0.00 0.00 0.00 0.00 8.00 0.00 1.84 1.84 0.00 1.15 0.00
dm-1 0.00 0.00 0.23 0.29 0.00 0.00 23.78 0.00 1.87 4.06 0.12 0.55 0.03
dm-2 0.00 0.00 0.01 0.00 0.00 0.00 8.00 0.00 0.47 0.47 0.00 0.45 0.00
約48時間後、隣接するページが断片化されるため、4つの割り当て(16ページ、65536バイト)が失敗し、パケットのドロップが始まります(SLABが大きくなるとkallocが失敗するため)。
これは、比較的「正常な」サーバーは次のようになります。
# cat /sys/kernel/debug/extfrag/unusable_index
Node 0, zone DMA 0.000 0.000 0.000 0.001 0.003 0.007 0.015 0.031 0.031 0.096 0.225
Node 0, zone DMA32 0.000 0.009 0.015 0.296 0.733 0.996 0.997 0.998 0.998 1.000 1.000
Node 0, zone Normal 0.000 0.000 0.019 0.212 0.454 0.667 0.804 0.903 0.986 1.000 1.000
Node 1, zone Normal 0.000 0.027 0.040 0.044 0.071 0.270 0.506 0.772 1.000 1.000 1.000
断片化がかなり悪化すると、システムはカーネル空間で回転し始め、すべてがばらばらになります。この障害時の1つの異常は、xfsaildが大量のCPUを使用しているように見え、割り込みできないスリープ状態でスタックすることです。ただし、システム全体の障害が発生している間、奇妙な結論にジャンプしたくありません。
これらの割り当てが失敗しないことを保証するために、私は断片化しても、次のように設定しました:
vm.min_free_kbytes = 16777216
SLABキャッシュで数百万のblkdev_requestsを確認した後、次の方法でダーティページを削減しようとしました。
vm.dirty_ratio = 1
vm.dirty_background_ratio = 1
vm.min_slab_ratio = 1
vm.zone_reclaim_mode = 3
一度に変更する変数が多すぎる可能性がありますが、inodeとdentriesが断片化を引き起こしている場合に備えて、それらを最小限に抑えることにしました。
vm.vfs_cache_pressure = 10000
そしてこれは助けになりました。フラグメンテーションはまだ高いですが、inodeとdentryの問題が減ったことで、奇妙なことに気づき、...
キャッシュをドロップすると消えるblkdev_requests(アクティブである以上)が非常に多いのはなぜですか?
これが私の意味です:
# slabtop -o -s c | head -20
Active / Total Objects (% used) : 19362505 / 19431176 (99.6%)
Active / Total Slabs (% used) : 452161 / 452161 (100.0%)
Active / Total Caches (% used) : 72 / 100 (72.0%)
Active / Total Size (% used) : 5897855.81K / 5925572.61K (99.5%)
Minimum / Average / Maximum Object : 0.01K / 0.30K / 15.69K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
2565024 2565017 99% 1.00K 80157 32 2565024K xfs_inode
3295194 3295194 100% 0.38K 78457 42 1255312K blkdev_requests
3428838 3399527 99% 0.19K 81639 42 653112K dentry
5681088 5680492 99% 0.06K 88767 64 355068K kmalloc-64
2901366 2897861 99% 0.10K 74394 39 297576K buffer_head
34148 34111 99% 8.00K 8537 4 273184K kmalloc-8192
334768 334711 99% 0.57K 11956 28 191296K radix_tree_node
614959 614959 100% 0.15K 11603 53 92824K xfs_ili
21263 19538 91% 2.84K 1933 11 61856K task_struct
18720 18636 99% 2.00K 1170 16 37440K kmalloc-2048
32032 25326 79% 1.00K 1001 32 32032K kmalloc-1024
10234 9202 89% 1.88K 602 17 19264K TCP
22152 19765 89% 0.81K 568 39 18176K task_xstate
# echo 2 > /proc/sys/vm/drop_caches :(
# slabtop -o -s c | head -20
Active / Total Objects (% used) : 965742 / 2593182 (37.2%)
Active / Total Slabs (% used) : 69451 / 69451 (100.0%)
Active / Total Caches (% used) : 72 / 100 (72.0%)
Active / Total Size (% used) : 551271.96K / 855029.41K (64.5%)
Minimum / Average / Maximum Object : 0.01K / 0.33K / 15.69K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
34140 34115 99% 8.00K 8535 4 273120K kmalloc-8192
143444 20166 14% 0.57K 5123 28 81968K radix_tree_node
768729 224574 29% 0.10K 19711 39 78844K buffer_head
73280 8287 11% 1.00K 2290 32 73280K xfs_inode
21263 19529 91% 2.84K 1933 11 61856K task_struct
686848 97798 14% 0.06K 10732 64 42928K kmalloc-64
223902 41010 18% 0.19K 5331 42 42648K dentry
32032 23282 72% 1.00K 1001 32 32032K kmalloc-1024
10234 9211 90% 1.88K 602 17 19264K TCP
22152 19924 89% 0.81K 568 39 18176K task_xstate
69216 59714 86% 0.25K 2163 32 17304K kmalloc-256
98421 23541 23% 0.15K 1857 53 14856K xfs_ili
5600 2915 52% 2.00K 350 16 11200K kmalloc-2048
これは、blkdev_requestのビルドアップが実際にはダーティページに関連しているではなく、さらにアクティブなオブジェクトが実際にはアクティブではないことを私に言います。これらのオブジェクトが実際に使用されていない場合、どのようにして解放できますか?ここで何が起こっているのですか?
いくつかの背景として、drop_cachesの処理は次のとおりです。
http://lxr.free-electrons.com/source/fs/drop_caches.c
それらはblkdev_requestsではないかもしれないが、その「見出し」の下にxfs_bufエントリが表示されている可能性があることを理解しましたか?これがどのように機能するかわかりません:
/sys/kernel/slab # ls -l blkdev_requests(
lrwxrwxrwx 1 root root 0 Nov 7 23:18 blkdev_requests -> :t-0000384/
/sys/kernel/slab # ls -l | grep 384
lrwxrwxrwx 1 root root 0 Nov 7 23:18 blkdev_requests -> :t-0000384/
lrwxrwxrwx 1 root root 0 Nov 7 23:19 ip6_dst_cache -> :t-0000384/
drwxr-xr-x 2 root root 0 Nov 7 23:18 :t-0000384/
lrwxrwxrwx 1 root root 0 Nov 7 23:19 xfs_buf -> :t-0000384/
これらが「drop_slabs」によってクリアされる理由、またはこの断片化の原因を解明する方法はまだわかりません。
ここまで読んだら、ご清聴ありがとうございました!
メモリとxfs情報: https://Gist.github.com/christian-marie/f417cc3134544544a8d1
ページ割り当ての失敗: https://Gist.github.com/christian-marie/7bc845d2da7847534104
http://ponies.io/raw/compaction.png
圧縮コードは少し非効率的に見えますか?失敗した圧縮を複製するためにいくつかのコードをまとめました: https://Gist.github.com/christian-marie/cde7e80c5edb889da541
これは問題を再現しているようです。
また、イベントトレースにより、何度も何度も何度も失敗した再利用が失敗していることがわかります。
<...>-322 [023] .... 19509.445609: mm_vmscan_direct_reclaim_end: nr_reclaimed=1
Vmstatの出力も関係しています。システムがこの高負荷状態にある間、コンパクションは屋根を通過します(そしてほとんどが失敗します)。
pgmigrate_success 38760827 pgmigrate_fail 350700119 compact_migrate_scanned 301784730 compact_free_scanned 204838172846 compact_isolated 18711615 compact_stall 270115 compact_fail 244488 compact_success 25212
確かに、再生/圧縮には何か問題があります。
現時点では、ipoibセットアップにSGサポートを追加して、高次の割り当てを減らすことを目指しています。実際の問題はおそらくvmscanに関連しているようです。
これは興味深く、この質問を参照しています: http://marc.info/?l=linux-mm&m=141607142529562&w=2
コメントが多いので観察で答えると思いました。
https://Gist.github.com/christian-marie/7bc845d2da7847534104 の出力に基づいて
以下を決定できます。
ゾーンの断片化はここにあります:
[3443189.780792] Node 0 Normal: 3300*4kB (UEM) 8396*8kB (UEM) 4218*16kB (UEM) 76*32kB (UEM) 12*64kB (M) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 151056kB
[3443189.780801] Node 1 Normal: 26667*4kB (UEM) 6084*8kB (UEM) 2040*16kB (UEM) 96*32kB (UEM) 22*64kB (UEM) 4*128kB (U) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 192972kB
そして、当時のメモリ使用量はここにあります:
[3443189.780759] Node 0 Normal free:149520kB min:40952kB low:51188kB high:61428kB active_anon:9694208kB inactive_anon:1054236kB active_file:7065912kB inactive_file:7172412kB unevictable:0kB isolated(anon):5452kB isolated(file):3616kB present:30408704kB managed:29881160kB mlocked:0kB dirty:0kB writeback:0kB mapped:25440kB shmem:743788kB slab_reclaimable:1362240kB slab_unreclaimable:783096kB kernel_stack:29488kB pagetables:43748kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
[3443189.780766] Node 1 Normal free:191444kB min:45264kB low:56580kB high:67896kB active_anon:11371988kB inactive_anon:1172444kB active_file:8084140kB inactive_file:8556980kB unevictable:0kB isolated(anon):4388kB isolated(file):4676kB present:33554432kB managed:33026648kB mlocked:0kB dirty:0kB writeback:0kB mapped:45400kB shmem:2263296kB slab_reclaimable:1606604kB slab_unreclaimable:438220kB kernel_stack:55936kB pagetables:44944kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
各ゾーンの断片化は、ページ割り当て失敗の出力で不良です。無料の注文ページがたくさんあり、より高い注文ページはほとんどありません。 「良い」結果は、各注文に沿って豊富な無料ページとなり、注文が高くなるにつれてサイズが徐々に小さくなります。高次ページが0以上である5以上は、高次割り当ての断片化と飢餓を示します。
私は現在、この期間の断片化がスラブキャッシュと関係があることを示唆する確かな程度の証拠を見ていません。結果のメモリ統計では、次のことがわかります
Node 0 = active_anon:9694208kB inactive_anon:1054236kB
Node 1 = active anon:11371988kB inactive_anon:1172444kB
ユーザースペースから割り当てられた巨大なページはないため、ユーザースペースは常に注文0のメモリを要求します。したがって、両方のゾーンで22GiBを超えるデフラグ可能なメモリが存在します。
説明できない行動
高次の割り当てが失敗した場合、高次のメモリ割り当ての領域を実行して成功させるために、メモリの圧縮が常に試行されていると理解しています。なぜこれが起こらないのですか?それが発生した場合、並べ替えに適した22GiBのメモリがあるのに、デフラグするメモリが見つからないのはなぜですか?
私が説明できると思う行動
これを正しく理解するにはさらに調査が必要ですが、ページキャッシュを自動的にスワップ/ドロップする割り当ての機能は、まだ十分に利用できる空きメモリがあるため、おそらくここでは適用されず、再利用は発生しないと思います。高次では十分ではありません。
多くの空きメモリおよび各ゾーンに残っているいくつかの注文4リクエストがある一方で、「各注文の合計空きメモリの合計と実際の空きメモリから差し引く」という問題は、実際の割り当てエラーの原因となる「最低」ウォーターマークの下の「空きメモリ」。