Ursache der Seitenfragmentierung auf "großem" Server mit xfs, 20 Festplatten und Ceph

18

Jeder Einblick von jemandem mit ein wenig Erfahrung im Linux-IO-System wäre hilfreich. Hier ist meine Geschichte:

Kürzlich wurde ein Cluster von sechs Dell PowerEdge rx720xds gestartet, um Dateien über Ceph bereitzustellen. Diese Maschinen haben 24 Kerne über zwei Sockel mit zwei numa Zonen und 70 ungeraden Gigabyte Speicher. Die Datenträger sind als Raids von jeweils einem Datenträger formatiert (wir konnten keinen Weg finden, sie ansonsten direkt freizugeben). Das Netzwerk wird von mellanox infiniband IP over IB bereitgestellt (IP-Pakete werden im Kernel-Land in IB umgewandelt, nicht in Hardware).

Wir haben jedes unserer SAS-Laufwerke folgendermaßen montiert:

# 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

Das E / A, das diese Maschinen durchläuft, platzt mit ein paar hundert MB / s, aber die meiste Zeit ist es ziemlich untätig mit vielen kleinen "Stößen":

# 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

Das Problem:

Nach ungefähr 48 Stunden sind zusammenhängende Seiten so fragmentiert, dass die Zuweisung von vier (16 Seiten, 65536 Byte) fehlschlägt und wir beginnen, Pakete zu verwerfen (aufgrund von Kalloc-Fehlern, wenn ein SLAB wächst).

So sieht ein relativ "gesunder" Server aus:

# 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 

Wenn sich die Fragmentierung erheblich verschlechtert, scheint sich das System im Kernelraum zu drehen und alles fällt einfach auseinander. Eine Anomalie bei diesem Fehler ist, dass xfsaild anscheinend viel CPU verbraucht und im unterbrechungsfreien Ruhezustand hängen bleibt. Ich möchte jedoch nicht zu merkwürdigen Schlussfolgerungen bei einem Totalausfall des Systems kommen.

Bisherige Problemumgehung

Um sicherzustellen, dass diese Zuweisungen auch bei Fragmentierung nicht fehlschlagen, habe ich Folgendes festgelegt:

vm.min_free_kbytes = 16777216

Nachdem ich Millionen von blkdev_requests in SLAB-Caches gesehen hatte, versuchte ich, schmutzige Seiten zu reduzieren:

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

Möglicherweise werden zu viele Variablen gleichzeitig geändert, aber nur für den Fall, dass die Inodes und Dentries eine Fragmentierung verursachen, habe ich beschlossen, sie auf ein Minimum zu beschränken:

vm.vfs_cache_pressure = 10000

Und das schien zu helfen. Die Fragmentierung ist immer noch hoch und die reduzierten Inode- und Dentry-Probleme führten dazu, dass ich etwas Seltsames bemerkte, das mich zu ...

Meine Frage:

Warum habe ich so viele blkdev_requests (die nicht weniger aktiv sind), die einfach verschwinden, wenn ich Caches lösche?

Hier ist was ich meine:

# 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           

Dies sagt mir, dass der Aufbau von blkdev_request nicht mit schmutzigen Seiten zusammenhängt und dass die aktiven Objekte nicht wirklich aktiv sind? Wie können diese Objekte freigegeben werden, wenn sie tatsächlich nicht verwendet werden? Was geht hier vor sich?

Für einige Hintergründe ist hier, was die drop_caches tun:

http://lxr.free-electrons.com/source/fs/drop_caches.c

Aktualisieren:

Haben Sie herausgefunden, dass es sich möglicherweise nicht um blkdev_requests handelt, sondern um xfs_buf-Einträge, die unter dieser Überschrift angezeigt werden? Ich bin mir nicht sicher, wie das funktioniert:

/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/

Ich weiß immer noch nicht, warum diese von den 'drop_slabs' gelöscht werden oder wie man herausfindet, was diese Fragmentierung verursacht.

Bonusfrage: Wie gelangt man besser zur Quelle dieser Fragmentierung?

Wenn Sie so weit gelesen haben, vielen Dank für Ihre Aufmerksamkeit!

Zusätzliche angeforderte Informationen:

Speicher und XFS-Informationen: https://gist.github.com/christian-marie/f417cc3134544544a8d1

Fehler bei der Seitenzuordnung : https://gist.github.com/christian-marie/7bc845d2da7847534104

Follow-up: Perfekte Informationen und Verdichtung

http://ponies.io/raw/compaction.png

Verdichtungscode scheint ein wenig ineffizient, oder? Ich habe Code zusammengefügt, um zu versuchen, die fehlgeschlagenen Komprimierungen zu replizieren: https://gist.github.com/christian-marie/cde7e80c5edb889da541

Dies scheint das Problem zu reproduzieren.

Ich werde auch bemerken, dass eine Ereignisablaufverfolgung mir sagt, dass es immer und immer wieder viele fehlgeschlagene Rückforderungen gibt:

<...>-322 [023] .... 19509.445609: mm_vmscan_direct_reclaim_end: nr_reclaimed=1

Vmstat Ausgabe betrifft auch. Während sich das System in diesem Hochlastzustand befindet, gehen die Verdichtungen durch das Dach (und fallen meistens aus):

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

Rückgewinnung / Verdichtung hat in der Tat etwas Falsches.

Im Moment bin ich bestrebt, die Zuweisung von hohen Aufträgen zu reduzieren, indem ich SG-Unterstützung zu unserem ipoib-Setup hinzufüge. Das eigentliche Problem scheint wahrscheinlich mit vmscan zu zusammenhängen.

Dies ist interessant und verweist auf diese Frage: http://marc.info/?l=linux-mm&m=141607142529562&w=2

