Jump to content
Калькуляторы

Параллелизм dummynet Распределение шейпинга на несколько процессоров

Всем доброго дня!

 

Имею PC шлюз на примерно 1700 абонентов, построен на FreeBSD 7.1-RELEASE-p2 на 2х 5410 Xeon.

Абоненты терминируются на L3 свичах, до шлюза бежит только трафик Интернет. Всё простой маршрутизацией без vlan'ов, em0 смотрит в инет, em1 - в локальную сеть. Сетевые em встроенные.

Помимо шейпа, работает ipfw nat и сбор статистики через ng_netflow.

 

В ЧНН почти всё время наблюдаю такую картину в top'е:

last pid: 37420;  load averages:  0.84,  0.79,  0.71   up 85+06:27:37  22:55:24
67 processes:  11 running, 45 sleeping, 11 waiting
CPU:  0.0% user,  0.0% nice, 21.9% system,  0.7% interrupt, 77.5% idle
Mem: 97M Active, 133M Inact, 161M Wired, 920K Cache, 199M Buf, 3118M Free
Swap:

  PID USERNAME  THR PRI NICE   SIZE    RES STATE  C   TIME    CPU COMMAND
   12 root        1 171 ki31     0K     8K CPU5   5 1980.5 97.17% idle: cpu5
   15 root        1 171 ki31     0K     8K CPU2   2 1910.2 89.89% idle: cpu2
   14 root        1 171 ki31     0K     8K RUN    3 1955.3 89.06% idle: cpu3
   10 root        1 171 ki31     0K     8K CPU7   7 1981.3 87.89% idle: cpu7
   17 root        1 171 ki31     0K     8K CPU0   0 1845.6 87.21% idle: cpu0
   16 root        1 171 ki31     0K     8K CPU1   1 1847.4 84.18% idle: cpu1
   13 root        1 171 ki31     0K     8K CPU4   4 1972.8 82.86% idle: cpu4
   11 root        1 171 ki31     0K     8K RUN    6 1972.2 67.29% idle: cpu6
   38 root        1 -68    -     0K     8K CPU6   6 301.8H 41.85% dummynet
   29 root        1  43    -     0K     8K RUN    3  64.3H 12.16% em0_rx_kthrea
  152 root        1  43    -     0K     8K WAIT   2  64.4H 11.47% em0_rx_kthrea
   33 root        1  43    -     0K     8K WAIT   1  63.2H 10.89% em1_rx_kthrea
49273 root        1  43    -     0K     8K WAIT   5 713:21 10.89% em1_rx_kthrea
  151 root        1  43    -     0K     8K WAIT   4  64.2H 10.84% em0_rx_kthrea
   28 root        1  43    -     0K     8K WAIT   0  64.4H 10.69% em0_rx_kthrea
  163 root        1  43    -     0K     8K WAIT   0  63.1H 10.55% em1_rx_kthrea
   32 root        1  43    -     0K     8K WAIT   7  63.1H 10.35% em1_rx_kthrea
   18 root        1 -32    -     0K     8K WAIT   0  43.4H  1.51% swi4: clock

но довольно часто на короткое время процесс dummynet выжирает до 85-90% проца.

 

Нагрузка на шлюз не очень велика:

gw-228-0 22:58:55 ~ # netstat -w1d
            input        (Total)           output
   packets  errs      bytes    packets  errs      bytes colls
     46268     0   34363024      45307     0   33805885     0
     45964     0   34642701      44742     0   34093655     0
     46851     0   35027810      46254     0   34640772     0
     45837     0   33805929      44721     0   33213205     0
     46796     0   35255467      45791     0   34552068     0
     45343     0   34140908      44396     0   33633273     0
     46217     0   34563171      45345     0   34008366     0

В фаерволе вроде как всё оптимизированно по максимуму, если нет, подскажите что и где?

