Menu

#20 using with billings witch use IPCAD for counting user trafic

open-works-for-me
nobody
5
2009-08-10
2009-08-06
No

I have found this module very interesting for my self using and thinking to moving my system to use it. but current configuration use ipcad for generating netflows for storing history (direct on disk) and ipcad RSH COMMANDS for collecting traffic amount. Such billing architecture.
So i start to think how to use this module.
I understand that i need to modify source code to add other hash table witch will hold just src_ip dest_ip packet_count total_bytes. and collect information like do it ipcad
1. need to add some flag witch will on/off such ipcad compatibility mode in /proc/net/stat/netflow/ like ipcad_compatibility_mode
2. need to add in /proc/net/stat/ipt_netflow_ipcad_checkpoint with full realized file_operations function for reading checkpoint table and ioctl to execute remembering check point command and clearing it

also will be need some easy user space deamon witch will listen and emulate rsh ipcad command
show ip accounting checkpoint - will just read /proc/net/stat/ipt_netflow_ipcad_checkpoint & send it in ipcad format
clear ip accounting - will use ioctl on /proc/net/stat/ipt_netflow_ipcad_checkpoint for remembering current in checkpoint account table and clearing current one
clear ip accounting checkpoint - will use ioctl on /proc/net/stat/ipt_netflow_ipcad_checkpoint for clearing check point table