pingu
quelle
2
Mist ja !! Wir bekommen nicht viele dieser guten Fragen. Ich werde sehen, was wir tun können.
ewwhite
1
Können Sie die Ausgabe /proc/buddyinfound die Ergebnisse von bereitstellen free -m? Die blockdev-Anforderungen werden wahrscheinlich als Puffer in dargestellt free. Oh, und die Distribution, die Sie benutzen, wäre auch gut. Haben Sie auch page allocation failureNachrichten in dmesg? Wenn ja, geben Sie bitte die Ausgabe sowie den relevanten Kontext an.
Matthew Ife
1
Haben Sie auch eine bestimmte mkfs.xfsBefehlszeile verwendet? Riesenseiten aktiviert?
ewwhite
Auch die Ausgabe von/proc/meminfo
Matthew Ife
Es wurde versucht, transparente Riesen-Seiten selbst zu deaktivieren (auf "Niemals" zu setzen), aber es trat immer noch ein Fehler auf. Habe das nicht in Verbindung mit anderen 'Fixes' ausprobiert.
Pingu

Antworten:

4

Ich dachte, ich würde mit meinen Beobachtungen eine Antwort geben, weil es viele Kommentare gibt.

Basierend auf Ihrer Ausgabe unter https://gist.github.com/christian-marie/7bc845d2da7847534104

Wir können Folgendes feststellen:

  1. Die GFP_MASK für die versuchte Speicherzuweisung darf Folgendes tun.
    • Kann auf Notfallpools zugreifen (ich denke, dies bedeutet, dass auf Daten unterhalb des hohen Wasserzeichens für eine Zone zugegriffen werden kann)
    • Verwenden Sie keine Notfallreserven (ich denke, dies bedeutet, dass Sie keinen Zugriff auf Memo unterhalb des Mindestwasserzeichens zulassen)
    • Ordnen Sie aus einer der normalen Zonen.
    • Kann tauschen, um Platz zu schaffen.
    • Kann Caches ablegen, um Platz zu schaffen.

Die Zonenfragmentierung befindet sich hier:

[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

Und Speicherauslastung zu der Zeit ist hier:

[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

Die Fragmentierung jeder Zone ist in der Ausgabe für den Fehler bei der Seitenzuweisung schlecht. Es gibt viele freie Seiten mit einer Bestellung von 0 Seiten mit viel weniger bis gar keinen Seiten mit einer höheren Bestellung. Ein "gutes" Ergebnis sind reichlich freie Seiten in jeder Bestellung, deren Größe mit zunehmender Bestellung allmählich abnimmt. Wenn die Seiten 5 und höher von hoher Ordnung 0 sind, bedeutet dies Fragmentierung und Verhungern für Zuordnungen hoher Ordnung.

Ich sehe derzeit keine überzeugenden Beweise dafür, dass die Fragmentierung in dieser Zeit etwas mit Slab-Caches zu tun hat. In den resultierenden Speicherstatistiken sehen wir Folgendes

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

Es werden keine riesigen Seiten aus dem Benutzerbereich zugewiesen, und der Benutzerbereich beansprucht daher immer den Speicher der Reihenfolge 0. Somit sind in beiden Zonen insgesamt über 22 GB defragmentierbarer Speicher vorhanden.

Verhaltensweisen, die ich nicht erklären kann

Wenn Zuweisungen höherer Ordnung fehlschlagen, wird meines Wissens nach immer eine Speicherkompaktierung versucht, um zu ermöglichen, dass Bereiche mit Speicherzuweisungen höherer Ordnung stattfinden und erfolgreich sind. Warum passiert das nicht? Wenn es doch passiert, warum kann es dann keinen Speicher finden, der defragmentiert werden kann, wenn 22 GB für eine Neuordnung reif sind?

Verhalten, von dem ich glaube, dass ich es erklären kann

Dies erfordert weitere Nachforschungen, um es richtig zu verstehen, aber ich glaube, dass die Fähigkeit zur automatischen Auslagerung von Seiten-Caches, um erfolgreich zu sein, hier wahrscheinlich nicht zutrifft, da noch viel freier Speicher verfügbar ist und daher keine Rückforderungen erfolgen. Nur nicht genug in den höheren Ordnungen.

Während in jeder Zone noch viel freier Speicherplatz und ein paar Anforderungen für die Bestellung 4 vorhanden sind, führt das Problem "Gesamter freier Speicherplatz für jede Bestellung und Abzug vom tatsächlichen freien Speicherplatz" zu einem "freien Speicherplatz" unter dem "minimalen" Wasserzeichen was zu dem tatsächlichen Zuordnungsfehler führt.

Matthew Ife
quelle
Es scheint seltsam, dass ein relativ (zum gesamten freien Speicher) kleiner SLAB-Cache alle Speicher fragmentieren würde. Ich hätte erwartet, dass es bei all diesen frei entfernbaren Seiten einfach einige davon entfernt und damit fertig ist. Ich vermute, dass NUMA etwas mit dieser Kuriosität zu tun haben könnte.
Pingu
Ist numadläuft auf diesem System?
Ewwhite
@ newwhite numad läuft nicht, nein.
Pingu
@pingu Wenn dieses Verhalten reproduzierbar ist, versuchen Sie, den numadDienst zu aktivieren , und notieren Sie sich die Aktionen in /var/log/numad.log. Möglicherweise muss auch libcgroup installiert sein.
ewwhite
@ewwhite Okay, ich habe jetzt eine am laufen. Ich bin mir nicht sicher, was ich davon erwarte oder welche Informationen wir daraus erhalten könnten. Was hoffen Sie, könnte passieren?
Pingu