Про ручки или knobs



Тут недавно самый влиятельный на всю разработку в Google Titus Winters выступал на CppCon и CppRussia с докладом про ручки, конфигурации. Слайды можно посмотреть здесь. А именно глубоко личная для меня история была на слайде 47. Да, доклад слегка философский, но Titus уже такой человек, он должен учить так, чтобы другие вдохновлялись и глубоко думали.



Там показано про num_threads = 8 как пример плохой конфигурации в нашей MapReduce/Dataflow системе. По-русски их называют "ручками", но по-английски мне больше нравится слово knobs, смачнее звучит, что ли. Да, я один из людей, кто ответственный за эту функциональность. Наконец-то это вышло на публику в каком-то виде.



Typical prehistory



При обработке огромных массивов в абстрактном MapReduce/Dataflow мы в любом случае должны плодить много workers/jobs, притом на разных машинах, чтобы они в параллель обрабатывали данные. Как одно решение вы можете плодить здоровые такие воркеры по 40+ ядер на пустом кластере, а на другом конце есть решение, что вы можете плодить воркеры по 1 треду.



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



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



В году так 2010 один из наших разработчиков приклеил число 4 на количество тредов на воркер, и в целом оно неплохо работало. 4 треда казалось хорошим балансом, но как оно обычно бывает, это было просто сделано на глазок.



В Google Dataflow вы можете видеть эту настройку под numberOfWorkerHarnessThreads.



Это число продержалось 11 лет внутри.



Что поменялось?



Одним пятничным утром после пьянки(?) в 2020 мой техлид проснулся и вспомнил, что это число реально первый раз было закоммичено в 2010 году тем, кто вот вот покинул Google. Мы посидели и подумали, что хорошо бы это сделать как минимум 8, а то и 16. А в идеале вообще динамически.



С динамикой что-то пошло не так, потому что количество тредов это филигранный анализ между



- Удобством и скоростью упаковки по датацентру

- Оптимальности по памяти (если много тредов, больше памяти используется и кеш миссов, и в итоге перформанс деградирует)

- Выигрышу из fixed cost RAM немного CPU — люди иногда сохраняют SideInput на пару сотен мегабайт. В общем случае это баланс между CPU и RAM. А RAM и CPU стоят по-разному в разных датацентрах 🙂

- Не умереть по lock contention, если оно есть

- Убивать треды не самая простая задача из-за проблем с аллокацией этих же самых SideInput, их надо значит аллоцировать в каких-то неубиваемых тредах или уметь мигрировать память



Мы честно пытались решать это целый год, на что-то ответили слегка, на что-то вообще нет. Это очень интересная задача



В итоге провели эксперимент на 8, сэкономили свои X% по всему гуглу и выкатили.



Только послевкусие осталось. Какие-то пользователи перестали работать из-за проблем с памятью (больше тредов — больше памяти же на воркер), они откатились обратно на 4 в своих конфигах. И кажется некоторые из конфигов не тронутся годами после этого, ведь регулирование этой ручки решило их проблему.



Сегодня вечером я пытался настроить температуру воды из под крана, чтобы набрать ванную. Чуть-чуть влево и льётся кипяток, чуть-чуть вправо и уже ледяная вода. В этот момент я вспомнил Тайтаса и этот проект.



И кажется у меня нет выбора, и проект надо довести до конца в 2022. Мы просто убьём эту опцию, это единственный способ избавляться от ручек, просто делать их no-op. Это безумно сложная задача, но кто-то должен ответить на вопросы, потому что они не только интересные, но и полезные для понимания перфоманса всего флота датацентров.



Everything will get less terrible with time.



[1] Презентация Titus

[2] Dataflow pipeline options

[3] OOM worker harness email thread