00001 nat 1 ip from any to any in via em0
00002 skipto tablearg ip from any to table(1)
00003 skipto tablearg ip from table(2) to any
00004 deny ip from any to any
00100 allow tcp from table(5) to any dst-port 22
00101 allow tcp from table(6) to any dst-port 4567
00102 deny tcp from any to any dst-port 22,4567
00103 allow ip from any to any
00500 pipe tablearg ip from any to table(11) out via em1
00501 ngtee 65534 ip from any to any out via em1 # <- это заворот на ng_netflow
00502 allow ip from any to any
01000 pipe tablearg ip from table(12) to any in via em1
01001 ngtee 65534 ip from any to any in via em1
01002 nat 1 ip from any to any out via em0
01003 allow ip from any to any
01500 pipe tablearg ip from any to table(11) out via em1
01501 ngtee 65534 ip from any to any out via em1
01502 allow ip from any to any
02000 pipe tablearg ip from table(12) to any in via em1
02001 ngtee 65534 ip from any to any in via em1
02002 allow ip from any to any
02500 ngtee 65534 ip from any to any out via em1
02501 allow ip from any to any
03000 ngtee 65534 ip from any to any in via em1
03001 nat 1 ip from any to any out via em0
03002 allow ip from any to any
03500 ngtee 65534 ip from any to any out via em1
03501 allow ip from any to any
04000 ngtee 65534 ip from any to any in via em1
04001 allow ip from any to any
65535 allow ip from any to any

 

Собственно вопрос: возможно ли как-то распараллелить dummynet? Ибо запас по производительности ещё есть, так как совокупная нагрузка на проц шлюза ~30% и планируется догрузить его ещё 700 абонентами.

 

Заранее спасибо :)

Share this post


Link to post
Share on other sites
dev.em.0.%desc: Intel(R) PRO/1000 Network Connection 6.9.6.Yandex[$Revision: 1.36.2.8 $]
dev.em.0.%driver: em
dev.em.0.%location: slot=0 function=0
dev.em.0.%pnpinfo: vendor=0x8086 device=0x1096 subvendor=0x8086 subdevice=0x3476 class=0x020000
dev.em.0.%parent: pci4
dev.em.0.debug: -1
dev.em.0.stats: -1
dev.em.0.rx_kthreads: 4
dev.em.0.rx_int_delay: 250
dev.em.0.tx_int_delay: 250
dev.em.0.rx_abs_int_delay: 500
dev.em.0.tx_abs_int_delay: 500
dev.em.0.rx_kthread_priority: 127
dev.em.1.%desc: Intel(R) PRO/1000 Network Connection 6.9.6.Yandex[$Revision: 1.36.2.8 $]
dev.em.1.%driver: em
dev.em.1.%location: slot=0 function=1
dev.em.1.%pnpinfo: vendor=0x8086 device=0x1096 subvendor=0x8086 subdevice=0x3476 class=0x020000
dev.em.1.%parent: pci4
dev.em.1.debug: -1
dev.em.1.stats: -1
dev.em.1.rx_kthreads: 4
dev.em.1.rx_int_delay: 250
dev.em.1.tx_int_delay: 250
dev.em.1.rx_abs_int_delay: 500
dev.em.1.tx_abs_int_delay: 500
dev.em.1.rx_kthread_priority: 127
...
net.inet.ip.intr_queue_maxlen: 5120
net.inet.ip.forwarding: 1
net.inet.ip.fastforwarding: 1
...
net.inet.ip.dummynet.debug: 0
net.inet.ip.dummynet.pipe_byte_limit: 1048576
net.inet.ip.dummynet.pipe_slot_limit: 100
net.inet.ip.dummynet.io_pkt_drop: 899085190
net.inet.ip.dummynet.io_pkt_fast: 3971984921
net.inet.ip.dummynet.io_pkt: 958136342
net.inet.ip.dummynet.io_fast: 1
net.inet.ip.dummynet.tick_lost: 0
net.inet.ip.dummynet.tick_diff: 156233873
net.inet.ip.dummynet.tick_adjustment: 96367395
net.inet.ip.dummynet.tick_delta_sum: 7
net.inet.ip.dummynet.tick_delta: 503
net.inet.ip.dummynet.red_max_pkt_size: 1500
net.inet.ip.dummynet.red_avg_pkt_size: 512
net.inet.ip.dummynet.red_lookup_depth: 256
net.inet.ip.dummynet.max_chain_len: 16
net.inet.ip.dummynet.expire: 1
net.inet.ip.dummynet.search_steps: 0
net.inet.ip.dummynet.searches: 0
net.inet.ip.dummynet.extract_heap: 0
net.inet.ip.dummynet.ready_heap: 400
net.inet.ip.dummynet.curr_time: 1921183021
net.inet.ip.dummynet.hash_size: 64
...
net.inet.ip.fw.dyn_keepalive: 1
net.inet.ip.fw.dyn_short_lifetime: 5
net.inet.ip.fw.dyn_udp_lifetime: 10
net.inet.ip.fw.dyn_rst_lifetime: 1
net.inet.ip.fw.dyn_fin_lifetime: 1
net.inet.ip.fw.dyn_syn_lifetime: 20
net.inet.ip.fw.dyn_ack_lifetime: 300
net.inet.ip.fw.static_count: 31
net.inet.ip.fw.dyn_max: 4096
net.inet.ip.fw.dyn_count: 0
net.inet.ip.fw.curr_dyn_buckets: 256
net.inet.ip.fw.dyn_buckets: 256
net.inet.ip.fw.default_rule: 65535
net.inet.ip.fw.verbose_limit: 0
net.inet.ip.fw.verbose: 0
net.inet.ip.fw.debug: 0
net.inet.ip.fw.one_pass: 0
net.inet.ip.fw.autoinc_step: 1
net.inet.ip.fw.enable: 1

