linux – 使用xfs,20个磁盘和Ceph的“大型”服务器上的页面碎片的原因

来自具有 linux IO系统经验的人的任何见解都会有所帮助.这是我的故事:

最近推出了六个Dell PowerEdge rx720xds集群,通过Ceph提供文件服务.这些机器有24个核心,两个插座,两个numa区域和70奇数千兆字节的内存.磁盘被格式化为每个磁盘的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,noquota 0 0
/dev/sdu1 /var/lib/ceph/osd/ceph-99 xfs rw,noquota 0 0
/dev/sdd1 /var/lib/ceph/osd/ceph-82 xfs rw,noquota 0 0
/dev/sdk1 /var/lib/ceph/osd/ceph-88 xfs rw,noquota 0 0
/dev/sdl1 /var/lib/ceph/osd/ceph-89 xfs rw,noquota 0 0
/dev/sdh1 /var/lib/ceph/osd/ceph-86 xfs rw,noquota 0 0
/dev/sdo1 /var/lib/ceph/osd/ceph-97 xfs rw,noquota 0 0
/dev/sdc1 /var/lib/ceph/osd/ceph-81 xfs rw,noquota 0 0
/dev/sdb1 /var/lib/ceph/osd/ceph-80 xfs rw,noquota 0 0
/dev/sds1 /var/lib/ceph/osd/ceph-98 xfs rw,noquota 0 0
/dev/sdn1 /var/lib/ceph/osd/ceph-91 xfs rw,noquota 0 0
/dev/sde1 /var/lib/ceph/osd/ceph-83 xfs rw,noquota 0 0
/dev/sdq1 /var/lib/ceph/osd/ceph-93 xfs rw,noquota 0 0
/dev/sdg1 /var/lib/ceph/osd/ceph-85 xfs rw,noquota 0 0
/dev/sdt1 /var/lib/ceph/osd/ceph-95 xfs rw,noquota 0 0
/dev/sdf1 /var/lib/ceph/osd/ceph-84 xfs rw,noquota 0 0
/dev/sdr1 /var/lib/ceph/osd/ceph-94 xfs rw,noquota 0 0
/dev/sdi1 /var/lib/ceph/osd/ceph-96 xfs rw,noquota 0 0
/dev/sdp1 /var/lib/ceph/osd/ceph-92 xfs rw,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小时后,连续页面碎片化,以至于四个(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

当碎片变得更糟时,系统似乎开始在内核空间中旋转,一切都崩溃了.在这次失败期间,一个异常现象是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 ……. 19509.445609:mm_vmscan_direct_reclaim_end:nr_reclaimed = 1

Vmstat输出也有关系.虽然系统处于这种高负载状态,但压缩通过屋顶(并且主要是失败):

pgmigrate_success 38760827
pgmigrate_fail 35https://gist.github.com/christian-marie/f417cc3134544544a8d119
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的输出

我们可以确定以下内容:

>尝试进行内存分配的GFP_MASK允许执行以下操作.

>可以访问紧急池(我认为这意味着访问区域的高水位线以下的数据)
>不要使用紧急储备(我认为这意味着不允许在最小水印下方访问memroy)
>从其中一个正常区域分配.
>可以交换以腾出空间.
>可以放下缓存以腾出空间.

区域碎片位于此处:

[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页,更少订单页面更少.一个“好”的结果将是每个订单上的丰富的免费页面,随着您的订单越高,尺寸逐渐变小.具有0个高阶页面5及以上表示高阶分配的碎片和饥饿.

我目前没有看到令人信服的证据表明这一时期的碎片与板坯缓存有任何关系.在生成的内存统计信息中,我们可以看到以下内容

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

用户空间没有分配大页面,因此用户空间将始终声明订单0内存.因此,在两个区域中总共存在超过22GiB的可碎片化存储器.

行为我无法解释

当高阶分配失败时,我的理解是总是尝试进行内存压缩,以便允许高阶内存分配区域发生并成功.为什么这不会发生?如果它确实发生了,为什么当22GiB的重新排序成熟时,它没有找到任何内存进行碎片整理?

行为我认为我可以解释

这需要更多的研究才能正确理解,但我相信分配能够自动交换/删除一些页面缓存才能成功,这可能不适用于此,因为仍有大量可用内存,因此不会发生回收.高阶订单还不够.

虽然每个区域都有大量的空闲内存和一些订单4请求,但“每个订单的所有可用内存总量和从真实可用内存中扣除”问题会导致“最小”水印下方的“空闲内存”导致实际分配失败的原因.

相关文章

linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、...
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别...
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书...
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满...
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的...
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线...