具有xfs,20个磁盘和Ceph的“大型”服务器上页面碎片的原因


18

任何有Linux IO系统经验的人的任何见解都会有所帮助。这是我的故事:

最近建立了一个由六个Dell PowerEdge rx720xds组成的集群,用于通过Ceph提供文件。这些机器在两个插槽上具有24个内核,并具有两个numa区域和70奇吉字节的内存。磁盘格式化为每个磁盘的RAID(否则,我们看不到直接公开磁盘的方法)。网络由IB上的mellanox infiniband IP提供(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小时后,连续的页面变得非常分散,以至于四个(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 [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 2014年

1
请提供的输出/proc/buddyinfo和结果free -m吗?blockdev请求可能表示为中的缓冲区free。哦,您正在使用的发行版也将很好。此外,您是否有任何page allocation failure消息出现在中dmesg?如果是这样,请提供输出以及任何相关上下文。
Matthew Ife 2014年

1
另外,您是否使用了特定的mkfs.xfs命令行?已启用大页面?
ewwhite 2014年

以及/proc/meminfo
Matthew Ife

尝试单独禁用透明大页面(将它们设置为“永不”),仍然发生故障。请勿将其与其他“修复程序”一起尝试。
pingu 2014年

Answers:


4

我以为我会对自己的观察结果做出回答,因为有很多评论。

基于https://gist.github.com/christian-marie/7bc845d2da7847534104的输出

我们可以确定以下内容:

  1. 尝试对内存分配进行尝试的GFP_MASK可以执行以下操作。
    • 可以访问紧急池(我认为这意味着访问区域高水位以下的数据)
    • 不要使用紧急储备(我认为这意味着不允许访问最低水位以下的记忆)
    • 从正常区域之一分配。
    • 可以交换以腾出空间。
    • 可以删除缓存以腾出空间。

区域碎片位于此处:

[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个请求,但是“每个订单的所有可用内存总计并从实际可用内存中扣除”问题会导致“最小”水印下方的“可用内存”为导致实际分配失败的原因。


相对较小的(总计可用内存)较小的SLAB缓存会碎片化所有内存,这似乎很奇怪。我本来希望所有这些免费的可撤出页面都会将其逐出并完成。我怀疑NUMA可能与这种奇怪情况有关。
pingu 2014年

正在numad这个系统上运行?
ewwhite 2014年

@ewwhite numad没有运行,不。
pingu 2014年

@pingu如果此行为是可重现的,请尝试启用该numad服务并注意中的操作/var/log/numad.log。您可能还需要安装libcgroup。
ewwhite 2014年

@ewwhite好的,我现在正在运行。我不确定我期望它做什么或我们可能从中获得什么信息。您希望发生什么事?
pingu 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.