Share this post


Link to post
Share on other sites

net.isr ?

 

и полную комманду создания pipes

 

 

Ну и для начала -

 

dev.em.0.rx_int_delay: 1000

dev.em.0.tx_int_delay: 1000

dev.em.0.rx_abs_int_delay: 2000

dev.em.0.tx_abs_int_delay: 2000

dev.em.1.rx_int_delay: 1000

dev.em.1.tx_int_delay: 1000

dev.em.1.rx_abs_int_delay: 2000

dev.em.1.tx_abs_int_delay: 2000

 

 

 

и vmstat -i

 

Share this post


Link to post
Share on other sites

id - номер договора грубо говоря, bw - скорость

ipfw pipe <id> config bw <bw абона>Kbit/s queue 25 #pipe на входящий трафик

ipfw pipe <id + 32766> config bw <bw абона>Kbit/s queue 25 # pipe на исходящий трафик

 

net.isr.swi_count: 122159776
net.isr.drop: 0
net.isr.queued: 5093
net.isr.deferred: 0
net.isr.directed: -741084354
net.isr.count: -743769476
net.isr.direct: 1

interrupt                          total       rate
irq1: atkbd0                           8          0
irq14: ata0                            1          0
irq20: atapci1+                  9557788          1
cpu0: timer                   1918089054        259
irq256: em0                   1194304630        161
irq257: em1                   3589944981        484
cpu7: timer                   1917521160        258
cpu1: timer                   1918088982        259
cpu2: timer                   1915192574        258
cpu3: timer                   1915192589        258
cpu6: timer                   1917521161        258
cpu4: timer                   1918881586        259
cpu5: timer                   1918881965        259
Total                        20133176479       2718

 

Значения dev.em поменял

Edited by sid1333

Share this post


Link to post
Share on other sites

 

net.isr.direct=0

 

Поменять pipes на queue 100.

Share this post


Link to post
Share on other sites
net.isr.direct=0

 

Поменять pipes на queue 100.

Сделал

Помогло/нет не могу сказать. Сейчас нагрузка маленькая.

 

600Мбит/с и 140kpps в одну сторону проходят без проблем. Dummynet на это как-бы параллельно. Как с net.isr.direct=1 так и net.isr.direct=0

Может быть, дело в NAT? При большом количестве активных юзеров. Либо сам dummynet так себя ведёт при шейпинге?

 

Share this post


Link to post
Share on other sites
600Мбит/с и 140kpps в одну сторону проходят без проблем. Dummynet на это как-бы параллельно. Как с net.isr.direct=1 так и net.isr.direct=0

Может быть, дело в NAT? При большом количестве активных юзеров. Либо сам dummynet так себя ведёт при шейпинге?

Ну судя по тому, что у меня он себя так не ведет, это что-то в настройках. Правда у меня версия операционки старше.

Share this post


Link to post
Share on other sites
Ну судя по тому, что у меня он себя так не ведет, это что-то в настройках. Правда у меня версия операционки старше.
Может быть :) Настройки буду дальше ковырять. Но какое у вас количество абонентов через такой шлюз ходит?

 

