Структура розетки ядра та TCP_DIAG


18

Я працюю над програмним забезпеченням, яке підключається до сервера даних у режимі реального часу (за допомогою TCP), і у мене відпадають деякі з'єднання. Я здогадуюсь, що клієнти не читають дані, які надходять із сервера, досить швидко. Тому я хотів би стежити за своїми розетками TCP. Для цього я знайшов інструмент "ss".

Цей інструмент дозволяє побачити стан кожного сокета - ось приклад рядка виходу команди ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

Моє запитання: що означає частина пам'яті? Переглядаючи вихідний код інструменту, я виявив, що дані надходять із структури ядра ( sockв sock.h). Точніше, він походить з полів:

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

Хтось знає, що вони означають? Мої здогадки:

  • rmem_alloc : розмір вхідного буфера
  • wmem_alloc : розмір вихідного буфера
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

Ось мої розміри буферів:

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071

Яка ваша конфігурація розміру буфера? Ви бачите, що буфери прийому насичуються на роз'ємах розетки? Чи припиняє ваш учасник з'єднання на EWOULDBLOCK?
— Карлсон

Мої розміри розеток досить малі, я думаю, я оновив пост з ними. Про EWOULDBLOCK я не можу сказати. Мій клієнт знаходиться в JAVA і просто скажіть, що його відключив сервер. Сервер знаходиться на C ++, і це просто говорить про те, що він перервав з'єднання без будь-якої інформації. У мене немає вихідного коду сервера, тому я не можу змінити його поведінку. Здається, що клієнти відключаються, коли вони трохи перевантажені, навіть якщо це триває лише кілька секунд.
— Твістер

Чи налаштована конфігурація розмірів буфера на сервері? Чи можете ви дивитися розміри буфера на клієнті? Чи маєте ви доступ до джерела клієнта? Ви запустили netstat -apnc для перегляду розмірів буфера? Ви намагалися збільшити розміри буфера в ядрі, щоб побачити, що відбувається?
— Карлсон

Так, вони вже встановлені на максимальне значення сервера (я вважаю, що вони не можуть бути більшими за властивості net.ipv4.tcp_ *, правда?) Для netstat -apnc він не дає мені розмірів буферів, тому я дивився на сс. Щодо ядра, я не корінь на сервері, а ІТ-команди тут досить вперті. Мені потрібно бути впевненим у тому, що відбувається, перш ніж я попрошу їх змінити значення ... І так, я маю доступ до джерела клієнта, і моє розслідування щодо клієнта підтверджує, що відключення відбувається від сервера.
— Твістер

netstat -apnc дає загальний розмір черг для надсилання та отримання в Linux. Якщо сервер встановлює буфер максимально доступним, а ви все ще насичуєте, можливо, вам потрібні більш високі настройки буфера на рівні ОС
— Карлсон,

Відповіді:


7

sk_forward_alloc - це пам'ять, що розподіляється вперед, яка є загальною пам'яттю, наявної в даний час у квоті сокета.

sk_wmem_queued - це об'єм пам'яті, який використовується буфером передачі сокетів, що знаходиться в черзі в черзі передачі, або або ще не надсилається, або ще не підтверджений.

Ви можете дізнатися більше про управління пам’яттю TCP у розділі 9 архітектури, проектування та впровадження TCP / IP в Linux від Sameer Seth, М. Ajaykumar Venkatesulu


Я не розумію, чим sk_wmem_queuedвідрізняється це визначення sk_wmem_alloc, ви могли б трохи розширити це? (Якщо ви знаєте відповідь, сміливо додайте відповідь на це питання: unix.stackexchange.com/questions/551444/… )
— маленький чувак

1

Див. Сторінку чоловіка ss.

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)

0

Щодо sk_wmem_queuedта sk_wmem_alloc, я задав те саме питання, тож я скопію відповідь тут:

Я надіслав електронною поштою Еріку Думазету, який сприяє мережевому стеку Linux, і ось відповідь:

sk_wmem_allocвідстежує кількість байтів для черги skb після транспортного стеку: qdisc шар та кільцеві буфери NIC TX.

Якщо у вас є 1 Мб даних, що знаходяться в черзі запису TCP, ще не надісланої (обмеження cwnd), sk_wmem_queueбуде близько 1 МБ, але sk_wmem_allocбуде приблизно 0

Дуже хороший документ для розуміння того, що ці три види черг (буфер сокетів, черга qdisc та черга пристроїв) - це ця стаття (досить довга) стаття . У двох словах, розетка починається з натискання пакетів прямо на чергу qdisc, яка пересилає їх у чергу пристроїв. Коли черга qdisc заповнена, сокет починає буферизацію даних у власній черзі запису.

мережевий стек розміщує пакети безпосередньо в дисципліні черги або ж відштовхується на верхні шари (наприклад, буфер сокета), якщо черга заповнена

В основному: sk_wmem_queuesчи використовується пам'ять, яка використовується буфером сокета ( sock.sk_write_queue), а sk_wmem_allocпам'ять, яка використовується пакетами в черзі qdisc та пристроїв.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.