Size: a a a

2020 August 31

AR

Anton Revyako in ctodailychat
1) user_id 12 байт это сильно
2) content_id 10 байт  это сильно
3) date 4 байта тоже можено перепаковать, если очень захочется в 2 байта

хз сколько у вас юзеров и контента, но полагаю, что 4+4 байта вполне бы хватило. и того на все 10 байт, которые за сутки настучат 8 гигов на запись. Т.е. даже если прибавить оверхед структур данных в любой из баз - ну пусть 16 гигов в сутки.

хранить это можно приблизительно как угодно, хоть в своем демоне, хоть в редисе, хоть в посгре в unlogged таблице. хоть как. я ведь так понимаю, информация о прочтении - не самая ценная информация и может полежать в оперативе?

мы использовали вот такую штуку, когда очень надо было на запись и не очень на чтение
https://github.com/yinqiwen/ardb
источник

R

Ruslan in ctodailychat
Сергей Аксёнов
Ну окей, вот, например, боевая задачка: сервис "отметки о прочитанном".

Сервис хранит 30 дней истории просмотров юзерами контента строками вида:

user_id int96, content_id string(10), timestamp int32

На базу идёт нагрузка в 10000 RPS на запись блоками от 1 до 10 строк. Итого в таблице постоянно хранится примерно полтора триллиона строк. Понятно, что таблицу надо обрезать не реже чем раз в сутки, при этом не блокируя остальных операций.

Также идёт нагрузка в 3000 RPS запросов вида: "вот список content_id размером не более 1000 элементов, верни мне те из них, которые не были просмотрены юзером user_id", т.е. которых нет в таблице.

Ну и всякая мелочь типа "дай мне историю просмотренного контента для юзера", суммарно скажем ещё на 2000 RPS, для ровного счёта.

Сколько реплик и шардов Постгри нужно для реализации такого сервиса, и с какого раза удастся так его написать, чтобы он отвечал не более чем за 50ms и имел среднее время между инцидентами не менее 3 недель, а время восстановления не более часа?  Вопрос со звёздочкой: как будем делать и хранить бэкапы?
А постгря обязательное условие?
источник

AP

Alexander Panko in ctodailychat
Сергей Аксёнов
Вопрос на зачёт автоматом: как будем масштабировать при росте нагрузки в 2, 3 и 10 раз?
я бы начал с того что убрал бы из требований постгрес)
источник

СА

Сергей Аксёнов... in ctodailychat
Igor V
Очень мало входных данных.

1. Почему content_id это string? Там slug?
2. Почему надо обрезать не реже чем раз в сутки?
3.  Вот список content_id из 1000 элементов.. - эти 1000 элементов уникальны для каждого юзера  или стандартные для всех? Эти 1000 записей новые записи или вообще любые?
4.  Какие паттерны у пользователя. Какое отношение просмотренных vs. непросмотренных? Как часто требуется эта операция? Список нужен  пользователю или админу?
1. Так исторически сложилось. Внешне похоже на youtube video id.
2. Потому что за сутки добавляется 50 миллиардов записей и жаба душит хранить больше лишних данных. Ну и как-то понятно, что операция удаления тем дороже, чем больше данных надо удалять.
3. Это разные для всех юзеров наборы, 1000 - ограничение сверху, обычно 30-50-100. Выдача сервиса рекомендаций, из которой надо выкинуть уже просмотренное.
4. Пользователь листает контент со скоростью примерно 0.5 шт/сек, клиент отправляет отметки о прочтении раз в 5 секунд. Пользоователь запрашивает новый контент пачками по 25-50 штук, делает это примерно раз в минуту.
источник

СА

Сергей Аксёнов... in ctodailychat
Alexander Panko
я бы начал с того что убрал бы из требований постгрес)
Не, ну мне тут RDBMSники монгу унижают, зачем вообще иначе этот разговор заводить)
источник

AP

Alexander Panko in ctodailychat
Сергей Аксёнов
Не, ну мне тут RDBMSники монгу унижают, зачем вообще иначе этот разговор заводить)
ааа, пропустил, ок)
источник

IV

