172 lines
21 KiB
Markdown
172 lines
21 KiB
Markdown
---
|
||
title: Межсайтовая пропускная способность — TrueNAS (Taiga) ↔ Mac/TV
|
||
created: '2026-09-02'
|
||
updated: '2026-09-21'
|
||
type: tech
|
||
namespace: personal
|
||
tags: [network, truenas, throughput, rtt, tcp, jellyfin, xray, bottleneck, webos, moonfin, breezyfin, prefetch, single-flow]
|
||
related:
|
||
- "[[xray-reverse-tunnel-kraken-truenas]]"
|
||
- "[[../how-to/truenas-infrastructure]]"
|
||
- "[[../family/how-to/kraken-network]]"
|
||
---
|
||
|
||
# Межсайтовая пропускная способность — TrueNAS ↔ Mac/TV
|
||
|
||
> Контекст: после восстановления стека медиа/права на Taiga (см. `family/documents/vault-sync/2026-09-02-restore-privilege-scope.md`) Jellyfin запустился и файлы читаются, но **прямое воспроизведение с ТВ «грузится кусками»**. Диагностика 2026-09-02 установила: это **НЕ транскодинг и НЕ тариф**, а ограничение сети между двумя физически разнесёнными локальными сетями.
|
||
|
||
## Cетевой layout (фактический)
|
||
|
||
| Узел | LAN | Шлюз | Egress IP | Провайдер |
|
||
|---|---|---|---|---|
|
||
| Mac / TV (дом) | `192.168.1.57` | `192.168.1.1` | динамический | ТТК (92.62.x / 185.20.x) |
|
||
| **TrueNAS (Taiga)** | `192.168.2.197` | `192.168.2.2` | `90.189.160.148` (`mallexxx.duckdns.org`) | Ростелеком (194.186.x → 217.107.x) |
|
||
|
||
**Ключевое:** TrueNAS НЕ в локальной сети Мака/ТВ. Трафик ТВ→Jellyfin идёт целиком по интернету между двумя разными операторами/домохозяйствами.
|
||
|
||
## Замеры (2026-09-02)
|
||
|
||
### Задержка / маршрут
|
||
- RTT Mac → TrueNAS: **~104 мс**.
|
||
- Traceroute: хопы 1–7 моего ISP (ТТК) — **3–6 мс** ✅ чисто. **На хопе 8 (`194.186.168.65`) прыжок до ~54 мс** — межоператорская передача в сеть Ростелекома, где живёт TrueNAS. Хоп 10 (`217.107.108.41`) ~60 мс.
|
||
- Этот +50 мс — физическое/пиринговое расстояние между региональными операторами, НЕ петля. Перенастройка маршрута полностью RTT не уберёт.
|
||
- Примечание: **дальние сети в целом** (8.8.8.8 ~100 мс) у ТТК тоже идут через ~50 мс переход — деградация на стороне выхода, а не только до TrueNAS.
|
||
|
||
### Пропускная способность (распутали про «тариф»)
|
||
- Mac download с CDN: **~78 Мбит/с** (линия Мака в порядке).
|
||
- **TrueNAS сторона**: NIC `enp3s0` 1 Gb/s, до шлюза 0.2–0.8 мс 0% loss. NAS→Cloudflare: **download ~184 Мбит/с, upload ~117 Мбит/с**. → **Лимита тарифа на TrueNAS НЕТ.**
|
||
- Mac → TrueNAS (SCP 200MB): **~28 Мбит/с** одним потоком.
|
||
- Mac → TrueNAS, **4 параллельных SCP потока: ~28 → ~51 Мбит/с** (агрегат растёт с параллельностью).
|
||
|
||
## Вывод (важно)
|
||
|
||
Ограничение — **НЕ по суммарной полосе транзита, а по одному TCP-потоку из-за высокого RTT (~104 мс) + BDP / congestion-window**. Доказательство: 4 потока дали рост ×1.8 (28→51) — при жёстком лимите линии рост не произошёл бы.
|
||
|
||
**Почему Jellyfin дёргается прямо:** Jellyfin отдаёт видео одним последовательным HLS-потоком (один TCP). Один поток душится RTT-штрафом до ~28–50 Мбит, а BluRay-файл в пиках идёт к 20+ Мбит → с 104 мс RTT сегменты не успевают → стоп-кары. Файл The.Jungle.Book.1967.720p.BluRay ≈ 7.1GB/~78мин → средний ~12 Мбит/с, пики выше.
|
||
|
||
## Факты ИЗ ЛОГОВ Jellyfin (подтверждают: транскодинг не причина в этих тестах)
|
||
- Реальный транскод с `libx264` + reduce был только на "Snatch" (тестовые короткие старты каждые ~5 с — клиент переподключался).
|
||
- "Один день в Стамбуле"/"Рождественские хроники" — ремукс `-codec:v:0 copy` в HLS (не перекодирование), стоп на ~2-3 сек.
|
||
- В моменте (пока ТВ крутит 720p) — ffmpeg-дочерних процессов нет, папка transcodes пуста → **прямой stream/direct, транскодинг не идёт**.
|
||
|
||
## 🧭 2026-09-21: развилка решена — многопоточный HLS не существует в Jellyfin/webOS
|
||
|
||
Перепроверено по первоисточникам (см. [[personal/tech/multistream-single-flow-limit]]):
|
||
- Jellyfin «multiple parallel connections» — **Planned** 5 лет, кода нет (230 голосов).
|
||
- hls.js multi-segment prefetch (#6753) — открыт, не реализован.
|
||
- webOS-приложения используют **нативный media pipeline** → подменить логику загрузки нельзя.
|
||
- **Несколько xray-туннелей не помогут** — один физический путь, одно congestion window.
|
||
- Speedtest 120 Мбит = 8 параллельных сессий. Одна сессия упирается в **~28–45 Мбит** (подтверждено замерами ниже).
|
||
|
||
**Рабочие пути:** ограничить битрейт в клиенте / Moonfin с буфером / **Lampac на Кра́кене**
|
||
(буфер 50–100 МБ + GStreamer транскод) / prefetch-proxy. Полный разбор — в
|
||
[[personal/tech/multistream-single-flow-limit]].
|
||
|
||
## Решение / направление
|
||
1. **Правильное лекарство** (не мультипоток ради мультипотока, а либо снижение латентности, либо запас по битрейту под single-flow): лимит транскода ~12–18 Мбит, ЛИБО гнать трафик ТВ→TrueNAS через **xray tunnel** (`vpn.mallexxx.duckdns.org`, смотри `[[xray-reverse-tunnel-kraken-truenas]]`) вместо прямого межоператорского пути.
|
||
2. Jellyfin **не умеет** штатно разбивать один плейбек на параллельные TCP. Параллельность (28→51 Мбит) достижима только поднятием файла способом «качалка в N коннектов» + прокси, либо через туннель.
|
||
3. Задача замера скорости через **`xray-test-client`** контейнер (teddysun/xray, SOCKS `127.0.0.1:1080`) — НЕ завершена: команда замера была заблокирована юзером; способ/endpoint (стучались на внутренний `192.168.2.197:8096`) предложен неверно.
|
||
|
||
## Связанный локальный кейс (Kraken, same-LAN)
|
||
|
||
> Тот же симптом «ТВ Jellyfin Direct Play дёргается» 2026-09-02, но в **локальной сети** (Kraken RPi5, дом) — причина ДРУГАЯ. См. `family/how-to/kraken-network.md`.
|
||
> **Как отличать кейсы:** если Jellyfin-хост в одной LAN с ТВ (ping < ~10 мс) → дёрганье Direct Play почти всегда из-за **линка 100 Мбит/с** на сервере, а НЕ полосы/RTT. Проверка: `cat /sys/class/net/<iface>/speed` (это Kракен упал 1G→100M). Если хост в другой сети/операторе (ping ~104 мс, как Taiga) → ограничение по одному TCP-потоку из-за RTT. «99 Mbps» в UI = битрейт 4K remux-файла (обычно ~60–100 Mbps), НЕ скорость сети/линка.
|
||
|
||
### Endpoint-факты для замера туннеля
|
||
- Локальный тестовый xray-клиент на Mac: контейнер **`xray-test-client`** (`127.0.0.1:1080->1080/tcp`), конфиг `/Users/admin/xray-test/config.json`, оставлен на `kraken-user`.
|
||
- Per-user egress на `vpn.mallexxx.duckdns.org`: `user1` → direct TrueNAS `90.189.160.148`; `kraken-user` → reverse через Kraken `92.62.70.41`.
|
||
- Конфиг клиента лежит на Mac отдельно (не в vault); бэкап direct-клиента: `/Users/admin/xray-test/config.json.bak-user1-direct-20260902-1227`.
|
||
|
||
---
|
||
|
||
## 🔴 2026-09-21 — РАЗБОР: почему speedtest 120 Мбит ≠ Jellyfin не тормозит. Что делать
|
||
|
||
> Контекст: Alex (Бишкек) сообщил, что плейбек Jellyfin на ТВ тормозит даже по проводу, но **speedtest через reverse-туннель показал до 120 Мбит**. Гипотеза Alex: «поднять реальный VPN в 192.168.2.x через VLESS и проверить, может заработает». Ниже — разбор, почему это не поможет, и что реально может.
|
||
|
||
### ❌ Что опровергнуто этой сессией
|
||
|
||
**1. «Speedtest доказал, что 120 Мбит физически можно — значит туннель/multi-tunnel даст столько же».**
|
||
Speedtest гоняет **8 параллельных TCP-сессий**, каждая со своим congestion window. 8 × ~15 Мбит = 120 Мбит. Это доказывает, что канал **пропускает** 120 Мбит суммарно. Это **НЕ** доказывает, что **одна** сессия получит 120 Мбит. Наши замеры это уже показывали: 1 поток = 28 Мбит, 4 потока = 51 Мбит (×1.8). Скорость TCP ≈ окно / RTT; при RTT 104 мс для 120 Мбит нужно окно ≈ **1.5 МБ «в полёте»**, одна сессия до такого не разгоняется при потерях на межоператорском стыке.
|
||
|
||
**Правильная модель (не «узкая труба», а «кассы»):** канал пропустит 120, но **только если запрашивать 8 потоками одновременно**. У Jellyfin — один покупатель в одной кассе.
|
||
|
||
**2. «Поднять несколько xray-туннелей и распараллелить».**
|
||
Не сработает: **физический путь один** (ТТК → Ростелеком, хоп 8 = +50 мс). N туннелей по одному пути делят один congestion window → суммарно не больше, чем один, плюс накладные расходы. Это MPTCP/bonding-территория, а он агрегирует **разные** пути. Аналогия Alex «узкое место — линк между провайдерами» — верно; вывод «значит, надо прокинуть больше туннелей» — нет, линк пропускает 120 Мбит, но не одному потоку.
|
||
- Честный путь к «несколько путей» — только **второй независимый линк** (мобильный 4G/5G backup-WAN на TrueNAS) + MPTCP/OpenMPTCProuter.
|
||
|
||
**3. «VLESS/REALITY-туннель уберёт лимит».**
|
||
Уже проверено 2026-09-02 (см. раздел «Замеры скорости туннелей» в `[[xray-reverse-tunnel-kraken-truenas]]`): direct через `vpn.mallexxx` = **~37 Мбит**, reverse через Kraken = **~45 Мбит** (нестабилен). Оба — в том же коридоре, что и прямой путь (28 Мбит single-flow). Туннель идёт тем же маршрутом; REALITY/Vision добавляет обёртки и обычно чуть хуже прямого. **Строить «реальный VPN в 192.168.2.x» смысла нет — он уже есть (`vpn.mallexxx`), и он не помог.**
|
||
|
||
### ✅ Что реально работает — ранжировано
|
||
|
||
| # | Подход | Механизм | Усилие | Шанс |
|
||
|---|---|---|---|---|
|
||
| 1 | **Лимит битрейта в клиенте** (10–15 Мбит) | Транскод на TrueNAS; один поток 10 Мбит проходит с запасом ×3 | 2 мин | **Высокий** |
|
||
| 2 | **Moonfin / Breezyfin** (webOS-клиенты) | Нативный pipeline + транскод-лимит в UI + лог «кто отказал в Direct Play» | ~30 мин (Homebrew Channel) | Средний (диагностика) |
|
||
| 3 | **Prefetch-proxy на стороне клиента** | Прокси тянет файл/HLS **8 параллельными Range-запросами**, отдаёт клиенту из локального кэша → клиент видит «быстрый сервер» | Высокое (писать/настраивать) | Средний |
|
||
| 4 | **BBR + HTTP/3 на TrueNAS** | BBR вместо CUBIC держит cwnd на long-haul; Caddy умеет HTTP/3, но webOS-клиент его не использует | 30 мин | +20–50%, не ×4 |
|
||
| 5 | **Второй ISP + MPTCP** | Настоящая агрегация разных путей | Очень высокое / деньги | **Ноль** без второго линка |
|
||
|
||
### 🔑 Ключевое различие для варианта 3 (и почему он единственный «правильный»)
|
||
Параллелизм рождается от **независимых HTTP-запросов** (каждый = своё TCP-окно), а НЕ от мультиплексирования транспорта.
|
||
- ✅ **Клиент/prefetch-proxy делает 8 Range-запросов** → 8 независимых окон → 120 Мбит возможно.
|
||
- ❌ **8 xray-туннелей + mux** → одно логическое окно, порезанное на 8 → head-of-line blocking, выигрыша нет.
|
||
Prefetch-proxy **обязан стоять на стороне клиента** (Mac/ТВ в Бишкеке), не на TrueNAS — иначе параллельные запросы всё равно идут через узкий канал по отдельности, выигрыш частичный.
|
||
|
||
### 🔴 КРИТИЧНО: клиент Alex — LG webOS (`Jellyfin for WebOS 1.2.2`)
|
||
Официальный webOS-клиент — **обёртка вокруг веб-интерфейса**, внутри **один HTML5 `<video>` element = один TCP-поток**. Ни настройки числа соединений, ни Range-префетча.
|
||
|
||
### 📋 Исследование альтернативных webOS-клиентов (2026-09-21)
|
||
|
||
**Оба проверены по первоисточникам (GitHub/вики).**
|
||
|
||
| | **Moonfin** | **Breezyfin** |
|
||
|---|---|---|
|
||
| Проект | `Moonfin-Client/Smart-TV` (общий код Tizen+webOS), 409★, 1153 коммита, 58 форков | `botagas/Breezyfin`, 63★, 6 форков |
|
||
| Версия | 2.5.1 | v0.2.1 (21 авг 2026), **beta**, 112 коммитов сверх upstream |
|
||
| Сайт | moonfin.io | breezyfin.app |
|
||
| webOS | **3.0+ / 2016+** | 5.0+ |
|
||
| Движок | Enact/Sandstone + **Starfish** (нативный webOS pipeline) | Enact Sandstone, HTML5 + нативный webOS player |
|
||
| **Параллельные потоки** | ❌ **НЕТ** (один HTML5 video element) | ❌ **НЕТ** |
|
||
| Транскод-лимит в UI | ✅ **есть** (*Playback & SyncPlay → Video Playback Preferences → Transcoding Limits*: Max Streaming Bitrate / Max Resolution) | не заявлено явно |
|
||
| Лог «кто отказал в Direct Play» | ✅ **есть** (*Settings > About > Diagnostics & Logging*; отчёт называет причину отказа) | Есть diagnostics/logs, формулировка не заявлена |
|
||
| Fallback-цепочка | Direct Play → native transcode → **hls.js** | Direct Play → Direct Stream → Transcode + explicit consent перед HDR/DV-даунгрейдом |
|
||
| Jellyfin backend | минимум **10.9.0**; **Jellyfin 12 совместим** (`ApiKey`) | 12 auth fix: legacy `X-Emby-Authorization`/`X-Emby-Token` за флагом `EnableLegacyAuthorization` (по умолчанию off) |
|
||
| Emby | ✅ | ❌ |
|
||
| codec-профиль | per-TV профиль, сообщается серверу; на webOS транскод fallback **HEVC→H264**, когда сервер запрещает HEVC; FLAC direct play в MP4/MKV на **webOS 5+** (до 8 каналов) | adaptive; JASSUB Canvas2D для сабтитров (WebGL на webOS ненадёжен) |
|
||
| Аудио passthrough | DTS/DTS-HD/TrueHD bitstream; **на webOS — экспериментально**; Force TrueHD/Atmos | не заявлено |
|
||
| Сабтитры | PGS client-side, ASS/SSA через **libass**, DVD/DVB burn-in сервером, отдельный стиль для HDR | configurable client/bitmap |
|
||
| Live TV/DVR | ✅ (webOS 5+) | ❌ |
|
||
| SyncPlay | ✅ | ✅ (native Jellyfin SyncPlay + JellyWatchParty) |
|
||
| Установка | **Homebrew Channel** (не истекает) или Dev Manager Desktop / `ares-install` | Homebrew catalog или IPK |
|
||
| Лицензия | MPL 2.0 | GPL-3.0-only |
|
||
|
||
**Ключевой факт по установке:** LG Developer Mode **истекает каждые 50 часов** → sideloaded-приложения удаляются. **Homebrew Channel-путь НЕ истекает** (root-эксплойт, не Dev Mode). Оба клиента есть в основном каталоге Homebrew Channel (`repo.webosbrew.org`). → Установка через Homebrew Channel убирает главный минус sideload.
|
||
|
||
**Проверка через Homebrew-каталог:** `https://repo.webosbrew.org/apps/com.breezyfin.app/`, `https://repo.webosbrew.org/apps/org.jellyfin.webos/`.
|
||
|
||
### ⚠️ Честный вывод по клиентам
|
||
Moonfin/Breezyfin **НЕ дадут 120 Мбит** — они не распараллеливают поток. Их ценность:
|
||
1. **Endpoint-лимит битрейта в UI** — то же лекарство, что ручной лимит, но штатно.
|
||
2. **Лог «почему не Direct Play»** — диагностика, которой у официального клиента нет. Сразу различит «сеть душит» vs «кодек/аудио отказали».
|
||
3. Нативный pipeline вместо веб-обёртки → меньше оверхеда.
|
||
4. Homebrew Channel = без истечения Dev Mode.
|
||
|
||
**Настоящее распараллеливание остаётся только за prefetch-proxy (вариант 3) — клиенты его не заменяют.**
|
||
|
||
### Готовые инструменты для prefetch-proxy (найдены 2026-09-21)
|
||
- **`aria3`** (PyPI) — multi-threaded streaming proxy с кэшем и умным prefetch.
|
||
- **`node-HLS-Proxy`** (warren-bank) — prefetch `.ts`-сегментов, hook-функции для управления префетчем.
|
||
- **`jspeedstreamer`** (conorh) — Java-прокси, multiple parallel requests.
|
||
- **nginx `proxy_cache` + `slice`** — кэширует byte-ranges, а не файлы целиком (штатный механизм под Range-prefetch).
|
||
- **`JellyfinCache`** (ArnyminerZ) — прокси-кэш между клиентом и Jellyfin-сервером. ⚠️ Ставится на стороне **клиента**, не сервера.
|
||
|
||
### Предложенный план (НЕ начат, ждёт решения Alex)
|
||
1. Проверить версию Jellyfin на TrueNAS (нужно ≥10.9.0 для Moonfin). *~2 мин, ничего не меняет.*
|
||
2. Поставить **Moonfin** через Homebrew Channel. *~30 мин.*
|
||
3. Включить Diagnostics & Logging, проиграть проблемный файл.
|
||
4. Прочитать лог: кто отказал в Direct Play и почему.
|
||
5. По результату: сеть → лимит битрейта или prefetch-proxy; кодек → подбор профиля.
|
||
|
||
**Статус: план предложен, Alex решения не дал. Ничего не менялось — ни на TrueNAS, ни на ТВ, ни в туннелях.**
|