Curl медленная многопоточность днс
Программа сделана на C++ и индексирует веб-страницы, поэтому все домены являются случайными доменными именами из Интернета. Странная часть в том, что днс fail
/not found
процент невелик (>5%).
вот трассировка стека pmp:
3886 __GI___poll,send_dg,buf=0xADDRESS,__libc_res_nquery,__libc_res_nquerydomain,__libc_res_nsearch,_nss_dns_gethostbyname3_r,gaih_inet,__GI_getaddrinfo,Curl_getaddrinfo_ex
601 __GI___poll,Curl_socket_check,waitconnect,singleipconnect,Curl_connecthost,ConnectPlease,protocol_done=protocol_done@entry=0xADDRESS),Curl_connect,connect_host,at
534 __GI___poll,Curl_socket_check,Transfer,at,getweb,athread,start_thread,clone,??
498 nanosleep,__sleep,athread,start_thread,clone,??
50 __GI___poll,Curl_socket_check,Transfer,at,getweb,getweb,athread,start_thread,clone,??
15 __GI___poll,Curl_socket_check,Transfer,at,getweb,getweb,getweb,athread,start_thread,clone
7 nanosleep,usleep,main
Почему так много тем в _nss_dns_gethostbyname3_r
? Что я мог сделать, чтобы ускорить это.
Может быть потому, что я использую по умолчанию curl синхронный DNS-преобразователь с CURLOPT_NOSIGNAL
?
Программа работает на Intel I7 (8 ядер HT), 16 ГБ оперативной памяти, Ububtu 12.10.
Пропускная способность варьируется от 6 МБ / с (предел ISP) -> 2 МБ / с с нерегулярным интервалом, а иногда даже падает до нескольких 100 КБ / с.
2 ответа
Я обнаружил, что решение было изменить преобразователь curl dns по умолчанию на c-ares
и специально просить ipv4
как ipv6
моя сеть еще не поддерживается.
Изменение на c-ares
также позволил мне добавить больше наборов DNS-серверов и обвести их, чтобы увеличить количество DNS-запросов / с.
Исход:
//set to ipv4 only
curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
//cicle dns Servers
dns_index=DNS_SERVER_I;
pthread_mutex_lock(&running_mutex);
if(DNS_SERVER_I>DNS_SERVERS.size())
{
DNS_SERVER_I=1;
}else
{
DNS_SERVER_I++;
}
pthread_mutex_unlock(&running_mutex);
string dns_servers_string=DNS_SERVERS.at(dns_index%DNS_SERVERS.size())+","+DNS_SERVERS.at((dns_index+1)%DNS_SERVERS.size())+","+DNS_SERVERS.at((dns_index+2)%DNS_SERVERS.size());
// set curl DNS (option available only when curl is built with c-ares)
curl_easy_setopt(curl, CURLOPT_DNS_SERVERS, &dns_servers_string[0]);
Потоки, которые вы видите, вероятно, ожидают ответов DNS. Одним из способов ускорить этот процесс является предварительный поиск, чтобы они кэшировались на рекурсивном DNS-сервере вашего соседа. Также убедитесь, что никто не спрашивает об авторитетных ответах, это всегда медленно.