i don`t know is some body need possibility to read current account table, if so tell me.
In a few days i will put some patches hire. So i need testers all of this.

also in current version i found some part witch can be optimized for smp environment where traffic balanced between cores.
in netflow_target function present working with lists under locks may be if it will be changed to _rcu funcitons like hlist_for_each_entry_rcu it will not need lock for multiply searching in parallel on smp, only will need lock for modification like add or remove item form list. But will be harder to implement change of hash size on fly. Also can be used read_lock write_lock primitives. I i will have possibility to test speed on have load on different variant of synchronizations on smp i will inform about that hire.

So if some body interesting in such thing please help in developing or testing.

Discussion

  • Evgen Bendyak

    Evgen Bendyak - 2009-08-06

    Also found funny things in netflow_target function
    in such part
    } else {
    /* ipt_netflow_list is sorted by access time:
    * most recently accessed flows are at head, old flows remain at tail
    * this function bubble up flow to the head */
    list_move(&nf->list, &ipt_netflow_list);
    }

    nf->nr\_packets++;
    nf->nr\_bytes += ntohs\(iph->tot\_len\);
    nf->ts\_last = jiffies;
    nf->tcp\_flags |= tcp\_flags;
    
    NETFLOW\_STAT\_INC\(pkt\_total\);
    NETFLOW\_STAT\_ADD\(traf\_total, ntohs\(iph->tot\_len\)\);
    
    if \(active\_needs\_export\(nf, active\_timeout \* HZ\)\) \{
        /\* ok, if this active flow to be exported
         \* bubble it to the tail \*/
        list\_move\_tail\(&nf->list, &ipt\_netflow\_list\);
    
        /\* Blog: I thought about forcing timer to wake up sooner if we have
         \* enough exportable flows, but in fact this doesn't have much sense,
         \* becasue this would only move flow data from one memory to another
         \* \(from our buffers to socket buffers, and socket buffers even have
         \* limited size\). But yes, this is disputable. \*/
    \}
    

    this line -> list_move(&nf->list, &ipt_netflow_list); must be putted in else of
    if (active_needs_export(nf, active_timeout * HZ)).
    Why ? Because, if flow (with big bit rate) must be exported so why it need all time before WORK "netflow_work" wakeup all time "run" from head to tail with each time then new packet arrives before netflow_work will made it work to export it.

     
  • ABC

    ABC - 2009-08-06

    > Why ? Because, if flow (with big bit rate) must be exported so why it need
    > all time before WORK "netflow_work" wakeup all time "run" from head to tail
    > with each time then new packet arrives before netflow_work will made it
    > work to export it.

    Can you say more clearly?

    Note:

    If flow need to be exported, it is by reason it's Full or Expiring (or Finishing).
    1) If flow is Expiring, it could account packets until it is Expired in work queue.
    2) If flow is Full it become 'transparent' and not worked much.

    Your suggestion only 'optimize' out list_move to the head in case flow is need exporting. But it will add redundant list_move for new flows. Plus list_move operation is really fast constant time pointer reassignment.

    What probably would be more worth is to remove "exporting and Full" flow from the hlist. But this situation should be is quite rare and not affect performance (not worth code addition). And/Or there could be added move to the top of hlist for all new flows. So high performance flow get top position in hash bucket. But that is also additional processing and could steal performance for other cases.

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-06

    Я так понял вы понимаете русский (по вашему мылу) если да то может мы на нем лучше изъяснятся будем?

     
  • ABC

    ABC - 2009-08-07

    ok

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-07

    Если возник вопрос, почему я так думаю про активный записи где вышел таймер сброса для активной записи, то могу сказать что у меня в районе 30% таких записей в трафике возникает. Ибо я сбрасываю записи раз в 5 минут. Я так подумал что да для новых будет лишняя операция, посему все можно реализовать так.

    nf->nr\_packets++;
    nf->nr\_bytes += ntohs\(iph->tot\_len\);
    nf->ts\_last = jiffies;
    nf->tcp\_flags |= tcp\_flags;
    

    } else {
    nf->nr_packets++;
    nf->nr_bytes += ntohs(iph->tot_len);
    nf->ts_last = jiffies;
    nf->tcp_flags |= tcp_flags;
    if (active_needs_export(nf, active_timeout * HZ)) {
    list_move_tail(&nf->list, &ipt_netflow_list);
    } else {
    list_move(&nf->list, &ipt_netflow_list);
    }
    }
    NETFLOW_STAT_INC(pkt_total);
    NETFLOW_STAT_ADD(traf_total, ntohs(iph->tot_len));

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-07

    Если возник вопрос, почему я так думаю про активный записи где вышел таймер сброса для активной записи, то могу сказать что у меня в районе 30% таких записей в трафике возникает. Ибо я сбрасываю записи раз в 5 минут. Я так подумал что да для новых будет лишняя операция, посему все можно реализовать так.

    nf->nr\_packets++;
    nf->nr\_bytes += ntohs\(iph->tot\_len\);
    nf->ts\_last = jiffies;
    nf->tcp\_flags |= tcp\_flags;
    

    } else {
    nf->nr_packets++;
    nf->nr_bytes += ntohs(iph->tot_len);
    nf->ts_last = jiffies;
    nf->tcp_flags |= tcp_flags;
    if (active_needs_export(nf, active_timeout * HZ)) {
    list_move_tail(&nf->list, &ipt_netflow_list);
    } else {
    list_move(&nf->list, &ipt_netflow_list);
    }
    }
    NETFLOW_STAT_INC(pkt_total);
    NETFLOW_STAT_ADD(traf_total, ntohs(iph->tot_len));

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-07

    А я пока занимаюсь реализацией агрегации как в ipcad как закончу и немного протестирую выложу сюда.

     
  • ABC

    ABC - 2009-08-08

    Т.е. вы предлагаете, оптимизировать для новых потоков, убрать у них лишнюю проверку if active_needs_export(), которая сводится для них к операции if (jiffies - nf->ts_first) > a_timeout). Думаю, это можно сделать, но это не даст заметного выигрыша в производительности, так как это очень быстрая операция. Но такая оптимизация корежит код - дублирование кода, и нужно помнить, что новый поток не может требовать экспорта, в случае с единичным RST пакетом в данном случае вообще экспорт будет происходить по разному со стандартной схемой - он будет экспортирован через таймаут, а не сразу.

    Лучше оптимизировать циклы.

     
  • ABC

    ABC - 2009-08-08

    Насчет вашей идей с ipcad, так как тут не форум, мало вероятно, что вас кто-то видит, кроме меня, поэтому рекомендую вынести ваше предложение на какой-либо форум типа http://forum.nag.ru/

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-08

    По поводу переноса в active_needs_export я не для того что бы новые не попадали, а что бы на существующих требующих екпорта не становился вперед списка а потом опять в конец не более. И там где новый флов можно оптимизировать ибо там не надо
    nf->nr_packets++;
    nf->nr_bytes += ntohs(iph->tot_len);
    nf->ts_last = jiffies;
    nf->tcp_flags |= tcp_flags;

    а можно

    nf->nr_packets=1;
    nf->nr_bytes = ntohs(iph->tot_len);
    nf->ts_last = jiffies;

    ибо это новый флов и чтения с озу (кеша) не нужно. Но согласен даст очень малый прирост, гораздо больше даст это оптимизация множественного доступа при поиске нужного флова. Я так подумал что есть еще способ но затратный к памяти это в параллель иметь массив спин_локов для каждой хеш ячейки, но согласен затратный метод по озу посему можно уменьшить этот размер массива локов (длина хеш масива)/32 (или сюда подобрать разные значения) это даст легкий множественный доступ к разным спискам хеш массива, в одном месте я применял такое так дало серьёзный прирост. По поводу рв_лока для хеш массива тоже можно но он даст меньший прирост по сравнению с разделением доступа к хеш массиву на разные зоны.

    По поводу ipcad да выложу на http://forum.nag.ru/ пусть народ тестирует.

     
  • ABC

    ABC - 2009-08-08

    1. Чтение в кэш все равно будет т.к. размер cache line 32-64 байта и для записи (вместо сложения) этот участок памяти все равно сначала считается в кэш. Оптимизируется же не работа с L1 кэшем, а взаимодействие кэша с памятью (за счет оптимальной рабоыт с L1 кэшем), так как работа с L1 кэшем очень быстрая, по сравнению с работой с обычной памятью. В данном случае, как я уже сказал, все равно будет прочитан участок памяти в кэш, так что это оптимизации кэша не даст.

    2. Понятно про list_move/list_move_tail, это можно сделать. Но на мой взгляд эта оптимизация незначительная и практически не даст заметного выигрыша, по сравнению с тем, что даст простое увеличение хэш таблицы.

    Модуль требует ручной настройки размера хэша в соответствии с bandwidth пользователя, это отмечено в README, но возможно не все обращают на это внимание.

    3. Насчет оптимизации локов доступа к хешу. Это конечно тема интересная. ПО поводу рвлока, не думаю что получится его использовать. Если занчение в хэше не найдено, то нужно его в неё добавить сохраняя состояние хеша (ненайденность). А перехода между read_lock во write_lock не существует, а разлочивать таблицу тоже нелья.

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-08

    по 1. и 2 пункту согласен. По 3 пункту переход возможен только при закрытии read_lock и ожидания write_lock можно легко делать ибо любая балансировка трафика на процессоры гарантирует, что один и тот же флов будет идти через один и тот же процессор. А даже если так получится что случайно трафик перебросится на другой маршрут и придет сразу с двух сетевух, то ну создатся один флов дополнительный который при следующем поиске просто не будет увеличиваться и по тайм ауту сбросится и все.
    Но все равно надо будет маленький короткий лок при работе со списком что используется для сортировки по времени доступа и сброса фловов. И по идее не нужна блокировка конкретного флова ибо опять же как писал выше про балансировку, хотя если он сбрасывается и должен удалится то есть вопросы надо к _rcu спискам идти. Думаю наибольший прирост даст это разбить хеш массив на группы доступа со своими локами и отдельный лок для работы с список временной сортировки, хотя если как вы сказали держать хеш масив в слабо заполненном состоянии и удерживать число поисков сравнений в конкретной ячейке хеша в оптимальной величине в пределах 3-4 сравнений или менее, то думаю будет выигрыш такой же как и с разбиением доступа на группы хеш ячеек.
    Возможно автоматизировать принятие решение а увеличении размера хеш массива. Типа по таймеру (раз в минуту например) если максимальный пик фловов превышает порог хеш масива, то надо увеличить его на определенную градацию (создать массив соответствий, типа если количество фловов в таких то предела, то размер хеша такой-то) И дать возможность параметром, включать этот алгоритм он и избавит от вопросов с размеров таблицы.

     
  • ABC

    ABC - 2009-08-08

    1. Что любая балансировка трафика привязвает потоки к процессору - мне про это не известно или я не помню, чтоб такое кем-то гарантирвалось. (Тем более обычный балансинг, это четные пакеты туда нечетные сюда.) Соотв. по умолчанию я считаю, что пакеты в конкретный поток могут приходить любому процессору.
    2. Если "закрывать read_lock и ожидать write_lock", то нужно при write_lock снова делать поиск в хэше, чтоб небыло дублирующихся потоков. (Дополнительные затраты).
    3. Обсужденеи оптимизации думаю стоит вести в контексте оптимального размера хэша (в два раза больше кол-ва потоков).

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-08

    1. Балансирование на коммутаторах портов LINK AGGREGATION сделано с учетом того чтобы исключить пакет реордеринг. там считается хеш и делится на количество портов балансировки (в общем тот же хеш масив). В линухе bond тоже есть такой режим. А по поводу пакет туда следующий в следующую сетевуху, это плохо ибо при нагрузке может возникнуть пакет реордеринг, тсп очень странно отреагирует на такое подумает что предыдущий потерялся и будут все вытекающие от сюда проблемы.
    2. Если есть гарантия с 1 пункту то все ок, если нет то да абсурдно еще одну проверку делать.
    3. 100% согласен, а как идея про авто оптимизатор этого параметра.

    Из всего самое оптимальное, это идея про авто оптимизатор размера кеша.

     
  • ABC

    ABC - 2009-08-09

    3. Идея рассматривалась, но не была реализована. Вместо этого указание в README пользователям настраивать размер hash вручную под ожидаемый поток. Возможно, стоит это реализовать...

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-10
    • status: open --> open-works-for-me
     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-10

    выложил на тестирование на http://forum.nag.ru/forum/index.php?showtopic=50524

     
  • Evgen Bendyak

    Evgen Bendyak - 2009-08-10

    уже работает на 2 шлюзах боевых где вечерняя нагрузка за 2гигабита зашкаливала посмотрим что теперь оно сможет выдавить из себя без айпикада. и плюс увижу как по памяти оно работает. Вы бы не могли просмотреть исходники что, я выложил на наге может что заметно станет. Хотя уже пару легких ляпов в функции инициализации модуля, которые мало на что влияют, нашел и исправил, завтра обновлю на наге.

     

Log in to post a comment.