Share this post


Link to post
Share on other sites
Может быть :) Настройки буду дальше ковырять. Но какое у вас количество абонентов через такой шлюз ходит?

Ну именно _такого_ шлюза у меня нет и быть не может. ;-) Зато абонентов и траффика поболее.

Share this post


Link to post
Share on other sites

В фаерволе вроде как всё оптимизированно по максимуму, если нет, подскажите что и где?

Это не оптимальный набор правил уже из-за того, что там сто раз повторяется одни и те же nat, ngtee, allow ip from any to any. Напишите один раз и пользуйтесь skipto. ngtee у вас делает лишнее копирование. Трафик для Netflow оптимальнее заворачивать с хуков сетевого интерфейса на ng_split, а с него уже на ng_netflow. Пример здесь: http://tmp.barev.net/htmlart/unix/ngnetflow.html

Edited by photon

Share this post


Link to post
Share on other sites
Имею PC шлюз на примерно 1700 абонентов, построен на FreeBSD 7.1-RELEASE-p2 на 2х 5410 Xeon.

Абоненты терминируются на L3 свичах, до шлюза бежит только трафик Интернет. Всё простой маршрутизацией без vlan'ов, em0 смотрит в инет, em1 - в локальную сеть. Сетевые em встроенные.

Помимо шейпа, работает ipfw nat и сбор статистики через ng_netflow.

1. Обновить до 7.2. в крайнем случае до 7.1p4

2. Перейти на однопроходный ipfw (заменить allow на pipe с соответсвующей переменной в sysctl, Netflow сделать как указано выше)

3. /usr/src/sys/netinet/ip_dummynet.c - там есть 2 строчки:

#define HASHSIZE 16

#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)

Поднять первую цифру (должна быть степень двойки), соответственным образом изменить маску в конце второй. Пересобрать ядро.

4. NAT в pf

 

Edited by Deac

Share this post


Link to post
Share on other sites
В фаерволе вроде как всё оптимизированно по максимуму, если нет, подскажите что и где?
Это не оптимальный набор правил уже из-за того, что там сто раз повторяется одни и те же nat, ngtee, allow ip from any to any. Напишите один раз и пользуйтесь skipto. ngtee у вас делает лишнее копирование. Трафик для Netflow оптимальнее заворачивать с хуков сетевого интерфейса на ng_split, а с него уже на ng_netflow. Пример здесь: http://tmp.barev.net/htmlart/unix/ngnetflow.html

Пакет проходит максимум 5 правил - для этого там и выставлены skipto tablearg в начале.

 

ip.fw.one_pass попробую, убрав netflow из ipfw как вы посоветовали. Единственное, что скорее всего трафик будет считаться даже если у абона доступ закрыт, но тот продолжает ломиться в инет... но это уже не особо к теме относится...

 

Deac, ваши советы также попробую.

Edited by sid1333

Share this post


Link to post
Share on other sites

1. Обновить до 7.2. в крайнем случае до 7.1p4

Просветите, что именно изменилось?

Share this post


Link to post
Share on other sites
1. Обновить до 7.2. в крайнем случае до 7.1p4
Просветите, что именно изменилось?

Например:

...

[amd64, i386] The FreeBSD virtual memory subsystem now supports fully transparent use of superpages for application memory; application memory pages are dynamically promoted to or demoted from superpages without any modification to application code. This change offers the benefit of large page sizes such as improved virtual memory efficiency and reduced TLB (translation lookaside buffer) misses without downsides like application changes and virtual memory inflexibility. This is disabled by default and can be enabled by setting a loader tunable vm.pmap.pg_ps_enabled to 1.

...

 

И ещё масса всего полезного и вкусного.

http://www.freebsd.org/releases/7.2R/relnotes-detailed.html

 

Share this post


Link to post
Share on other sites

уберите шейп входящего трафика (хотябы на 5 минут в период максимально нагрузки)

Share this post


Link to post
Share on other sites

уберите шейп входящего трафика (хотябы на 5 минут в период максимально нагрузки)

Попробую сегодня вечером

Share this post


Link to post
Share on other sites
3. /usr/src/sys/netinet/ip_dummynet.c - там есть 2 строчки:

#define HASHSIZE 16

#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)

на что влияет изменения этих строк?