Igor V in ctodailychat
Сергей Аксёнов
1. Так исторически сложилось. Внешне похоже на youtube video id.
2. Потому что за сутки добавляется 50 миллиардов записей и жаба душит хранить больше лишних данных. Ну и как-то понятно, что операция удаления тем дороже, чем больше данных надо удалять.
3. Это разные для всех юзеров наборы, 1000 - ограничение сверху, обычно 30-50-100. Выдача сервиса рекомендаций, из которой надо выкинуть уже просмотренное.
4. Пользователь листает контент со скоростью примерно 0.5 шт/сек, клиент отправляет отметки о прочтении раз в 5 секунд. Пользоователь запрашивает новый контент пачками по 25-50 штук, делает это примерно раз в минуту.
так у вас монга. все нормально 🙂 нет смысла обсуждать как переделывать все неправильно на postgres
источник

Y

Yaroslav in ctodailychat
БуханкаХлеба_тролейбус.жпг
источник

AR

Anton Revyako in ctodailychat
Сергей Аксёнов
Не, ну мне тут RDBMSники монгу унижают, зачем вообще иначе этот разговор заводить)
ты натягиваешь сову на глобус. тут не нужна посгря (хотя при выше описаных изменениях справится), тут нужно другое решение. то, что ты мужественно заталкиваешь по 26 байт на запись в монгу (прибавь еще ключи, даже если ты их выбираешь по 1 букве, будет все 32), не делает все остальные решения плохими
источник

AP

Alexander Panko in ctodailychat
Сергей Аксёнов
1. Так исторически сложилось. Внешне похоже на youtube video id.
2. Потому что за сутки добавляется 50 миллиардов записей и жаба душит хранить больше лишних данных. Ну и как-то понятно, что операция удаления тем дороже, чем больше данных надо удалять.
3. Это разные для всех юзеров наборы, 1000 - ограничение сверху, обычно 30-50-100. Выдача сервиса рекомендаций, из которой надо выкинуть уже просмотренное.
4. Пользователь листает контент со скоростью примерно 0.5 шт/сек, клиент отправляет отметки о прочтении раз в 5 секунд. Пользоователь запрашивает новый контент пачками по 25-50 штук, делает это примерно раз в минуту.
я бы 2 версии проверил 1) можно ли хранить timestamp последнего просмотренного контента, а не все id 2) подумал бы на тему вероятностных оптимизаций, например для каждой единицы контента хранить bloom filter от user id которые его просмотрели и эти значения фильтров в памяти 1 раз для каждой единицы контента, и только если если фильтр не дает точного ответа перепроверять в базе
источник

СА

Сергей Аксёнов... in ctodailychat
Anton Revyako
1) user_id 12 байт это сильно
2) content_id 10 байт  это сильно
3) date 4 байта тоже можено перепаковать, если очень захочется в 2 байта

хз сколько у вас юзеров и контента, но полагаю, что 4+4 байта вполне бы хватило. и того на все 10 байт, которые за сутки настучат 8 гигов на запись. Т.е. даже если прибавить оверхед структур данных в любой из баз - ну пусть 16 гигов в сутки.

хранить это можно приблизительно как угодно, хоть в своем демоне, хоть в редисе, хоть в посгре в unlogged таблице. хоть как. я ведь так понимаю, информация о прочтении - не самая ценная информация и может полежать в оперативе?

мы использовали вот такую штуку, когда очень надо было на запись и не очень на чтение
https://github.com/yinqiwen/ardb
1) Mongo ContentID :)
2) Это строка, похожа на как у YouTube, чтобы URL были не слишком длинными и не слишком предсказуемыми.
3) Наверное можно, нужно чтобы хватило на 10 лет с секундным разрешением.

Даже 8 гигов в сутки = 0.25T в месяц. И хотелось бы как-то их не продолбать, иметь возможность бэкапить и восстанавливать при случае. А главное - нужен составной индекс user_id + content_id, желательно уникальный, но при этом чтобы просто дропал входящие дубликаты, а не заставлял как-то по другому с ними разбираться.
источник

AR

Anton Revyako in ctodailychat
Alexander Panko
я бы 2 версии проверил 1) можно ли хранить timestamp последнего просмотренного контента, а не все id 2) подумал бы на тему вероятностных оптимизаций, например для каждой единицы контента хранить bloom filter от user id которые его просмотрели и эти значения фильтров в памяти 1 раз для каждой единицы контента, и только если если фильтр не дает точного ответа перепроверять в базе
даже без этого redis+ardb вполне справятся с решением проблемы в несколько раз дешевле, чем монга.
источник

AR

Anton Revyako in ctodailychat
Сергей Аксёнов
1) Mongo ContentID :)
2) Это строка, похожа на как у YouTube, чтобы URL были не слишком длинными и не слишком предсказуемыми.
3) Наверное можно, нужно чтобы хватило на 10 лет с секундным разрешением.

