Различное поведение кеша страниц в Linux для серверов, выполняющих ту же работу

У меня есть два набора серверов с памятью 128G, которые различаются по времени подготовки, которые ведут себя по-разному при запуске одного и того же демона (elasticsearch). Я использую elasticsearch для полнотекстового поиска, а не для хранения журналов, поэтому это обычно тяжелая операция чтения с минимальными записями (менее 1 МБ / с). Этот демон mmap помещает полный набор данных размером ~ 350 ГБ в свою виртуальную память, а затем обращается к определенным его частям для обслуживания запросов. На этих серверах не настроено пространство подкачки.

Проблема в том, что один набор серверов ведет себя хорошо, выдает ~ 50 основных ошибок в секунду и требует в среднем 10 МБ / с дискового ввода-вывода для удовлетворения этой потребности. Плохо работающие серверы видят 500 основных ошибок в секунду, и для этого требуется в среднем ~ 200 МБ / с диска io. Увеличение дискового ввода-вывода приводит к низкой задержке ответа p95 и случайным перегрузкам, поскольку он достигает дисковых ограничений ~ 550 МБ / с.

Все они находятся за одним и тем же балансировщиком нагрузки и являются частью одного кластера. Я мог видеть, если один сервер ведет себя плохо, это могут быть различия в нагрузке, но чтобы иметь такое четкое различие, когда 16 серверов ведут себя плохо, а 20 серверов ведут себя хорошо, при этом что-то в ядре / уровень конфигурации должен вызывать проблемы.

Чтобы перейти к вопросу, как я могу заставить эти плохо работающие серверы вести себя как хорошо работающие? На чем следует сосредоточить усилия по отладке?

Ниже приведены некоторые данные, которые я собрал, чтобы посмотреть, что делает система с помощью инструментов sar и page-types в каждом из три состояния.

Программное обеспечение: - дебиан Джесси - Linux 4.9.25 - elasticsearch 5.3.2 - openjdk 1.8.0_141

Сначала некоторые данные о сбоях страницы с хорошо настроенного сервера (из sar -B ):

07:55:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
08:05:01 PM   3105.89    811.60   2084.40     48.16   3385.30      0.00      0.00    810.35      0.00
08:15:01 PM   4317.65    665.28    910.29     57.03   3160.14      0.00      0.00   1047.14      0.00
08:25:01 PM   3132.84    648.48    868.41     50.00   2899.14      0.00      0.00    801.27      0.00
08:35:01 PM   2940.02   1026.47   2031.69     45.26   3418.65      0.00      0.00    764.05      0.00
08:45:01 PM   2985.72   1011.27    744.34     45.78   2796.54      0.00      0.00    817.23      0.00
08:55:01 PM   2970.14    588.34    858.08     47.65   2852.33      0.00      0.00    749.17      0.00
09:05:01 PM   3489.23   2364.78   2121.48     47.13   3945.93      0.00      0.00   1145.02      0.00
09:15:01 PM   2695.48    594.57    858.56     44.57   2616.84      0.00      0.00    624.13      0.00

И вот один из плохо работающих серверов:

07:55:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
08:05:01 PM 268547.64   1223.73   5266.73    503.12  71836.18      0.00      0.00  67170.50      0.00
08:15:01 PM 279865.31    944.04   3995.52    520.17  74231.90      0.00      0.00  70000.23      0.00
08:25:01 PM 265806.75    966.55   3747.43    499.45  70443.49      0.00      0.00  66407.62      0.00
08:35:01 PM 251820.93   1831.04   4689.62    475.43  67445.29      0.00      0.00  63056.35      0.00
08:45:01 PM 236055.04   1022.32   3498.37    449.37  62955.37      0.00      0.00  59042.16      0.00
08:55:01 PM 239478.40    971.98   3523.61    451.76  63856.04      0.00      0.00  59953.38      0.00
09:05:01 PM 232213.81   1058.04   4436.75    437.09  62194.61      0.00      0.00  58100.47      0.00
09:15:01 PM 216433.72    911.94   3192.28    413.23  57737.62      0.00      0.00  54126.78      0.00

Я подозреваю, что это происходит из-за плохой производительности LRU-части восстановления страницы. Если я запускаю пока true; сделать echo 1> / proc / sys / vm / drop_caches; спать 30; done , который отбрасывает все страницы без mmaped, будет начальный всплеск диска io, но примерно через 30 минут он уляжется. Я запускал это в течение ~ 48 часов на всех серверах, чтобы убедиться, что он покажет одинаковое сокращение ввода-вывода как при пиковой дневной нагрузке, так и при низких значениях. Это было так. Теперь Sar сообщает следующее:

12:55:01 PM  pgpgin/s pgpgout/s   fault/s  majflt/s  pgfree/s pgscank/s pgscand/s pgsteal/s    %vmeff
01:05:01 PM 121327.14   1482.09   2277.40    140.25  32781.26      0.00      0.00   1764.61      0.00
01:15:01 PM 109911.39   1334.51   1057.51    130.53  31095.68      0.00      0.00   1121.39      0.00
01:25:01 PM 126500.69   1652.51   1216.76    143.07  35830.38      0.00      0.00   2801.84      0.00
01:35:01 PM 132669.45   1857.62   2309.86    148.47  36735.79      0.00      0.00   3181.19      0.00
01:45:01 PM 126872.04   1451.94   1062.94    145.68  34678.26      0.00      0.00    992.60      0.00
01:55:01 PM 121002.21   1818.32   1142.16    139.40  34168.53      0.00      0.00   1640.18      0.00
02:05:01 PM 121824.18   1260.22   2319.56    142.80  33254.67      0.00      0.00   1738.25      0.00
02:15:02 PM 120768.12   1100.87   1143.36    140.20  34195.15      0.00      0.00   1702.83      0.00

Основные ошибки страниц были сокращены до 1/3 от предыдущего значения. Страницы, принесенные с диска, сократились вдвое. Это уменьшает ввод-вывод диска с ~ 200 МБ / с до ~ 100 МБ / с, но хорошо настроенный сервер по-прежнему значительно превосходит их всех: всего 50 основных ошибок в секунду, и ему нужно делать только ~ 10 МБ / с диска io.

Чтобы понять, что должен работать алгоритм LRU, я использую инструмент типов страниц из ядра. Это хорошо работающий сервер (из page-types | awk '$ 3> 1000 {print $ 0}' | sort -nk3 ):

             flags      page-count       MB  symbolic-flags                     long-symbolic-flags
0x0000000000000828          257715     1006  ___U_l_____M______________________________ uptodate,lru,mmap
0x0000000000000080          259789     1014  _______S__________________________________ slab
0x000000000000006c          279344     1091  __RU_lA___________________________________ referenced,uptodate,lru,active
0x0000000000000268          305744     1194  ___U_lA__I________________________________ uptodate,lru,active,reclaim
0x0000000000100000          524288     2048  ____________________n_____________________ nopage
0x000000000000082c          632704     2471  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
0x0000000000000000          763312     2981  __________________________________________
0x0000000000000068         2108618     8236  ___U_lA___________________________________ uptodate,lru,active
0x000000000000086c         6987343    27294  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
0x0000000000005868         8589411    33552  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x0000000000000868        12513737    48881  ___U_lA____M______________________________ uptodate,lru,active,mmap
             total        34078720   133120

Это плохо работающий сервер:

             flags      page-count       MB  symbolic-flags                     long-symbolic-flags
0x0000000000100000          262144     1024  ____________________n_____________________ nopage
0x0000000000000828          340276     1329  ___U_l_____M______________________________ uptodate,lru,mmap
0x000000000000086c          515691     2014  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
0x0000000000000028          687263     2684  ___U_l____________________________________ uptodate,lru
0x0000000000000000          785662     3068  __________________________________________
0x0000000000000868         7946840    31042  ___U_lA____M______________________________ uptodate,lru,active,mmap
0x0000000000005868         8588629    33549  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x0000000000000068        14133541    55209  ___U_lA___________________________________ uptodate,lru,active
             total        33816576   132096

И вот что это выглядит так при выполнении команды drop_caches:

             flags      page-count       MB  symbolic-flags                     long-symbolic-flags
0x0000000000100000          262144     1024  ____________________n_____________________ nopage
0x0000000000000400          394790     1542  __________B_______________________________ buddy
0x0000000000000000          761557     2974  __________________________________________
0x0000000000000868         1451890     5671  ___U_lA____M______________________________ uptodate,lru,active,mmap
0x000000000000082c         3123142    12199  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
0x0000000000000828         5278755    20620  ___U_l_____M______________________________ uptodate,lru,mmap
0x0000000000005868         8622864    33683  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
0x000000000000086c        13630124    53242  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
             total        33816576   132096

