Pull to refresh

Comments 29

А почему бы не отдавать RSS каждому юзеру а в приложении подписывать уже на сами rss потоки?

Чтоб сформировать единый RSS для юзера нужно решить ту же самую задачу. RSS это просто формат выдачи в данном случае. У нас фактически такой же RSS, только в JSON формате.

Если вы храните id новости в ленте но за контентом, как я понял, ходите каждый раз в другой сервис, зачем нужен механизм с удалением новости из всех лент? Вырежте контент перед выдачей, в момент запроса данных пользователем, когда будете контент собирать по ID. А потом тихонько пометьте записи к удалению в бэкграунде.

Тоже вариант, но тогда получится что в ленте могут удалиться все новости и нечего будет показывать + появится лишняя логика при каждой выдаче (придётся не просто получить новость, а ещё вытаскивать все подписки пользователя и считать показывать ли новость)

Я конечно не знаю всей внутренней кухни, но, исходя из ваших цифр по объемам, возможно, достаточно было сделать таблицу news_id, tag_id, published_at. (денормализация новостей по тегам ..без денормализации по юзерам).

  1. Она по объему равнялась бы news_tags (что в тысячи раз меньше полной денормализации).

  2. Это гораздо проще в обслуживании

При полной денормализации у вас получился бы объем где то от 500млн. записей. Поэтому вам приходится усложнять систему за счёт "активных" пользователей, построения на лету и прочего. При денормализации без юзеров объем таблицы всегда равен объему таблицы news_tags (в принципе её можно даже убрать). При этом такая таблица/покрывающий индекс скорее всего полностью в оперативную память поместится.

P.S. когда вы пишите, что пользователь может быть подписан на сотни тегов, то... согласно вашим данным в среднем пользователь подписан на 16/5 чуть более 3х тегов. ..пусть будет 10 :)

Справедливо, но судя по тому что в статье сказано, тут рассказ упрощённый. И подписки у них могут быть не только на теги, но и на конкретных редакторов и на что-то там ещё. Это уже более сложный менеджмент и больше строк. Может поэтому другим путём пошли

Тоже не понимаю, зачем так усложнять себе жизнь дополнительным базами, когда достаточно таблицы с идентификаторами, наполняемыми триггерами

В статье это объяснил – с NoSQL удобнее обновлять и очищать данные. Для таблиц придётся делать ровно ту же логику, хранить и поддерживать бизнес-логику в коде удобнее, чем в триггерах.

я это не понял, что значит удобнее?

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

если все что будет добавлено в базу - это кеш-ссылки, это буквально мизер, данные и так уже есть, запросы потребуют минимум правки (убрать части, собирающие данные, так как они уже будут собраны тригерами) и вся проблема - чутчуть замедленное добавление данных

p.s. если вам нравится работать с готовыми сеарилизованными данными, тригерами добавляйте не списки id в М-к-М а json-чиками, нужно тестировать что будет быстрее и на сколько добавит это тормозов при добавлении тех же подписок (ведь придется обновлять весь json вместо добавления 1 записи), но сейчас еще хуже, ведь в соседнюю базу вообще кусок всего переезжает

Там есть запросы на выборку и обновление документов, которых нет в реляционных БД. Потому что Монго построена для работы с документами.

В книжке кабанчика высоко нагруженные системы писали про вашу задачу, про условный твиттер.

Если коротко то речь такая:

Если у автора мало подписчиков - мы платим за него при публикации. Если у автора огромное количество подписчиков мы платим за него при чтении.

То есть один запрос в монгу для непопулярных авторов, один запрос в вашу бд для популярных авторов. В конце мержите данные.

Решал такую же задачу, не стал ничего выдумывать и взял твитеровскую архитектуру - хранение в Redis, максимально быстро. Мастер данные в постгри, сервис ленты берет обновление из кафки.

Ну или как вариант - вместо редиса кликхаус (но это если он ещё для другого понадобится) или эластик.

Кликхауз очень плохо работает с частым обновлением

Кмк, решение уйти от sql - бесполезное.

Вы вот указываете формат хранения в монгоДб, а список тегов лежит внутри сложного объекта. Теперь надо перебрать все ленты в монгодб, в них перебрать все теги в поисках того, который есть в текущей новости. Ок, добавляем на это поле индекс. Судя по описанию - монгоДб делает примерно то же, что и обычная СУБД: выносит это в отдельную таблицу и делает там двоичное дерево со ссылками на исходные записи. Что существенно изменилось то? Таблица индекса, критичная для производительности - примерно та же с теми же принципами.

Ну а перенос расчета на запись с чтения вполне логичен. Тут меньше операций и меньше требований к скорости (ваш редактор 5 секунд без проблем подождет, а вот пользователь с каждой лентой так не будет).

В Монго удобнее работа с вложенными объектами, можно за один запрос найти все объекты с определенной новостью. В статье подробнее рассказал о преимуществах.

Чисто технически можно решить задачу и на sql и хранить также готовые ленты в реляционных таблицах

можно за один запрос найти все объекты с определенной новостью

я все равно не понимаю, что ж такого она делает нового?

