Распределение памяти слишком медленное - PullRequest
0 голосов
/ 27 марта 2019

Я использую сервис с интенсивным использованием памяти в AWS (m4.15xlarge и m5.12xlarge) и заметил, что в определенных условиях (обычно после определенного предела памяти) время, необходимое для выделения дополнительной памяти, резко увеличивается (до 50 раз)

Когда это происходит htop показывает 100% в режиме ядра (красный) и perf top выглядит так:

  62.82%  [kernel]                                           [k] pageblock_pfn_to_page                                                              
  15.21%  [kernel]                                           [k] clear_page_c_e                                                                     
   5.78%  [kernel]                                           [k] get_pfnblock_flags_mask                                                            
   3.06%  [kernel]                                           [k] compaction_alloc                                                                   
   1.59%  [kernel]                                           [k] clear_huge_page                                                                    
   1.49%  [kernel]                                           [k] _raw_spin_lock                                                                     
   1.41%  [kernel]                                           [k] async_page_fault                                                                   
   1.29%  a.out                                              [.] memTest                                                                            
   0.99%  [kernel]                                           [k] get_page_from_freelist                                                             
   0.85%  [kernel]                                           [k] compact_zone                                                                       
   0.69%  [kernel]                                           [k] try_charge                                                                         
   0.51%  [kernel]                                           [k] error_entry                                                                        
...

При нормальной работе это выглядит так:

  66.29%  [kernel]                                           [k] clear_page_c_e
   7.05%  [kernel]                                           [k] clear_huge_page
   3.91%  a.out                                              [.] memTest
   3.66%  [kernel]                                           [k] _raw_spin_lock
   3.12%  [kernel]                                           [k] async_page_fault
   2.68%  [kernel]                                           [k] get_page_from_freelist
   1.93%  [kernel]                                           [k] _cond_resched
   1.49%  [kernel]                                           [k] try_charge
   1.12%  [kernel]                                           [k] error_entry
   1.01%  [kernel]                                           [k] retint_user
   0.93%  [kernel]                                           [k] handle_mm_fault
   0.77%  [kernel]                                           [k] mem_cgroup_try_charge
   0.67%  [kernel]                                           [k] pmd_pfn
   0.66%  [kernel]                                           [k] __rmqueue.isra.80
...

Я не совсем понимаю, что вызывает поведение. Иногда это довольно сложно воспроизвести, но иногда это происходит постоянно.

У меня есть гипотеза, что это связано с виртуализацией AWS (поэтому тот факт, что проблема носит прерывистый характер, я приписываю тому, что происходит с "соседями") (см. Обновление ниже). Я также не смог воспроизвести проблему на m5.metal машине.

Мне удалось воспроизвести проблему с помощью простой программы на C, которая выделяет и инициализирует память в цикле:

void memTest(long chunk, long total) {
    struct timeval prev, cur = {0,0}, lastProgress = {0,0};
    int i, j;
    int num = total / chunk;
    int p, progress = -1;
    uint8_t *data[num];

    get_now(&prev);

    for (i = 0; i < num; i++) {
        data[i] = malloc(chunk);
        for (j = 0; j < chunk; j += 4096) {
            data[i][j] = rand()%265;
        }

        get_now(&cur);
        add(delta(&prev, &cur));
        prev = cur;

        p = (i * 20) / num * 5;

        if (p != progress) {
            if (lastProgress.tv_sec == 0) {
                printf("%s: %02d%%\n", format(&cur), p);
            } else {
                double elapsed = delta(&lastProgress, &cur);
                printf("%s: %02d%% (%gms)\n", format(&cur), p, elapsed);
            }
            lastProgress = cur;
            progress = p;
        }
    }
}
m5.12xlarge$ ./a.out --total 182714368000 --chunk 16777216
2019-03-27 05:03:22.805827: 00%
2019-03-27 05:03:25.035575: 05% (2229.75ms)
2019-03-27 05:03:27.244955: 10% (2209.38ms)
2019-03-27 05:03:29.458160: 15% (2213.2ms)
2019-03-27 05:03:31.665313: 20% (2207.15ms)
2019-03-27 05:03:33.871949: 25% (2206.64ms)
2019-03-27 05:03:36.075955: 30% (2204.01ms)
2019-03-27 05:03:38.284512: 35% (2208.56ms)
2019-03-27 05:03:40.489039: 40% (2204.53ms)
2019-03-27 05:03:42.697444: 45% (2208.41ms)
2019-03-27 05:03:44.902268: 50% (2204.82ms)
2019-03-27 05:03:47.110703: 55% (2208.43ms)
2019-03-27 05:03:49.315001: 60% (2204.3ms)
2019-03-27 05:03:51.523370: 65% (2208.37ms)
2019-03-27 05:03:53.728535: 70% (2205.16ms)
2019-03-27 05:03:55.936081: 75% (2207.55ms)
2019-03-27 05:03:58.141149: 80% (2205.07ms)
2019-03-27 05:04:00.349740: 85% (2208.59ms)
2019-03-27 05:04:02.553894: 90% (2204.15ms)
2019-03-27 05:04:04.762675: 95% (2208.78ms)
2019-03-27 05:04:41.470692: 100% (36708ms) .  <---

На этот раз мне удалось решить проблему только до предела памяти, но я смог получить ее даже на 20 ГБ (из 186 ГБ доступно).

Я был бы очень признателен, если бы кто-то смог пролить свет на то, что происходит и как избавиться от этого эффекта.

Обновление:

Я немного поиграл с этой проблемой и в настоящее время обвиняю Transparent Hugepage Support (THP), которая включена (always) на m5.12xlarge и отключена (madvise) на m5.metal. После переключения настроек на машинах я смог получить проблему на m5.metal и проблема ушла на m5.12xlarge.

1 Ответ

3 голосов
/ 27 марта 2019

Как предлагается в разделе Обновление , проблема, похоже, вызвана поддержкой прозрачной огромной страницы ( THP ). MongoDB и некоторыми другими ссылка , ссылка уже была обнаружена и рекомендована для отключения.

Существует множество вопросов о том, как отключить THP для stackoverflow и stackexchange. Например:

...