Что пробовали:

  • увеличить / proc / sys / vm / vfs_cache_pressure до различных значений между 1000 {print $ 0} '| sort -nk3 ):

                 flags      page-count       MB  symbolic-flags                     long-symbolic-flags
    0x0000000000000828          257715     1006  ___U_l_____M______________________________ uptodate,lru,mmap
    0x0000000000000080          259789     1014  _______S__________________________________ slab
    0x000000000000006c          279344     1091  __RU_lA___________________________________ referenced,uptodate,lru,active
    0x0000000000000268          305744     1194  ___U_lA__I________________________________ uptodate,lru,active,reclaim
    0x0000000000100000          524288     2048  ____________________n_____________________ nopage
    0x000000000000082c          632704     2471  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
    0x0000000000000000          763312     2981  __________________________________________
    0x0000000000000068         2108618     8236  ___U_lA___________________________________ uptodate,lru,active
    0x000000000000086c         6987343    27294  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
    0x0000000000005868         8589411    33552  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
    0x0000000000000868        12513737    48881  ___U_lA____M______________________________ uptodate,lru,active,mmap
                 total        34078720   133120
    

    Это плохо работающий сервер:

                 flags      page-count       MB  symbolic-flags                     long-symbolic-flags
    0x0000000000100000          262144     1024  ____________________n_____________________ nopage
    0x0000000000000828          340276     1329  ___U_l_____M______________________________ uptodate,lru,mmap
    0x000000000000086c          515691     2014  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
    0x0000000000000028          687263     2684  ___U_l____________________________________ uptodate,lru
    0x0000000000000000          785662     3068  __________________________________________
    0x0000000000000868         7946840    31042  ___U_lA____M______________________________ uptodate,lru,active,mmap
    0x0000000000005868         8588629    33549  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
    0x0000000000000068        14133541    55209  ___U_lA___________________________________ uptodate,lru,active
                 total        33816576   132096
    

    И вот как это выглядит при выполнении команды drop_caches в цикле:

                 flags      page-count       MB  symbolic-flags                     long-symbolic-flags
    0x0000000000100000          262144     1024  ____________________n_____________________ nopage
    0x0000000000000400          394790     1542  __________B_______________________________ buddy
    0x0000000000000000          761557     2974  __________________________________________
    0x0000000000000868         1451890     5671  ___U_lA____M______________________________ uptodate,lru,active,mmap
    0x000000000000082c         3123142    12199  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
    0x0000000000000828         5278755    20620  ___U_l_____M______________________________ uptodate,lru,mmap
    0x0000000000005868         8622864    33683  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
    0x000000000000086c        13630124    53242  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
                 total        33816576   132096
    

    Что пробовали:

    • увеличить / proc / sys / vm / vfs_cache_pressure на различные значения между 1000 {print $ 0} '| sort -nk3 ):

                   flags      page-count       MB  symbolic-flags                     long-symbolic-flags
      0x0000000000000828          257715     1006  ___U_l_____M______________________________ uptodate,lru,mmap
      0x0000000000000080          259789     1014  _______S__________________________________ slab
      0x000000000000006c          279344     1091  __RU_lA___________________________________ referenced,uptodate,lru,active
      0x0000000000000268          305744     1194  ___U_lA__I________________________________ uptodate,lru,active,reclaim
      0x0000000000100000          524288     2048  ____________________n_____________________ nopage
      0x000000000000082c          632704     2471  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
      0x0000000000000000          763312     2981  __________________________________________
      0x0000000000000068         2108618     8236  ___U_lA___________________________________ uptodate,lru,active
      0x000000000000086c         6987343    27294  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
      0x0000000000005868         8589411    33552  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
      0x0000000000000868        12513737    48881  ___U_lA____M______________________________ uptodate,lru,active,mmap
                   total        34078720   133120
      

      Это плохо работающий сервер:

                   flags      page-count       MB  symbolic-flags                     long-symbolic-flags
      0x0000000000100000          262144     1024  ____________________n_____________________ nopage
      0x0000000000000828          340276     1329  ___U_l_____M______________________________ uptodate,lru,mmap
      0x000000000000086c          515691     2014  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
      0x0000000000000028          687263     2684  ___U_l____________________________________ uptodate,lru
      0x0000000000000000          785662     3068  __________________________________________
      0x0000000000000868         7946840    31042  ___U_lA____M______________________________ uptodate,lru,active,mmap
      0x0000000000005868         8588629    33549  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
      0x0000000000000068        14133541    55209  ___U_lA___________________________________ uptodate,lru,active
                   total        33816576   132096
      

      И вот как это выглядит при выполнении команды drop_caches в цикле:

                   flags      page-count       MB  symbolic-flags                     long-symbolic-flags
      0x0000000000100000          262144     1024  ____________________n_____________________ nopage
      0x0000000000000400          394790     1542  __________B_______________________________ buddy
      0x0000000000000000          761557     2974  __________________________________________
      0x0000000000000868         1451890     5671  ___U_lA____M______________________________ uptodate,lru,active,mmap
      0x000000000000082c         3123142    12199  __RU_l_____M______________________________ referenced,uptodate,lru,mmap
      0x0000000000000828         5278755    20620  ___U_l_____M______________________________ uptodate,lru,mmap
      0x0000000000005868         8622864    33683  ___U_lA____Ma_b___________________________ uptodate,lru,active,mmap,anonymous,swapbacked
      0x000000000000086c        13630124    53242  __RU_lA____M______________________________ referenced,uptodate,lru,active,mmap
                   total        33816576   132096
      

      Что пробовали:

      • увеличить / proc / sys / vm / vfs_cache_pressure на различные значения между 150 и 10000. Это не влияет на ввод-вывод или данные, сообщаемые page-types , что имеет смысл, потому что это уравновешивает ядро структуры и пользовательские страницы, и моя проблема в том, что разные пользовательские страницы
      • увеличивают / proc / sys / vm / swappiness. Не ожидал, что это что-то сделает, и это не так, но проверить не повредило.
      • Отключите mmap (вместо этого используйте java nio, основанный на epoll). Это сразу же делает использование ввода-вывода сервером таким же, как и хорошо работающие с точки зрения использования ввода-вывода. Обратной стороной здесь является то, что% ЦП системы привязан к тому, сколько происходит операций ввода-вывода, при этом 10 МБ / с занимают ~ 1,5%, а периодическая загрузка до ~ 100 МБ / с% disk io saw system cpu% от 5 до 10%. На 32-ядерном сервере от 1,5 до 3 ЦП полностью используются для обработки epoll. Задержка также была хуже с nio (по сравнению с хорошо работающими серверами mmap). Это правдоподобное решение, но это отговорка, без понимания того, что на самом деле идет не так.
      • бесчисленное количество часов с инструментом perf , который копается в трассировках стека, графиках пламени и ищет различия в поведении ядра.
      • Проверенные параметры упреждающего чтения на всех серверах одинаковы. raid0 на плохо работающих серверах по умолчанию установлено 2048 блоков, на хорошо работающих серверах raid0 по умолчанию установлено 256 блоков. Обновление неэффективных серверов до 256 с помощью blockdev --setra не влияет на поведение ввода-вывода.
      • Запустите jvm с помощью numactl --interleave = all , чтобы убедиться, что проблема не возникает. связанных с балансировкой между двумя узлами numa. Никакой разницы.
      • проверено с помощью vmtouch , который в основном использует mincore (2) , чтобы запросить ядро, кэшируются ли файлы, что 99% + буферизованной памяти используется для файловой системы, в которой elasticsearch хранит свои данные. Это верно во всех трех приведенных выше случаях.
      • проверено с помощью fuser -m , что elasticsearch - единственный процесс, использующий файлы в файловой системе, где elasticsearch хранит свои данные.

      Для тестирования в ближайшее время:

      • Я повторно инициализирую один из некорректно работающих серверов на следующей неделе, но я не думаю, что это будет иметь большой эффект. Во время этой подготовки я также обновляю массив рейдов, чтобы поставить перед ним LVM. Не ожидать чего-либо отличного от LVM, но удаление переменной кажется целесообразным.
