У нас розповсюджена інфраструктура в кількох основних місцях по всьому світу - Сінгапуру, Лондону та Лос-Анджелесу. RTT між будь-якими двома локаціями перевищує> 150 мс.
Нещодавно ми оновили всі сервери для використання посилань на 1 Гбіт / с (від 100 Мбіт / с). Ми проводили кілька тестів на основі TCP між серверами в різних місцях і побачили дивовижні результати. Ці результати повністю повторювані.
- Лос-Анджелес (100 Мбіт / с) до Лондона (100 Мбіт / с): ~ 96 Мбіт / с
- Лос-Анджелес (100 Мбіт / с) до Лондона (1 Гбіт / с): ~ 96 Мбіт / с
- Лос-Анджелес (1 Гбіт / с) до Лондона (100 Мбіт / с): пропускна здатність 10-40 Мбіт / с (мінливий)
- Лос-Анджелес (1 Гбіт / с) до Лондона (1 Гбіт / с): пропускна здатність 10-40 Мбіт / с (мінливий)
- Лос-Анджелес (1 Гбіт / с) до Лос-Анджелеса (1 Гбіт / с):> 900 Мбіт / с
Схоже, щоразу, коли відправник працює на 1 Гбіт / с, наша пропускна здатність дуже сильно страждає за довгі посилання.
Підхід до тестування раніше надзвичайно простий - я просто використовую cURL для завантаження бінарного файлу 1 Гб з цільового сервера (так у вищенаведеному випадку клієнт cURL працює на лондонському сервері та завантажується з LA, так що LA є відправником) . Для цього звичайно використовується єдине TCP-з'єднання.
Повторивши ті ж тести над UDP за допомогою iperf, проблема зникає!
- Лос-Анджелес (100 Мбіт / с) до Лондона (100 Мбіт / с): ~ 96 Мбіт / с
- Лос-Анджелес (100 Мбіт / с) до Лондона (1 Гбіт / с): ~ 96 Мбіт / с
- Лос-Анджелес (1 Гбіт / с) до Лондона (100 Мбіт / с): ~ 96 Мбіт / с
- Лос-Анджелес (1 Гбіт / с) до Лондона (1 Гбіт / с):> 250 Мбіт / с
Це прямо вказує на деякі проблеми з конфігурацією TCP або NIC / портів у моїх очах.
На обох серверах працює CentOS 6.x, з кубічним TCP. У обох є вікно максимального TCP надсилання та прийому 8 Мб, увімкнено часові позначки TCP та вибіркове підтвердження. Однакова конфігурація TCP використовується у всіх тестових випадках. Повна конфігурація TCP наведена нижче:
net.core.somaxconn = 128
net.core.xfrm_aevent_etime = 10
net.core.xfrm_aevent_rseqth = 2
net.core.xfrm_larval_drop = 1
net.core.xfrm_acq_expires = 30
net.core.wmem_max = 8388608
net.core.rmem_max = 8388608
net.core.wmem_default = 131072
net.core.rmem_default = 131072
net.core.dev_weight = 64
net.core.netdev_max_backlog = 1000
net.core.message_cost = 5
net.core.message_burst = 10
net.core.optmem_max = 20480
net.core.rps_sock_flow_entries = 0
net.core.netdev_budget = 300
net.core.warnings = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_retrans_collapse = 1
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_retries1 = 3
net.ipv4.tcp_retries2 = 15
net.ipv4.tcp_fin_timeout = 60
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_abort_on_overflow = 0
net.ipv4.tcp_stdurg = 0
net.ipv4.tcp_rfc1337 = 0
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_fack = 1
net.ipv4.tcp_reordering = 3
net.ipv4.tcp_ecn = 2
net.ipv4.tcp_dsack = 1
net.ipv4.tcp_mem = 1528512 2038016 3057024
net.ipv4.tcp_wmem = 4096 131072 8388608
net.ipv4.tcp_rmem = 4096 131072 8388608
net.ipv4.tcp_app_win = 31
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_frto = 2
net.ipv4.tcp_frto_response = 0
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_no_metrics_save = 0
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_tso_win_divisor = 3
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_abc = 0
net.ipv4.tcp_mtu_probing = 0
net.ipv4.tcp_base_mss = 512
net.ipv4.tcp_workaround_signed_windows = 0
net.ipv4.tcp_dma_copybreak = 4096
net.ipv4.tcp_slow_start_after_idle = 1
net.ipv4.tcp_available_congestion_control = cubic reno
net.ipv4.tcp_allowed_congestion_control = cubic reno
net.ipv4.tcp_max_ssthresh = 0
net.ipv4.tcp_thin_linear_timeouts = 0
net.ipv4.tcp_thin_dupack = 0
Додано декілька зображень графіків вводу-виводу IOS деяких тестових випадків (вибачте, я не можу опублікувати зображення безпосередньо):
Тестовий випадок 1 (100Mbps -> 100Mbps) - приємна плавна передача. Жодних втрат при захопленні. - http://103.imagebam.com/download/dyNftIGh-1iCFbjfMFvBQw/25498/254976014/100m.png
Тестовий випадок 3 (1 Гбіт / с -> 100 Мбіт / с) - передача воталі, займає багато часу, щоб досягти будь-якої швидкості - ніколи не наближається до 100 Мбіт / с. Однак втрат / повторних передач у захопі немає! - http://101.imagebam.com/download/KMYXHrLmN6l0Z4KbUYEZnA/25498/254976007/1g.png
Отже, підсумовуючи, коли довге посилання використовується підключенням 1Gbps, ми отримуємо набагато нижчу пропускну здатність TCP, ніж коли ми використовуємо 100Mbps-з'єднання.
Я дуже вдячний деяким вказівникам будь-яких експертів TCP там!
Дякую!
ОНОВЛЕННЯ (2013-05-29):
Ми вирішили проблему з тестовим випадком №4 вище (відправник 1 Гбіт / с, приймач 1 Гбіт / с, на великій RTT). Тепер ми можемо вдарити ~ 970Mbps протягом декількох секунд після початку передачі. Здається, проблема була перемикачем, що використовується у постачальника хостингу. Перехід до іншого вирішив це.
Однак тест №3 здебільшого залишається проблематичним. Якщо у нас приймач працює зі швидкістю 100 Мбіт / с, а відправник - 1 Гбіт / с, то ми бачимо приблизно 2-3 хвилини очікування, коли одержувач досягне 100 Мбіт / с (але він зараз досягає повної швидкості, на відміну від раніше). Як тільки ми опустимо відправника до 100 Мбіт / с або збільшимо приймач до 1 Гбіт / с, тоді проблема зникає, і ми можемо проскочити на повну швидкість через секунду-дві.
Основна причина полягає в тому, що ми спостерігаємо збитки, звичайно, дуже скоро після початку передачі. Однак це не співпадає з моїм розумінням того, як працює повільний старт; швидкість інтерфейсу не повинна мати жодного відношення до цього, оскільки це повинно регулюватися ACK від приймача.
Пропозиції вдячні, отримані, будь ласка! Якби я міг запропонувати тут щедрості, я би!
tcp_*mem = 4096 1048576 33554432
Ви не ввімкнули Jumbo Frames на посилання 1Gbps? Це десь може спричинити фрагментацію.