Готовлю доклад на Highload и за время подготовки к докладу стал фанатом историй с продакшена. Ниже одна из таких историй. Если вы больше любите смотреть, чем читать, то есть видео на ютубе [1] начиная с 8-й минуты.
Нам нужно было kv-хранилище, чтобы очень быстро писать рекомендации и очень быстро читать. То есть не повезло, обычно всем нужно хранилище, которое, да пофиг, может медленно писать, главное чтобы быстро работало на чтение. А нам нужно было в обе стороны. Из кандидатов в чеклисте у нас там остался один тарантул. Это был где-то 2014 год, наверное, или 2015-й, не помню уже. Вот. А в тарантуле как раз поменяли движок. То есть изначально в тарантуле был lsm-tree движок. Пришел новый лид, он поменял, винил по-моему называется, я точно не помню. В общем поменяли движок с lsm-tree на другой, запись стал медленной. И просто так совпало, что к нам ходил пить пиво разработчик тарантула по пятницам и мы ему сказали: Как же так, чувак, ну классная же база, вы взяли всё сломали? Он говорит: Ну а что, говорит, дураки-то такие-то? Вообще ерунда, просто возьмите движок, который использовался в тарантуле, когда-то в самом первом тарантуле. Ну с чего начинался в тарантуле. Взяли движок, который тоже написали в мейле ребята там. Я даже ходил к ним в здание, у них там еще блины печёт автомат, я хотел пожать руку разработчику Sophia, но что-то так и постеснялся. Есть у них там такой серьезный дядька, он написал вот Sophia Systems. Это kv-движок с lsm-tree движком внутри и он, ну просто мы офигели, то есть там 500 тысяч в секунду запросто там, не знаю, жевал на чтение и на запись тоже соответственно. Очень хорошо работал. Вот, а у нас оставалось... Ну время еще было ограничено было, нужно было все соединить. Ну в общем он нас подбил, говорит "kv - это основная проблема, вы взяли её готовую. Осталось написать всё-таки сервер и всё. И в путь.". Мы написали на Java сокет-сервер. Ну потому что мы писали на Scala и Java. То есть программеры у меня были Java и Scala. Вот, и в общем в Scala прыжки в С небесплатные, как и в Go прыжки все не бесплатно, то есть дорогие. И получилось не очень оптимально. И мы баловались ещё, писали на Nim. Ну просто какие-то глупые клиенты для телеграмма там, не знаю. Ерунду какую-то. А Nim это транспилер в Си. И такие ради фана написали и заработало вроде, и причём прикольно заработало. То есть у него не было такого оверхеда в Си, потому что он в Си. Ну транспилится в Си и код получается сишный. Был еще вариант писать на плюсах, но плюсовик был в команде только один и соответственно это bus-фактор. То есть ну его собьёт автобус и некому будет поддерживать код. Вот поэтому плюсы откинули. А Си мы откинули потому что подумали что мы накосячим. Никто в команде Си у нас толком не знал. Вот и в общем на Nim мы все протестировал, очень быстро написали, буквально за пару недель, запустили. Выложили в прод и тут же он упал. Вот. Потому что в Nim оказалось ограничение. Но это вот просто я рассказываю прохладные истории, но еще не дошел до Гошки. Вот, это история из жизни. Ну типа, вроде все шло неплохо. И вот тебе сюрприз. В Nim оказался лимит на количество одновременно соединений в 255. Ну то есть разработчик языка Nim подумал, что 255 это и так достаточно много одновременных коннекшенов. А у нас их там было ну 70.000, то есть у нас на бэке была перлячка, перлячка размножается форканьем. То есть перлячка она как, она когда масштабируется она начинает форкаться так и всё идёт короче в одну дырку. И 60.000 идут в одну дырку, Nim вообще очень удивился. Вот, мы начали, а нужно уже запускаться, как бы не время, как бы нашли такую же проблему. У кого была она? Оказалась что такая же проблема была в Твиттере и они написали проксю, называлась она twemproxy, по-моему его переименовали в nutcracker, я не помню точно. Может быть так и остался. То есть у них было туча мемкешей и много коннекшенов, мемкеши были не рады и они написали прокси, который берёт кучу запросов, пайплайнит их и они так провозиком соответственно уезжают. То есть было 60.000 коннекшенов, мы их превратили там 200 и соответственно таким образом запатчили Nim и полетели. Где-то в декабре мы запустились, пережили Новый год успешно и в общем всё работало. Но осадочек остался что это какая-то фигня. ну потому что мы поправили прямо в языке. мы потом залезли в язык, там начали править и когда начали уже в языке править мы увидели там какие-то куски дна и поняли что это пилит один человек на парт-тайм и короче мы видим там прям ёшки-кошки, мы на этом как бы в прод выкатились. Переписали на Си короче потом через пару месяцев просто для того чтобы успокоиться. переписывал я, причем я Си не знал вообще, ну открыл как бы 10 проектов на гитхабе с похожими проектами, открыл книжку, прочитал до 4-й главы до указателей, там уснул, в общем отложил. Потом нашел книжку по libevent. libevent это такая библиотека которая делает всё за тебя. Это сокет-сервер, ну готовый фактически. Ну там есть и буфера, и вся работа с памятью, и аллокацией и всё это сделано очень прикольно. прямо есть книжка где просто ты берёшь и делаешь как там написано и всё работает. Главное ну нигде не опечататься, потому что у си есть такая особенность, что допустим мы написали программу, на Nim мы написали, тестировали, выкатили - упала. На Си написали, на Маке протестировали - всё работает, выкатили на убунту - на убунте упало. Нашёл ошибку в коде там, потом, ну теперь то уж всё точно нормально. Выкатили на debian и упала. Ну короче debian самый строгий судья, то есть Мак там выделяет там буфера допустим, чистят и все вообще прекрасно, пофиг на ошибки разработчика. Убунта она там чуть более такая уже там придирается, а debian он супер строгий там. То есть ты два байта выделил, он два байта дал. Ну и короче, короче на Си это был не (не разборчиво). Ну, то есть я писал, старался не ходить, не курить, потому что я забуду. И потом. В общем. Ну написали и всё было прекрасно в общем. И жили мы счастливо. Вот, мы начали переходить на гошку. Мы начали переходить на Go, этот момент это был где-то уже 2016 наверно. А не, не все было счастливо. София нас подвела, я забыл. Она падала каждые полгода. Это гораздо лучше было чем в кассандре, она не падала, у неё тот же самый питончик(?), тот же самый lsm-tree и какой-то мусор оставался. То есть через полгода она превращалась в терабайт ну и у нас кончалось место. и первый раз это было очень тревожно. То есть мне звонит админ и говорит: у тебя 6 часов, а потом всё станет колом. Ну типа, найдите что. Значит один разработчик сидел удалял не нужное там не знаю, а второй искал в чём проблема. вот, и это было очень тревожно. Ну первый раз тревожно, а потом мы уже были готовы к этой истории, мы уже начали мониторить размер базы и уже заранее готовились и просто за неделю, например, начинали дублировать в чистую базу записи, а потом просто подменяли базы. То есть мы обошли это костылем таким. Мониторили и просто это решали. Мы начали смотреть что есть вообще на Го из готовых ну вот движков. А почему не взять Софию и не прикрутить Го? cgo это не Go, есть такой. Ну во-первых, он в сто раз медленнее примерно, чем вызов нативной функции, то есть вызов сишной функции примерно в 100 раз медленнее. Но на самом деле это не главная проблема, там, если посмотреть на чиселке, как cocroachdb считали, там они что-то посчитали как-то подозрительно. Я уже когда потом подумал что-то подозрительно они 4 наносекунды вызов Го-функции, а 100 наносекунды прыжок в Си. То есть ну где-то в 100 раз медленнее. Но все это наносекунды это в принципе фигня. Ну потому что если у вас данные которые работают с диском, то там это 100 наносекунды это не так критично, но он ещё руинит какое-то повдеение с горутинами, они становятся более прожорливыми. Они становятся более и больше ждет памяти.
1. https://www.youtube.com/watch?v=tb_QCnBsFb4