Pull to refresh
14
0
Владимир @Yagoda123

User

Send message
Полностью конфиг не приводил. Указал только location.

А вообще, да. И aio и thread_pool, и много чего еще пробовал ))
Числа были несколько другие только.

Все-таки, думаю, было мало worker_rlimit_nofile.
Было 4К то-ли из коробки, то-ли сам делал, не помню уже. Хотя, 4к на воркер должно бы хватать чисто умозрительно. Но вот сейчас сделал 64к и на запросы сервер стал отвечать стабильнее.
Вероятно Вы правы.
Очень возможно, что у меня просто не хватало worker_rlimit_nofile в nginx.
Но почему тогда fastcgi_pass помог? Ведь это тоже «файл» для воркера.

php не принципиально. Наверное, лучше было бы сделать на питоне.
Но даже в том виде что сейчас (раздача nginx — fastcgi — php) все свистит и не грузит систему. Мне самое главное, что получился очень быстрый коннект. Т.е. отдача на запрос начинается очень быстро. По большому счету, на соединении большой скорости и не нужно. Но этих соединений много.
mhddfs/aufs, в принципе неплохая штука если надо логически объединить несколько каталогов/дисков. Из плюсов — каждый файл целиком лежит в одном месте. И при гибели одного диска остальное все целое.
Вот только большой трафик через эту прослойку гонять накладно для CPU.
Обычно на раздаче файлов много чтений и мало записей, поэтому писать в общую точку с автоматическим распределением, а читать из настоящего месторасположения — самое то.
LVM это тот-же RAID0, только чуть по-другому. Все равно «прослойка». И все плюсы с минусами от этого. LVM несколько удобнее — позволяет легко расширять дисковое пространство.
У обоих невозможно определить, где находится файл «по-настоящему», у обоих при смерти одного диска помирает все. И в обоих случаях, когда диск занят чем-то своим (это особенно касается SSD), доступ ко всему массиву в ступоре.
RAID0 (особенно аппаратный) хорошо помогает поднять IOPS если используются HDD. С SSD все на много печальнее. SSD периодически сами наводят у себя «порядок». Ну и весь массив будет недоступен пока какой-то диск занят своими делами.

О! Нашел статью: habrahabr.ru/company/webzilla/blog/227927
Как-то тут на хабрахабре проскакивала статья про RAID из SSD. Человек делал эксперименты, замерял результаты. Получилась плохая латентность. Как раз IOPS сильно падал.
Я сознательно не стал собирать RAID, хотя железо вполне позволяет.
Данные не настолько критичные, но потерять все равно жалко. Ну и было у меня несколько случаев, когда из-за смерти диска/контроллера терялся весь массив.
Может вам лучше иметь каждый диск отдельно, писать на него через mhddfs/aufs, а при считывании находить где находится на самом деле и читать от-туда? Можно nginx(ом) это разрулить.
Ну, у меня не совсем обычные HDD.
SAS-3, 12Gb/s, контроллер соответствующий.
И таких 8 штук. Пишется на них через «прокладку» aufs примерно равномерно. Так что чтение тоже примерно равномерное.

По гигабиту больше 950 Мб и не получится. Когда скорость отдачи подошла к 500 Мб (и кратковременные всплески до 800) поставили сетевую на 10 Гб. На тестах (1 URL * 200 потоков) получал 2,8 Гб выхлоп. Но это 1 URL, вероятно читает из кеша.
Сколько получится в реальности буду посмотреть.
await дисков мониторится, больше 10 мс не бывает.
Хм… Хотя отдача и по http, но это не Веб. Т.е. клиенты не используют какой-либо браузер. Используются специализированные «железяки» или специализированный софт (ПК, Smart-TV, Android). Список доступного контента и ссылки на него получают тоже через http с другого сервера. Этот просто раздает.

Каким образом зоопарк?.. Так сложилось. Такова жизнь. Слава богу клиенты этот зоопарк понимают. Хм… wmv вроде не понимают, но такого и не видел.

Вообще-то написал тут не особо заморачиваясь на видео.
Есть задача: раздавать произвольные части больших бинарных файлов. Так уж получилось, что это видео. В принципе, без разницы что это. Ну и как эту задачу лучше выполнить.

Всегда считал, что nginx для этого «самое то». Ну и когда уперся, начал экспериментировать. Получилось, что раздавать части файлов эффективнее через fastcgi. И даже php не принципиально, использовал что было «под рукой».

Т.е. связка nginx (без буферизации) — fastcgi оказалась эффективной для такой задачи.
Ну и решил поделиться своим удивлением ))
Timing cached reads: 15548 MB in 2.00 seconds = 7780.56 MB/sec
Timing buffered disk reads: 624 MB in 3.00 seconds = 207.74 MB/sec

Конвертировать неоправданно. «Продвинутых» клиентов сильно мало.
Приводить к одному формату, к сожалению, невозможно. Там реально зоопарк.

По железу. Нет цели «забить весь канал». Но думаю, 2-3 Gb в итоге потребуется.
CPU хватит за глаза. Диски… 8 штук, каждый гарантированно выдаст 50 МБ/с. В реальности больше (dd if=xxx.avi of=/dev/null выдает всегда больше 100 МБ/с). Итого в битах 8*50*8=3200 Мб.
Памяти бы добавить для кеша — это планируется.
Добавлю.
В php.ini для php-fpm отключены все дополнительные модули (mysql, mysqli и прочее).
Т.е. практически «голый» php. По-идее, можно было бы вообще пересобрать php5-fpm без cripto, ssl, xml и прочего, в данном случае не нужного. В результате потребление памяти сократилось бы еще. Но и так, 1 МБ на процесс, меня вполне устраивает.
pm = dynamic
pm.max_children = 500 // пока хватает. расчеты и мониторинг показывают, что можно довести до 2000
pm.start_servers = 20 // т.е. 20 штук всегда будут ожидать подключение. обеспечивается скорость ответа
pm.min_spare_servers = 20
pm.max_spare_servers = 100
pm.max_requests = 50 // боялся утечек памяти, вроде нормально.

