xfs、20個のディスク、Cephを備えた「大規模」サーバーでのページの断片化の原因


18

Linux IOシステムの経験が少しある人からの洞察は役に立ちます。これが私の話です。

最近、6つのDell PowerEdge rx720xdsのクラスターを立ち上げ、Ceph経由でファイルを提供しました。これらのマシンには、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 / sでバーストしますが、ほとんどの場合、多くの小さな「ポケ」でかなりアイドル状態です。

# 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_requestを確認した後、次の方法でダーティページを削減しようとしました。

vm.dirty_ratio = 1
vm.dirty_background_ratio = 1
vm.min_slab_ratio = 1
vm.zone_reclaim_mode = 3

一度に変更する変数が多すぎる可能性がありますが、iノードとデントリがフラグメンテーションを引き起こしている場合に備えて、それらを最小限に抑えることにしました。

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


2
そうそう!! これらの良い質問の多くは得られません。しかし、私たちに何ができるかを見ていきます。
ewwhite 14年

1
の出力/proc/buddyinfoと結果を提供してくださいfree -m。blockdevリクエストは、おそらくでバッファとして表されますfree。ああ、あなたが使用しているディストリビューションも良いでしょう。さらに、page allocation failureメッセージが表示されていdmesgますか?その場合、出力と関連するコンテキストを提供してください。
マシューイフェ14年

1
また、特定のmkfs.xfsコマンドラインを使用しましたか?ヒュージページは有効ですか?
ewwhite 14年

また、出力/proc/meminfo
マシューイフェ14年

透過的なhugepagesを単独で無効にしようと(それらをneverに設定)、失敗は依然として発生しました。これを他の「修正」と組み合わせて試しませんでした。
ピングー14年

回答:


4

多くのコメントがあるので、自分の意見に答えを出そうと思った。

https://gist.github.com/christian-marie/7bc845d2da7847534104の出力に基づいています

以下を決定できます。

  1. 試行されたメモリ割り当てのGFP_MASKは、以下を実行できます。
    • 緊急プールにアクセスできます(これは、ゾーンの最高水準点以下のデータにアクセスすることを意味すると思います
    • 緊急予備を使用しないでください(これは、最小透かし以下のメモリへのアクセスを許可しないことを意味すると思います
    • 通常ゾーンの1つから割り当てます。
    • スペースを空けるために交換できます。
    • 空きを作るためにキャッシュをドロップできます。

ゾーンの断片化は次の場所にあります。

[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以上の高位ページが0であるということは、高位割り当ての断片化と枯渇を示しています。

私は現在、この期間中の断片化がスラブキャッシュに関係していることを示唆する説得力のある証拠を見ていません。結果のメモリ統計では、次のことがわかります

Node 0 = active_anon:9694208kB inactive_anon:1054236kB
Node 1 = active anon:11371988kB inactive_anon:1172444kB

ユーザースペースから割り当てられた巨大なページはないため、ユーザースペースは常にオーダー0のメモリを要求します。したがって、両方のゾーンに合計で22GiBを超えるデフラグ可能なメモリがあります。

説明できない行動

高次の割り当てが失敗した場合、高次のメモリ割り当ての領域を有効にして成功させるために、常にメモリの圧縮が試行されることを理解しています。なぜこれが起こらないのですか?発生した場合、22GiBのリオーダの準備が整っているときに、最適化するメモリが見つからないのはなぜですか?

私が説明できると思う行動

これを適切に理解するには、より多くの調査が必要ですが、多くの空きメモリがまだ利用可能であるため、再利用が発生しないため、ページキャッシュを自動的にスワップ/ドロップして成功させるための割り当て機能はおそらくここでは適用されないと考えています。高次では十分ではありません。

各ゾーンには多くの空きメモリいくつかの注文4リクエストが残っていますが、「各注文のすべての空きメモリを合計し、実際の空きメモリから差し引く」問題により、「最小」ウォーターマークの下に「空きメモリ」があります。実際の割り当ての失敗につながるもの。


比較的(合計空きメモリに対して)小さなスラブキャッシュがすべてのメモリを断片化することは奇妙に思えます。私はそれらの無料の排除可能なページのすべてで、それが単にいくつかを追い出し、それで完了すると期待していたでしょう。NUMAはこの奇妙なことに関係があるのではないかと思う。
ピングー14年

されnumad、このシステム上で実行されていますか?
ewwhite 14年

@ewwhite numadは実行されていません。
ピング14年

@pinguこの動作が再現可能な場合は、numadサービスを有効にして、のアクションに注意してください/var/log/numad.log。libcgroupもインストールする必要がある場合があります。
ewwhite 14年

@ewwhiteさて、私は1つを実行しています。私はそれが何を期待しているのか、それからどのような情報を得るのかわからない。何が起こることを望んでいますか?
ピングー14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.