Спасибо за ответ и указание на TCQ_F_NOLOCK. A нашел что в 4.14 версии ядра, на котором мы видели эту проблему, нет никакой TCQ_F_NOLOCK, поэтому возможно стоит поновее ядро взять, хотя не понятно на сколько это поможет, так как в sch_direct_xmit все равно spinlock. Ну и да, у нас были pfifo_fast под mq, а так же не сбалансированная нагрузка по очередям, с которой тоже пришлось повозиться.
Спасибо за интересную статью, Леонид. Достаточно глубокий, не повседневный топик, при этом легко читать. Надеюсь, видеть побольше таких статей на хабре.
Мне тоже приходилось сталкиваться с похожей проблемой, когда сетевой трафик начинал шейпится, и это вызывало скачки CPU. perf показывал тот же стек, что в этой статье с native_queued_spin_lock_slowpath. Однако в моем случае, это была mq qdisc, и как я узнал, из данной статься, она должна быть не блокирующей (v4.14.198 версия ядра, на всякий случай), т.е. CPU от spinlock не должно быть? Перечитывая статью и, взглянув на упомянутый __dev_xmit_skb, мне стало не понятно, почему не блокирующая qdisc должна помочь, ведь `spinlock_t *root_lock = qdisc_lock(q);` берется на уровень выше и его тип всегда spinlock_t, независимо от типа qdisc. Или дело в том, что не блокирующая qdisc дает то, что внутри критического блока, поток будет проводить много меньше времени, таким образом другим потокам не придется жечь CPU? Вообщем, очень интересно Ваше мнение на этот счет.
Ага, спасибо, Руслан. Очень разумно звучит. Особенно понравились твои рассуждения про old-gen, про это я вообще ничего не писал и не задумывался даже об этом.
Если у вашего логера есть метод finalize, то нужно исопльзовать защитную технику: в логгере должен быть волатайл флаг, который выставляется при его финализации, а все метод логирования сначала проверяют этот флаг.
Проект большой, в том числе есть задачи которые можно решать локальным off-heap кэшом. Выборочные апдейты, выборочное чтение и фильтрация действительно много используются. К тому же если есть логика тесно связанная с данными, почему бы ей не находиться в том же процессе на удаленных распределенных кэшах.
Ключом может быть любой java объект. У нас это обычно лонги, они все же в хипе лежат, большие объекты в виде ключей, могут свести на нет все усилия освобождения heap. Как на картинке нарисовано, ключи лежат по сути в обычной хешмапе, а значение — адрес в памяти процесса вне хипа.
Для сериализации используем отдельно описанную логику. Эта логика так же позволяет делать выборку и апдейты отдельных полей по сдвигам от изначального адреса.
А какое у вас железо и сколько секунд паузы на минорных сборках и stop-the-world фазах CMS?
У нас все таки в памяти хранятся десятки гигабайт, используется commodity железо и CPU отдыхает.
Это было так давно, что вряд ли уже сможем поднять какую-то статистику. Сейчас при разработке любого функционала, мы сразу понимаем, в каком случае у нас могут возникнуть проблемы с GC и сразу делаем компонент с off-heap хранилищем, так что сейчас сложно сказать.
Oracle Coherence опять же совсем не дешевый и не open-source, что затрудняет с ним работу. К тому же, на сколько я знаю, off-heap конфигурация в Oracle Coherence появилась 2,5 года назад, нам же потребовалось решать проблемы с GC немного раньше.
Когда писался описанный фреймворк, azul еще не предлагал своего решения в этом плане. К тому же он платный и требует другую jvm. Текущее решение вполне удовлетворяет, поэтому в данный момент не рассматриваем.
Я смотрю данный топик побудил уже третью публикацию о CAP-теореме, что меня конечно же не может не радовать. Я сначала сомневался, писать или нет об этом всём. Думал закидают же тухлыми помидорами. Ан нет, действительно нашлось о чем поговорить!
Спасибо за ответ и указание на TCQ_F_NOLOCK. A нашел что в 4.14 версии ядра, на котором мы видели эту проблему, нет никакой TCQ_F_NOLOCK, поэтому возможно стоит поновее ядро взять, хотя не понятно на сколько это поможет, так как в sch_direct_xmit все равно spinlock. Ну и да, у нас были pfifo_fast под mq, а так же не сбалансированная нагрузка по очередям, с которой тоже пришлось повозиться.
Спасибо за интересную статью, Леонид. Достаточно глубокий, не повседневный топик, при этом легко читать. Надеюсь, видеть побольше таких статей на хабре.
Мне тоже приходилось сталкиваться с похожей проблемой, когда сетевой трафик начинал шейпится, и это вызывало скачки CPU. perf показывал тот же стек, что в этой статье с native_queued_spin_lock_slowpath. Однако в моем случае, это была mq qdisc, и как я узнал, из данной статься, она должна быть не блокирующей (v4.14.198 версия ядра, на всякий случай), т.е. CPU от spinlock не должно быть? Перечитывая статью и, взглянув на упомянутый __dev_xmit_skb, мне стало не понятно, почему не блокирующая qdisc должна помочь, ведь `spinlock_t *root_lock = qdisc_lock(q);` берется на уровень выше и его тип всегда spinlock_t, независимо от типа qdisc. Или дело в том, что не блокирующая qdisc дает то, что внутри критического блока, поток будет проводить много меньше времени, таким образом другим потокам не придется жечь CPU? Вообщем, очень интересно Ваше мнение на этот счет.
И про второе дополнение тоже спасибо.
Для сериализации используем отдельно описанную логику. Эта логика так же позволяет делать выборку и апдейты отдельных полей по сдвигам от изначального адреса.
У нас все таки в памяти хранятся десятки гигабайт, используется commodity железо и CPU отдыхает.