в чем проблема в sql найти все объекты с определенной новостью? что join/union придется писать на каждый тип объекта? ну так и в монго вы скорее всего подобным будете заниматься - у вас же в ленте лишь id (т.е. ссылки, а сами объекты лежат в отдельных "документах) - все равно придется за ними сходить и это либо аналог join/union (что исполнится на стороне движка СУБД), либо что еще хуже - переход контекста выполнения в код и вызов вторым запросом оттуда.

Я подозреваю, что будет “переход контекста выполнения в код и вызов вторым запросом оттуда” - т.е. эта частичка стала работать хуже, чем было до этого.

Например, в Монго есть удобные операторы для поиска внутри объекта или для обновления части данных внутри json.

SQL плохо работает с json полями, там по сути надо всё поле обновлять.

то что вам как программисту очень удобно работать с json полями mongo не означает что драйвер (на стороне клиента) не выполняет все эти тяжелые операции десериализации и обратной сериализации всего объекта.

Ну что же, друзьям я на эту ленту уже жаловался, теперь и авторам могу пожаловаться. Специально открыл ещё раз её (стараюсь туда не заходить, это паноптикум какой-то)

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

Перехожу в "Мою ленту"

Вижу, что у меня ровно три любимые темы: Спартак, Валерий Карпин, Алессандро Дель Пьеро. Вроде понятно, что я хочу видеть. Разве это не логично, что, если я подписан на теги "Спартак" и "Алессандро Дель Пьеро", то я должен где-то иметь возможность увидеть все статьи, новости, посты (можно и без них) по этим тегам, желательно в хронологическом порядке, может с какими-то фильтрами?

Мои ожидания, мои проблемы, я знаю. Что я вижу в итоге?

Скрытый текст
  1. Новость: «Бешикташ» готов фиксированно заплатить 5 млн евро за Кисляка. Остальная часть предложения в 30 млн – в бонусах (Иван Карпов)

  2. Статья: В битву Рыбакиной и Соболенко за №1 рейтинга влезли еще две участницы. Вот все сценарии

  3. Пост: " СУМАСШЕДШИЙ ФАКТ: Килиан Мбаппе забил 86 голов за «Реал Мадрид» к началу своего третьего сезона в клубе."

  4. Новость: Экс-чемпион мира по снукеру Грэм Дотт признан виновным в сексуальном насилии над детьми

  5. Пост «Барселона» только что подписала все документы по сделке с Домиником Ливаковичем; подтверждаю — here we go now.

  6. Статья "Ударом разорвал сопернику яичко, дрался за стиралки, выступал до 50. Великий Роберто Дюра "

  7. Пост "Доминик Ливакович пройдёт медосмотр в качестве нового игрока «Барселоны» завтра. "

  8. Новость "«Бешикташ» через посредника заявил о готовности заплатить до 30 млн евро за Кисляка. ЦСКА исключил продажу хавбека (Иван Карпов) "

Это видимо Рекомендательная лента.

2 статьи и одну новость я уже увидел сегодня на главной, только кроме них я увидел ещё кучу всего, что сюда может и попало, но не будет увидено мной, т.к. количество мусора значительно больше: Посты идут каким-то валом (чуть ниже в ленте их уже по 4 подряд), местами и ещё и на одну тему (Ливакович). Две новости про Кисляка (ну то есть из интересов моих ML решил что мне интересно ЦСКА? серьёзно?). +Возможно веса подкручены в модельке в сторону постов.

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

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

Переключаюсь на подписки (это же та самая персональная лента наконец-то?). В подписках видно только авторов и блоги на которых подписаны, статьи там не увидишь. При этом, если ты подписан на блог, то в ленте на статье указан только автор и ты просто не понимаешь, почему у тебя Дуанель и Михаил Морозов видны, хотя ты на них не подписан. А оказывается они авторы блогов, на которые ты пописан, но это в ленте не видно.

Кроме того в ленте снова плывет хронология

Скрытый текст

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

Это мне очень напоминает мою волну от яндекс музыки. Где за два года мне не попалось ни одной песни 3 групп. отмеченных мной как любимые. Всего у меня отмечено любимыми было 5 групп.

Или как новости Москвы от мейл ру, где именно новостей Москвы - одна штука, остальное геополитика или про загнивающий запад.

Так что может это и вправду я такой неправильный со своими ожиданиями.

наконец научился печатать 100500 символов в минуту, но такая фигня получается

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

Наверное это тренд современности (в отличии от 10-15 лет назад) - делать максимально плохо и неудобно для пользователя.

Да, вы правы, это рекомендательная лента. Текущий алгоритм работает не идеально, о проблемах коллеги знают и прям сейчас ими занимаются.

вы уверены что это 'проблемы'? случайно такое поведение не сделать, это явно намеренное поведение.

В рекомендательное ленте используется МЛ-механизм для подбора постов. Сейчас он подбирает посты, которые не попадают в интересы пользователей. Это проблема и её исправляют.

Да и про персональную я ниже расписал. +Вы пишите

Именно о персональной ленте дальше и пойдёт речь

До этого момента мы рассматривали только новости. Но со временем персональная лента стала включать и пользовательский контент.

Добавляем посты

Помимо новостей появились блоги и посты. Пользователь может подписываться:

  • на теги (те же самые, что и в новостях)

Т.е. утверждается, что в персональной ленте есть новости и подписка по ним по тегам. Но по факту в персональной ленте только блоги и посты. А где новости?

Персональная лента с новостями есть в приложении, на сайте фильтр только по постам. Возможно в будущем и на сайте добавится.

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

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

Реально, я очень люблю ваш сайт, пользуюсь наверно где-то с 2000-2001, поэтому и бомбит так.

При таком объёме данных

На таких объёмах можно все в оперативной памяти хранить и собирать в реальном времени. Редис с ZSET или эластик с обратным индексом - думаю будет в пределах микросекунд.

не обязательно стороннее хранилище городить, ведь можно буквально все поместить в ram backend приложения (дублирование с базой данных), все кроме собственно данных (тексты) можно полностью уместить в оперативную память вместе с индексами (заточенными на работу с оперативкой), работать будет не хуже любых нагромождений из микросервисов и уж точно дешевле (для превышения сотен гигабайт потребуются иные объемы, на несколько порядков больше).

Sign up to leave a comment.

Articles