Share this post


Link to post
Share on other sites
net.isr.direct=0

 

Поменять pipes на queue 100.

имеется ввиду поменять pipe на queue приатаченную к pipe если да то в чём физический смысл сего действия?

 

если увеличить очеред в pipe то почему именно 100?

Share this post


Link to post
Share on other sites
если увеличить очеред в pipe то почему именно 100?

Потому что 25 слотов на современных скоростях маловато.

Share this post


Link to post
Share on other sites
3. /usr/src/sys/netinet/ip_dummynet.c - там есть 2 строчки:

#define HASHSIZE 16

#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)

на что влияет изменения этих строк?

Подобные вопросы должно задавать в mail list FreeBSD, совет оттуда, хотя можешь и сам в исходниках покопаться, на то и opensource

 

Share this post


Link to post
Share on other sites
уберите шейп входящего трафика (хотябы на 5 минут в период максимально нагрузки)
Убрал. Нагрузка на dummynet спала на 15-25% примерно.

 

Собираю потихоньку систему на базе 7.2

Share this post


Link to post
Share on other sites
3. /usr/src/sys/netinet/ip_dummynet.c - там есть 2 строчки:

#define HASHSIZE 16

#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)

на что влияет изменения этих строк?

Ну человеку, имеющему представления о программировании, должно быть интуитивно понятно, что если некий хэш имеет слишком малый размер, то он очень быстро заполняется при большом числе одновременных соединений. Чтобы обработать все новые и новые пакеты dummynet вынужден удалять старые записи и вносить новые, пересчитывая ключ, вместо того, чтобы просто хранить записи в памяти. Такой хэш является узким местом и отнимает процессорное время.

Думаю, не стоит лезть в исходники без сильной нужды, т.к. самостоятельные исправления трудно поддерживать. Лучше сначала покрутить переменные sysctl.

 

Совпадение этих чисел

net.inet.ip.fw.curr_dyn_buckets: 256
net.inet.ip.fw.dyn_buckets: 256

говорит о том, что у вас забит хэш для динамических правил, нужно увеличить net.inet.ip.fw.dyn_buckets по крайней мере до 2048 и продолжать увеличивать до тех пор, пока curr_dyn_buckets не будет стабильно меньше, чем dyn_buckets.

Edited by photon

Share this post


Link to post
Share on other sites
3. /usr/src/sys/netinet/ip_dummynet.c - там есть 2 строчки:

#define HASHSIZE 16

#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & 0x0f)

на что влияет изменения этих строк?

Ну человеку, имеющему представления о программировании, должно быть интуитивно понятно, что если некий хэш имеет слишком малый размер, то он очень быстро заполняется при большом числе одновременных соединений. Чтобы обработать все новые и новые пакеты dummynet вынужден удалять старые записи и вносить новые, пересчитывая ключ, вместо того, чтобы просто хранить записи в памяти. Такой хэш является узким местом и отнимает процессорное время.

Думаю, не стоит лезть в исходники без сильной нужды, т.к. самостоятельные исправления трудно поддерживать. Лучше сначала покрутить переменные sysctl.

 

Совпадение этих чисел

net.inet.ip.fw.curr_dyn_buckets: 256
net.inet.ip.fw.dyn_buckets: 256

говорит о том, что у вас забит хэш для динамических правил, нужно увеличить net.inet.ip.fw.dyn_buckets по крайней мере до 2048 и продолжать увеличивать до тех пор, пока curr_dyn_buckets не будет стабильно меньше, чем dyn_buckets.

Если всё же покопаться в исходниках, то становится понятно, что именно указанный HASHSIZE, не тюнится из sysctl, значение его выбрано из компромиса между быстродействием и потребляемой памятью.

При сегодняшних объёмах оперативной памяти предпочтение стоит отдать быстродействию, рекомендую начать со значения HASHSIZE 64

Что касается переменных sysctl, то их изменение может осуществляться без пересборки ядра.

Например стоит увеличить net.inet.ip.dummynet.hash_size до 256

 

Share this post


Link to post
Share on other sites

хм, вот мне и не понятно нужно ли это мне, у меня например нету динамических пайпов (это каторый mask (src|dst)-ip ). Поможет ли оно мне.

или этот хеш работает в с указателям на статический пайп?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this