Назад | Перейти на главную страницу

DNS-кеш чрезмерное использование памяти Windows Server 2008 R2

У нас возникла проблема со службой dnscache, из-за которой использование памяти становится чрезмерным (~ 6 ГБ) через неделю или две.

Перезапуск службы освобождает эту память, но выполнение ipconfig / flushdns этого не делает, ipconfig / displaydns показывает примерно 15-20 записей в кеше.

Мы проверили, и, похоже, происходит около 150 DNS-запросов в секунду, но я не ожидал, что это вызовет проблему с памятью.

Я попытался найти в MSDN исправления или отчеты об ошибках, но смог найти только ссылку на утечку памяти в Windows 2003. Кто-нибудь может подсказать, что делать дальше.

Учитывая, что вы уже искали исправления, я полагаю, на вашем сервере уже установлена ​​последняя версия пакета обновления Windows и все обновления? Это всегда лучшее место для начала.

При размере кэша 6 ГБ мы говорим о десятках миллионов уникальных результатов DNS (что абсурдно). Маловероятно, что ваши клиенты будут делать так много уникальных DNS-запросов. В комментариях к вашему вопросу вы указали, что приложение выполняет поиск каждый раз, когда клиент отправляет данные на сервер. Я не знаю, как работает приложение (я предполагаю, веб-приложение) на вашем сервере, но мне интересно, создает ли какое-то событие уникальные DNS-запросы с каждым клиентским запросом, запросы, которые возвращаются как несуществующие домены. Я полагаю, что если DNS-запрос попадает в домен с подстановочным знаком, они могут возвращать действительные ответы. В любом случае это может объяснить огромный размер кеша.

Ipconfig / displaydns не всегда возвращает весь кеш, что объясняет, почему вы видите только 15-20 записей.

Вы можете (по крайней мере, я могу) подтвердить это, выполнив следующие действия…

В командной строке Powershell:

> ipconfig /flushdns
> [System.Net.Dns]::GetHostAddresses(“google.com”)

Проверьте кеш DNS

> ipconfig /displaydns

Вероятно, вы увидите запись Google.com. Обратите внимание на размер кеша с помощью диспетчера задач (в диспетчере задач найдите службу dnscache, щелкните ее правой кнопкой мыши и выберите перейти к процессу).

Теперь выполните следующую команду, где ### - большое число (я использовал 10 000). Обратите внимание: я настроил свой локальный DNS-сервер так, чтобы он отвечал на все субдомены .test с помощью подстановочного знака, поэтому я не попадал на DNS-сервер своего интернет-провайдера 10 000 раз за короткий период времени.

> $i = 0
> do {[System.Net.Dns]::GetHostAddresses(“blahblahfakedomain” + $i++ + “.test”)} while ($i –lt ###)

По мере выполнения команды следите за ростом использования памяти процессом кеширования в диспетчере задач. Как только он завершится, проверьте кеш. Вы, вероятно, не увидите только что сгенерированные ### запросы, но процессы кэша DNS не освободили память.

В своих экспериментах мне удалось восстановить память, очистив кеш DNS (10 000 запросов - это около 2 мегабайт). Я не знаю, почему у тебя это не работает. Может быть, потому что кеш чертовски большой…?

В любом случае, я предлагаю следующий обходной путь:

Измените MaxCacheTtl и MaxNegativeCacheTtl значения реестра в HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Dnscache \ Parameters ключ на (http://support.microsoft.com/kb/318803):

Измените или создайте значение DWord MaxCacheTtl, установив его на что-то низкое, например, 3600 секунд (0xE10 в шестнадцатеричном формате). Все значения указаны в секундах. По умолчанию - 1 день (86 400 секунд).

Измените или создайте значение DWord MaxNegativeCacheTtl, установив его в 0.

Это приведет к тому, что все записи будут удалены из кеша максимум через час после их добавления. Отрицательные результаты (несуществующие домены) вообще не будут сохраняться в кеше (я подтвердил это на своем рабочем столе Windows 7).

Я называю это обходным путем, потому что я бы сказал, что проблема заключается в том, какой процесс создает абсурдное количество запросов. Если есть возможность, попробуйте погасить поток запросов от источника.

Существует много дискуссий об использовании высокой памяти DNS в Windows 2008 R2. Многие из них указывают на отключение EDNS, что не снижает использование памяти. Реальная проблема на самом деле связана с портами, которые открывает DNS: 2500 UDP IPv4 и 2500 UDP IPv6. Это хорошее и круглое число для загруженного производственного DNS-сервера, однако для внутреннего DNS в небольшом офисе это слишком много.

Чтобы уменьшить количество открытых портов, выполните следующую команду. Для внутреннего DNS, когда в офисе работает около 20 человек, 100 портов более чем достаточно:

Dnscmd /Config /SocketPoolSize 100

После выполнения команды перезапустите службу DNS; потребление памяти должно уменьшиться.

Вы также можете посмотреть, сколько портов у вас открыто:

Dnscmd /Info /SocketPoolSize

Мы запустили захват Wireshark, чтобы увидеть, какие DNS-запросы выполняются, и оказалось, что когда каждый клиент отправляет данные на сервер, он подключается к серверу MSSQL на другом компьютере и выполняет DNS-запрос, чтобы получить IP-адрес этого SQL-сервер.

В качестве временного решения мы настроили сервер приложений с IP-адресом SQL-серверов, поэтому серверу приложений не нужно запрашивать кеш DNS.

Однако по-прежнему остается вопрос, почему то, что кажется обычными DNS-запросами, вызывает такое использование памяти в кэше DNS.

Я включил сюда след проволочной акулы, чтобы люди могли помочь диагностировать проблему.

Не уверен, что это слишком поздно, но я наткнулся на это, исследуя совершенно другую проблему - я думаю, что причиной проблемы был домен .uk.

Они продолжают описывать, что простое исправление regkey решит эту проблему.

http://support.microsoft.com/kb/968372

Когда разрешение имен обеспечивается корневыми подсказками, DNS-серверы Windows Server 2008 и Windows Server 2008 R2 могут не разрешать запросы для имен в определенных доменах верхнего уровня. В этом случае проблема будет продолжаться до тех пор, пока кэш DNS-сервера не будет очищен или служба DNS-сервера не будет перезапущена. Проблема проявляется в таких доменах, как .co.uk, .cn и .br, но не ограничивается этими доменами.

Когда проблема возникает, команда nslookup, выданная для затронутого имени, вернет ошибку «сбой сервера». Сетевая трассировка покажет, что DNS-сервер не отправляет трафик для такого запроса в Интернет. В журнале событий DNS не регистрируются события, связанные с проблемой.

Эта проблема не возникает, если DNS-сервер настроен на использование серверов пересылки для разрешения имен в Интернете вместо корневых ссылок.