Памяти на борту 20 G. Вот сейчас (в nginx еще остались настройки на собственную отдачу, пока не убираю, жду выходных). 100 соединений, 300 Мб выхлоп:
# free -m
total used free shared buffers cached
Mem: 20114 19382 732 410 374 16318
-/+ buffers/cache: 2689 17425
Swap: 16363 0 16363

..../status:
pool: www
process manager: dynamic
start time: 27/Nov/2017:11:39:48 +1000
start since: 167057
accepted conn: 92179
listen queue: 0
max listen queue: 0
listen queue len: 0
idle processes: 39
active processes: 65
total processes: 104
max active processes: 151
max children reached: 0
slow requests: 0

Цинус в том, что эти child-потоки потребляют очень мало ресурсов. Собственной памяти порядка 0,5-1 МБ каждый. Затраты на CPU тоже мизерные. Там главный процесс — чтение диска.
Это тоже самое что и «echo fread()». Читаются данные в свой некоторый буфер php. Затем эти данные выплевываются в STDOUT. PHP, прежде чем прочитать данные, запросит у системы память в объеме указанного буфера. Соответственно, скрипт будет потреблять приватной памяти не меньше этого буфера. Если читаем по 100К, то вроде не страшно. Но скорость отдачи получается низкая. В ходе экспериментов выяснил, что делать буфер меньше 2М нельзя. Т.е. скрипт будет съедать памяти 2М под буфер + ~0,5М для своих нужд. Итого, 1000 клиентов съедят 2,5 GB.
В моем же варианте «fpassthru($fd)» или «passthru('/bin/dd ...')» на 1000 клиентов придется максимум 1 GB.
Затраты на сам /bin/dd + «прокладка» sh — это мелочи. Приватной памяти они потребляют мизер (меньше 2К вместе). Затраты памяти на сам исполняемый код можно не учитывать — они в памяти в одном экземпляре.
Затраты времени на вызов системной команды маленькие — все нужное уже в памяти.
Интерфейс 10Gb. Зафиксированный максимум 850 Mb. На тестах (1 URL * 200 потоков) выдал 2,8 Gb.
#uname -a
Linux backup 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u2 (2016-01-02) x86_64 GNU/Linux

#cat /etc/debian_version
8.3

Добавлено в sysctl.conf:

net.ipv4.tcp_keepalive_time = 180
net.netfilter.nf_conntrack_tcp_timeout_established = 3000
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10
net.netfilter.nf_conntrack_generic_timeout = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 300
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 120
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 120
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180
net.netfilter.nf_conntrack_icmp_timeout = 10
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.ipv4.netfilter.ip_conntrack_generic_timeout = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent2 = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack = 30
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close = 10
net.ipv4.netfilter.ip_conntrack_tcp_timeout_max_retrans = 120
net.ipv4.netfilter.ip_conntrack_udp_timeout = 30
net.ipv4.netfilter.ip_conntrack_udp_timeout_stream = 180
net.ipv4.netfilter.ip_conntrack_icmp_timeout = 10
net.ipv4.ipfrag_time = 5
net.ipv4.tcp_timestamps = 1
net.ipv4.ipfrag_time = 1
vm.swappiness=20
vm.vfs_cache_pressure=500
Там читался текстовый файл. У меня бинарные.
Больше подошел бы stream_copy_to_stream, но в нем сложно копировать произвольную часть файла.
И этот stream_copy_to_stream в указанной статье дал примерно тот-же memory_get_peak_usage что и получилось у меня с passthru('/bin/dd ....').
Но у меня еще в скрипте дополнительно куча логики, которая ест память.
Так что не то. Функционала мало.
Какие именно интересуют?
Все постить много…
У меня в диски и канал пока не упирается. Канал 10 Gb.
По факту в выходные было 850 Mb. На используемых дисках await выше 10 ms не поднимается. Обычно 2 — 5.
Склеивать у меня не выход. Надо уметь отдавать произвольную часть файла. проблема именно в этом. И в том, что практически все запросы такие.
Это из питона? В принципе можно и на нем делать. Но тут принципиальной разницы нет. Все равно "$line = fgets($f)" сожрет кучу памяти. Если делать на рабочей машине — нормально. А на сервере, да на каждый запрос…
Нафиг-нафиг, ночью бежать до серверной чтобы ребутнуть сервер.
Формат всякий-разный. Воспроизводит специализированный софт или железо. Изменить его не могу.
Отдавать как есть.
Канал 10 Gb.
Модули nginx http_flv_module и http_mp4_module не подходят.
Сейчас имеется много контента, который этими модулями не поддерживаются.

hls тоже не в тему — клиенты не поддерживают. И изменить что-то у клиента невозможно.

Проблема у меня возникла именно с блокирующим чтением диска при обработке range-bytes запросов. Если кто предложит способ обойти именно эту проблему — подсказывайте плиз.
Мне надо отдать по запросу HTTP. Поставить на паузу, перемотать вперед-назад, продолжить.
1
23 ...

Information

Rating
Does not participate
Date of birth
Registered
Activity