Даже 8 гигов в сутки = 0.25T в месяц. И хотелось бы как-то их не продолбать, иметь возможность бэкапить и восстанавливать при случае. А главное - нужен составной индекс user_id + content_id, желательно уникальный, но при этом чтобы просто дропал входящие дубликаты, а не заставлял как-то по другому с ними разбираться.
1) ты сам в этом виноват
2) перепакуй, будет меньше
3) зачем тебе 10 лет, если ты хранишь только месяц? ))))

все что не влезет в оперативу, бекапишь на диск
источник

СА

Сергей Аксёнов... in ctodailychat
Alexander Panko
я бы 2 версии проверил 1) можно ли хранить timestamp последнего просмотренного контента, а не все id 2) подумал бы на тему вероятностных оптимизаций, например для каждой единицы контента хранить bloom filter от user id которые его просмотрели и эти значения фильтров в памяти 1 раз для каждой единицы контента, и только если если фильтр не дает точного ответа перепроверять в базе
1. Нельзя, у каждого пользователя своя сортировка и должна быть возможность запросить историю просмотра. Наверное я мог бы попробовать продать продактам идею "давайте сделаем кнопку bookmark как в Инстаграме, а историю просмотров хранить не будем", тогда наверное можно будет избавиться от timestamp.

2) мы думали про такой вариант и это потенциально было красиво, но давало только прирост производительности и никак особо не помогало со всем остальным, при этом было сложно в реализации и эксплуатации.
источник

AP

Alexander Panko in ctodailychat
Anton Revyako
даже без этого redis+ardb вполне справятся с решением проблемы в несколько раз дешевле, чем монга.
ну вопрос я так понял можно ли это сделать на postgres, то что не стоит - понятно, но можно ли вопрос интересный, я правда не в ту сторону предлагаю, если исключительно средставми postgres то без таблиц создаваемых на каждый день/неделю/месяц нужное подчеркнуть и еще шардинга по user/content id я думаю без шансов, соответственно задача сведется к управлению кучами таблиц и роутингу запросов в нужные
источник

СА

Сергей Аксёнов... in ctodailychat
Anton Revyako
1) ты сам в этом виноват
2) перепакуй, будет меньше
3) зачем тебе 10 лет, если ты хранишь только месяц? ))))

все что не влезет в оперативу, бекапишь на диск
3) а как тут художественно вырезать? Данные-то постоянно с одной стороны впихиваются, а с другой уходят в Валгаллу.
источник

IV

Igor V in ctodailychat
Сергей Аксёнов
1. Нельзя, у каждого пользователя своя сортировка и должна быть возможность запросить историю просмотра. Наверное я мог бы попробовать продать продактам идею "давайте сделаем кнопку bookmark как в Инстаграме, а историю просмотров хранить не будем", тогда наверное можно будет избавиться от timestamp.

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

AR

Anton Revyako in ctodailychat
Alexander Panko
ну вопрос я так понял можно ли это сделать на postgres, то что не стоит - понятно, но можно ли вопрос интересный, я правда не в ту сторону предлагаю, если исключительно средставми postgres то без таблиц создаваемых на каждый день/неделю/месяц нужное подчеркнуть и еще шардинга по user/content id я думаю без шансов, соответственно задача сведется к управлению кучами таблиц и роутингу запросов в нужные
не, вопрос в том, что монга - лекарство от всех болезней, но то что этот ваш постгрес) если расширить круг используемых технологий, то оказывется, что монга сливает не только в релиционных схемах, но и в других )
источник

СА

Сергей Аксёнов... in ctodailychat
Alexander Panko
ну вопрос я так понял можно ли это сделать на postgres, то что не стоит - понятно, но можно ли вопрос интересный, я правда не в ту сторону предлагаю, если исключительно средставми postgres то без таблиц создаваемых на каждый день/неделю/месяц нужное подчеркнуть и еще шардинга по user/content id я думаю без шансов, соответственно задача сведется к управлению кучами таблиц и роутингу запросов в нужные
Шардинг очевидно по user_id, это да. Если есть возможность сегментировать таблицы по суткам, но запросы в них делать прозрачно, как это делает clickhouse - это хороший вариант, можно просто дропать лишнюю таблицу каждый день.
источник

IV

Igor V in ctodailychat
Igor V
пользователь не может просмотреть контент раньше, чем контент был опубликован, поэтому достаточно хранить дельту, причем вполне можно в минутах
стоп. по просмотрам хотите сортировать…
источник