5
задан 15 August 2017 в 20:20
1 ответ

Это привело к чрезмерно агрессивному упреждающему чтению диска. Хорошо работающие серверы имели упреждающее чтение 128 КБ. Плохо работающие серверы имели опережающее чтение 2 МБ. Не удалось отследить, почему именно упреждающее чтение было другим, но наиболее вероятная причина заключалась в том, что новые машины имели LVM перед программным рейдом, а старые машины напрямую общались с программным рейдом

. мой вопрос указывает на то, что я изначально проверял упреждающее чтение, заметил разницу и обновил его на одном из серверов, взаимодействие между mmap и упреждающим чтением не так просто. В частности, когда файл mmap'd, ядро ​​Linux копирует настройки упреждающего чтения с диска в структуру этого файла mmap. Обновление настроек упреждающего чтения не приведет к обновлению этой структуры. Из-за этого обновленное упреждающее чтение не вступает в силу до тех пор, пока демон, удерживающий открытые файлы, не будет перезапущен.

Уменьшение упреждающего чтения и перезапуск демонов на плохо работающих серверах немедленно привели к тому, что чтение с диска было встроено в колодец выполняя их, и немедленно уменьшили время ожидания ввода-вывода и задержку хвоста.

2
ответ дан 3 December 2019 в 01:56

Теги

Похожие вопросы