А что писать про язык, который просто работает?
Да, он не самый удобный для всего на свете, не самый быстрый на свете, не самый элегантный.
Но он позволяет "get the job done", при этом без больших временных затрат на первом этапе, и помогая удобными профилировщиками на этапе оптимизации. При необходимость использовать другой язык для оптимизации (asm, C, C++) возникает намного реже, чем в других прикладных рантаймах.
А вообще, я до сих пор думаю, что, если бы JVM не выпилила в свое время свои зелёные потоки (или вовремя бы вернула), то Go бы не взлетел.
у фб мусор в датафайла, файлы распухают, все вокруг вынуждены делать много больше чтений, чем необходимо. требуется сборка мусора, что влечет тормоза и совершенно лишние приключения.
Тогда от PostgreSQL вы вообще бежите как черт от ладана?
вынуждена сразу писать в датафайлы, тогда как все конкуренты могут считать транзакцию подтвержденной после записи дельты в лог транзакций.
1) это не значит, что другие базы сразу в датафайлы не пишут. Пишут. Может не прям сразу, но пишут. Просто fsync делают только на log.
2) зато файербёрду не нужно прокручивать лог на старте в случае чего, не нужно иметь две сущности (датафайлы и лог). Если они смогли сделать так, что rps не сильно страдает, то чем же это плохо?
Конечно rps будет страдать. Но:
a) во многих охвученных применениях база локальна небольшому числу пользователей, а значит rps заведомо небольшой
б) некоторые озвученные применения подразумевают немаленький rps, а огнептах при этом справляется. Странно да?
Лог транзакций не является ценностью сам по себе. Это всего лишь инструмент решения задач. Если ОгнеПтах нашел другой инструмент, то что в этом плохого?
Автор как будто вышел из комы: водители всегда ставили нам оценки. Я несколько раз мешкался выбираясь из такси и видел, как его ставили. И год назад, и два.
Рейтинг у пассажира был всегда, просто теперь пассажир его видит.
> Т.е. 8 клиентов на 8 редис процессов могли бы идти по 8 сокетам. Все на разных ядрах.
А у вас 8 клиентов идут на 8 редис тредов через 1 сокет все в перемешку.
«Клиентов» в одном процессе — десятки. Редисов всего 96. Если по вашей логике, то это 1000 сокетов с одного только процесса клиента. А тачек клиентов у нас тоже не один десяток.
> А могло бы всё идти по разным сокетам и без конкурентности… В чём профит, непонятно. Разве что какие-то внутренние проблемы редиса с большим кол-вом сокетов.
Когда начнёте профилировать, поймёте: экономия цпу от 10% до 40%. Когда это экономится на клиенте, это не так может заметно. А вот когда в редисе, то очень чувствительно!
> сессии юзеров, фоновые задачи, csrf токены, межсервисные локи, различные другие токены, коды подтвеждений sms — всё отлично там хранится.
Т.е. любые данные, которые вроде и не хотелось бы потерять, но если потеряются, то и хрен с ними. Да, такое можно.
> у редиса два механизма записи на диск — снапшоты и AOF. не вижу повода не хранить там даже важные данные.
А я не вижу повода хранить:
— AOF и snapshot к сожалению друг о друге не знают.
— snapshot делается редко. Его рассматривать вообще нет смысла.
— запись в AOF идёт в том же треде. Если диск притормаживается (реплика подключилась), то всё встаёт колом. И ЧТЕНИЕ ТОЖЕ!
— а диск в том числе подтормаживает, когда AOF файл захотел сделать себе rewrite. Ну или если реплика приконнектилась.
— AOF не содержит номера команд. Потому Redis не может его использовать для наливки слейва. И слейв не может его использовать, если вдруг рестартанулся. Единственный выход у Редиса — откладывать новый снапшот (здравствуйте тормоза диска) и копить изменения в памяти. Чтобы отреплицировать 6ГБ инстанс мне приходится в настройках держать `client-output-buffer-limit replica 0 0 0` и `repl-backlog-size 200mb`.
Для сравнения, Tarantool:
— снапшоты и xlog файлы образуют единый механизм,
— xlog файлы содержат номер каждой операции
— реплика читает свой снапшот, проигрывает свои xlog и только после этого коннектится к мастеру и читает с последней операции
— мастер сперва шлёт данные с xlog файлов с нужного места (переслав перед этим уже готовый снапшота, если реплика новая или слишком отстала), и только когда реплика догоняет, переключается на inmemory посылку (емнип).
— данные в xlog пишутся в соседнем треде. Основной тред продолжает работу и спокойно обслуживает read запросы (и готовит к записи новые write запросы) даже если диск подтупил слегка.
Допустим, у нас Lua процедуры интенсивно используются в Redis. Но работают в основном с одним ключом (с одним Hash). В redis-cluster вообще сильно не попользуешься «разными ключами». Можно, конечно, если использовать фигурные скобки а-ля `namespace:{my-shard-key}-subkey`, но напряжно.
Интересно, почему они не стали хранить метаданные в одном ключе, сериализовав их в msgpack или protobuf? Запросы по метаданным все равно не будут сейчас быстрее работать, т.к. значения не в ключе. А места получается в несколько раз больше занимает, и локальность страдает. Кмк, в текущей схеме минусов больше, чем плюсов.
Ой да ладно. Проблемы с транзакциями существуют когда в одной транзакции трогается несколько ключей. Если же каждый раз щупается один ключ, то ни тебе дедлоков, ни тебе отката трагзакций. Все очень даже неплохо масштабируется, если правильно готовит.
Да, в редисе есть возможность использовать и что-то, что они называют транзакциями, и Lua процедуры. Но на практике этим пользуются невероятно редко.
Кстати, в KeyDB весь выигрыш только из распараллеливания сетевого взаимодействия. Вся работа с данными идет под глобальным локом.
Т.е.:
а) сетевое взаимодействие настолько накладно, что есть выигрыш от мношопоточности
б) типичная работа с данными настолько быстрая (в redis/keydb), что делать ее под глобальным локом не больно. А значит нет дедлоков и откатов транзакций.
в) конечно, если поставить keydb на 32 ядерную машину, проблемы от глобального лока начнутся. Так что им есть куда расти.
Вот я сейчас использую redis-cluster. 16 физических шардов по три процесса на сервер по две реплики. Т.е. 32 сервера, 48 редисных шардов, 96 редисных процессов. И я в серьез подумываю про KeyDB, т.к. это позволит мне сэкономить гору процессорного времени. Почему? Да потому что на 48 шардов очень плохо работает пайплайнинг запросов. А он экономит цпу как на клиенте, так и в самом редисе. А с keydb у меня будет всего 16 шардов.
Останавливает меня только репликация: сейчас каждый редисный шард по 6GB, и мне приходится применять не тривиальную конфигурацию, чтобы редис физически был способен отреплицировать после рестарта реплики без отвала по достижению своих внутренних лимитов. Я сильно сомневаюсь, что KeyDB сможет отреплицировать 18GB.
А что писать про язык, который просто работает?
Да, он не самый удобный для всего на свете, не самый быстрый на свете, не самый элегантный.
Но он позволяет "get the job done", при этом без больших временных затрат на первом этапе, и помогая удобными профилировщиками на этапе оптимизации. При необходимость использовать другой язык для оптимизации (asm, C, C++) возникает намного реже, чем в других прикладных рантаймах.
А вообще, я до сих пор думаю, что, если бы JVM не выпилила в свое время свои зелёные потоки (или вовремя бы вернула), то Go бы не взлетел.
Для систем с ограниченными ресурсами похоже что Go действительно не очень хорошо вписывается.
Странно, правда, что Dart при этот в рекомендуемых оставили. Видимо решили хотя бы один прикладной язык оставить.
Только А1 и медленнее раза в три. Так что, брать их можно только для тренировок.
А вот M6g нужно пробовать. Возможно они и правда хороши.
Тогда от PostgreSQL вы вообще бежите как черт от ладана?
1) это не значит, что другие базы сразу в датафайлы не пишут. Пишут. Может не прям сразу, но пишут. Просто fsync делают только на log.
2) зато файербёрду не нужно прокручивать лог на старте в случае чего, не нужно иметь две сущности (датафайлы и лог). Если они смогли сделать так, что rps не сильно страдает, то чем же это плохо?
Конечно rps будет страдать. Но:
a) во многих охвученных применениях база локальна небольшому числу пользователей, а значит rps заведомо небольшой
б) некоторые озвученные применения подразумевают немаленький rps, а огнептах при этом справляется. Странно да?
Лог транзакций не является ценностью сам по себе. Это всего лишь инструмент решения задач. Если ОгнеПтах нашел другой инструмент, то что в этом плохого?
SQLite3 очень шустро импортирует csv файл в пустую базу (в классическом режиме. С WAL тормозит). Тем более, если посортировать предварительно.
SQLite3
Сортированный файл, обьявленный как csv через встроенный импорт csv влетит пулей.
Автор как будто вышел из комы: водители всегда ставили нам оценки. Я несколько раз мешкался выбираясь из такси и видел, как его ставили. И год назад, и два.
Рейтинг у пассажира был всегда, просто теперь пассажир его видит.
Постгресс на двух сокетах ведет себя худе, чем нА одном. Т.е. можно тренироваться писать NUMA aware приложения
Проблема не в том, что копировали. А в том, что задвигали тех, кто мог сам делать.
У нас были и ученые, способные делать отечественные компьютеры и развивать отрасль. И разработки были свои.
Но советское руководство послало их на три буквы, и заставляло копировать.
Как я использую телефон, вряд ли я чаще 30 раз в день его раскладывал. Т.е. мне на три года бы хватило.
Но 100к у самсунга впечатляют больше.
А у вас 8 клиентов идут на 8 редис тредов через 1 сокет все в перемешку.
«Клиентов» в одном процессе — десятки. Редисов всего 96. Если по вашей логике, то это 1000 сокетов с одного только процесса клиента. А тачек клиентов у нас тоже не один десяток.
Когда начнёте профилировать, поймёте: экономия цпу от 10% до 40%. Когда это экономится на клиенте, это не так может заметно. А вот когда в редисе, то очень чувствительно!
С хорошим pipelining редис может миллион rps на половинке ядра выдать.
Т.е. любые данные, которые вроде и не хотелось бы потерять, но если потеряются, то и хрен с ними. Да, такое можно.
> у редиса два механизма записи на диск — снапшоты и AOF. не вижу повода не хранить там даже важные данные.
А я не вижу повода хранить:
— AOF и snapshot к сожалению друг о друге не знают.
— snapshot делается редко. Его рассматривать вообще нет смысла.
— запись в AOF идёт в том же треде. Если диск притормаживается (реплика подключилась), то всё встаёт колом. И ЧТЕНИЕ ТОЖЕ!
— а диск в том числе подтормаживает, когда AOF файл захотел сделать себе rewrite. Ну или если реплика приконнектилась.
— AOF не содержит номера команд. Потому Redis не может его использовать для наливки слейва. И слейв не может его использовать, если вдруг рестартанулся. Единственный выход у Редиса — откладывать новый снапшот (здравствуйте тормоза диска) и копить изменения в памяти. Чтобы отреплицировать 6ГБ инстанс мне приходится в настройках держать `client-output-buffer-limit replica 0 0 0` и `repl-backlog-size 200mb`.
Для сравнения, Tarantool:
— снапшоты и xlog файлы образуют единый механизм,
— xlog файлы содержат номер каждой операции
— реплика читает свой снапшот, проигрывает свои xlog и только после этого коннектится к мастеру и читает с последней операции
— мастер сперва шлёт данные с xlog файлов с нужного места (переслав перед этим уже готовый снапшота, если реплика новая или слишком отстала), и только когда реплика догоняет, переключается на inmemory посылку (емнип).
— данные в xlog пишутся в соседнем треде. Основной тред продолжает работу и спокойно обслуживает read запросы (и готовит к записи новые write запросы) даже если диск подтупил слегка.
А что я должен был понять?
Храните данные в Redis?… у вас стальные яйца, я вам скажу. Зная, как работает Redis, я бы не стал в нём ни чего хранить.
Если вам нужно inMemory, посмотрите хотя бы в сторону Tarantool. Он намного надёжнее в плане сохранности. А так же гибче. И вряд ли медленнее.
Будет. Оверхед от многопоточности в KeyDB — это взять мьютекс перед походом в хэш-мап, и отпустить после.
> И что за кейс где нужен пайплайнинг — это же не кэширование?
Как это «не кэширование»? У нас весь бэкенд шлёт до 2М запросов в секунду в редис именно за кешем. «не кэш» использования редиса у нас очень мало.
Просто наш коннектор умеет делать «прозрачный пайплайнинг», когда запросы из параллельных горутин в один сокет пишутся.
Интересно, почему они не стали хранить метаданные в одном ключе, сериализовав их в msgpack или protobuf? Запросы по метаданным все равно не будут сейчас быстрее работать, т.к. значения не в ключе. А места получается в несколько раз больше занимает, и локальность страдает. Кмк, в текущей схеме минусов больше, чем плюсов.
Ой да ладно. Проблемы с транзакциями существуют когда в одной транзакции трогается несколько ключей. Если же каждый раз щупается один ключ, то ни тебе дедлоков, ни тебе отката трагзакций. Все очень даже неплохо масштабируется, если правильно готовит.
Да, в редисе есть возможность использовать и что-то, что они называют транзакциями, и Lua процедуры. Но на практике этим пользуются невероятно редко.
Кстати, в KeyDB весь выигрыш только из распараллеливания сетевого взаимодействия. Вся работа с данными идет под глобальным локом.
Т.е.:
а) сетевое взаимодействие настолько накладно, что есть выигрыш от мношопоточности
б) типичная работа с данными настолько быстрая (в redis/keydb), что делать ее под глобальным локом не больно. А значит нет дедлоков и откатов транзакций.
в) конечно, если поставить keydb на 32 ядерную машину, проблемы от глобального лока начнутся. Так что им есть куда расти.
Вот я сейчас использую redis-cluster. 16 физических шардов по три процесса на сервер по две реплики. Т.е. 32 сервера, 48 редисных шардов, 96 редисных процессов. И я в серьез подумываю про KeyDB, т.к. это позволит мне сэкономить гору процессорного времени. Почему? Да потому что на 48 шардов очень плохо работает пайплайнинг запросов. А он экономит цпу как на клиенте, так и в самом редисе. А с keydb у меня будет всего 16 шардов.
Останавливает меня только репликация: сейчас каждый редисный шард по 6GB, и мне приходится применять не тривиальную конфигурацию, чтобы редис физически был способен отреплицировать после рестарта реплики без отвала по достижению своих внутренних лимитов. Я сильно сомневаюсь, что KeyDB сможет отреплицировать 18GB.