Несколько непонятностей по nginx

Александр Ворона voron at amhost.net
Fri Apr 13 13:10:17 MSD 2007


Igor Sysoev пишет:

> С неблокирующимся sendfile ситуация непонятна. Я впервые увидел, как
> Линукс за один неблокирующийся вызов передал 900M.

вызов должен был быть неблокирующимся - но он таким не был. nginx в это 
время естественно ничего кроме этого sendfile() не мог делать. Может 
стОит попробовать отдавать sendfile()'ом не до конца файла, а ровно 
столько, сколько влезет в буфер сокета, который перед каждым sendfile() 
и определять?

кстати попутно мелкая бага - при отдаче nginx'ом 0.5.17 файлов >2G 
(linux 2.6.20 и i386 sendfile64() и x86_64 sendfile() ) если за один 
sendfile[64](...,count) с  (2^31-1) > count > (2^31-page_size) уходит 
количество байт 2^31-page_size, то закачка замирает
strace

epoll_wait(11, {{EPOLLIN, {u32=1870331920, u64=53895119962128}}}, 512, 
4294967295) = 1
accept(8, {sa_family=AF_INET, sin_port=htons(51792), 
sin_addr=inet_addr("192.168.78.1")}, [5052830673564336144]) = 9
ioctl(9, FIONBIO, [1])                  = 0
epoll_ctl(11, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLET, {u32=1870332832, 
u64=53895119963040}}) = 0
epoll_wait(11, {{EPOLLIN, {u32=1870332832, u64=53895119963040}}}, 512, 
600000) = 1
recvfrom(9, "GET /3.tmp HTTP/1.0\r\nUser-Agent:"..., 1024, 0, NULL, 
NULL) = 147
open("/var/www/cacti/htdocs/3.tmp", O_RDONLY) = 12
fstat(12, {st_mode=S_IFREG|0644, st_size=4294967296, ...}) = 0
setsockopt(9, SOL_TCP, TCP_CORK, [1], 4) = 0
writev(9, [{"HTTP/1.1 200 OK\r\nServer: nginx/0"..., 262}], 1) = 262
sendfile(9, 12, [0], 2147479552)        = 20576
epoll_ctl(11, EPOLL_CTL_MOD, 9, {EPOLLIN|EPOLLOUT|EPOLLET, 
{u32=1870332832, u64=53895119963040}}) = 0
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
600000) = 1
sendfile(9, 12, [20576], 2147483552)    = 55568
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
599974) = 1
sendfile(9, 12, [76144], 2147481232)    = 20838
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
599974) = 1
sendfile(9, 12, [96982], 2147480874)    = 111136
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
599973) = 1
sendfile(9, 12, [208118], 2147480330)   = 388976
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
599972) = 1
sendfile(9, 12, [597094], 2147480474)   = 493166
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
599966) = 1
sendfile(9, 12, [1090260], 2147482924)  = 131612808
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
599954) = 1
sendfile(9, 12, [132703068], 2147482788) = 226022840
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
600000) = 1
sendfile(9, 12, [358725908], 2147481324) = 1526703016
epoll_wait(11, {{EPOLLOUT, {u32=1870332832, u64=53895119963040}}}, 512, 
600000) = 1
sendfile(9, 12, [1885428924], 2147480388) = 2147479552
epoll_wait(11,
и всё
nginx закрывает по таймауту соедиение и вгет докачивает

wget -Y off -O /dev/null http://192.168.78.2:81/3.tmp
--11:43:12--  http://192.168.78.2:81/3.tmp
            => `/dev/null'
Устанавливается соединение с 192.168.78.2:81... соединение установлено.
Запрос HTTP послан, ожидается ответ... 200 OK
Длина: 4 294 967 296 (4.0G) [application/octet-stream]

93% 
[===========================================================================> 
     ] 4 032 908 476   --.--K/s    ETA 00:42

11:54:12 (5.83 MB/s) - Соединение закрыто, позиция 4032908476. Повтор.

--11:54:13--  http://192.168.78.2:81/3.tmp
   (попытка: 2) => `/dev/null'
Устанавливается соединение с 192.168.78.2:81... соединение установлено.
Запрос HTTP послан, ожидается ответ... 206 Partial Content
Длина: 4 294 967 296 (4.0G), 262 058 820 (250M) осталось 
[application/octet-stream]

100%[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++====>] 
4 294 967 296   63.96M/s    ETA 00:00

11:54:17 (63.08 MB/s) - `/dev/null' сохранён [4294967296/4294967296]

> В случае linux-aio-sendfile, возможно, в ядре происходит минимум
> копирования (я не знаю), но во FreeBSD всегда есть две операции
> копирования - 2 и 3.
судя по raw perfomance - нет zero copy. Также заметно, что при 
linux-aio-sendfile нет iowait. Возможно это связано с тем, что не 
происходит упирания в скорость диска. Утилизация диска от sendfile - 
100%, от linux-aio-sendfile - 80%





More information about the nginx-ru mailing list