Pull to refresh
1
0
xfox@xfox

User

Send message
lol. вообще, я разрабатываю тот самый мой круг, который ты упомянул в суе в своем посте.
«база просела» и «использовать хранимые процедуры» — вещи никак не связанные. с таким же успехом можно написать запросы, которые не попадут в индекс и база так же просядет, так что это не аргумент.

вот эти патчи dklab.ru/lib/dklab_postgresql_patch/ делают пересечение очень быстро.
А вы меряли?
В posgresql массивы можно пересечь на базе, не гоняя данные по сети. Тем более — третьи круги. Для пользователя, у которого всего лишь 50 контактов третий насчитывает уже тысячи (и чем выше связность сети — тем больше)
Я к тому, что 0,3 — 0,5 секунд на построение цепочки это очень много, ведь такие цепочки нужно строить в реальном времени. Вы совсем не описали, как производили измерения. Если A и B в первом-втором круге друг у друга — цепочка должна получаться мгновенно.
«цепочки для 300к пользователей» = цепочки, в которой от А до B — 300к человек?
Имхо это плохая рекомендация.

1. Очень странно, починив один тест не прогнать сразу же все тесты еще раз, и ждать билда раз в сутки (Кстати, у вас правда такая большая система, что собирается 5-6 часов? Мб стоит гонять тесты чаще?)

2. Тесты должны быть понятными. Их должно быть просто читать. Должно быть понятно где сломалось. Если в тесте делается пара десятков проверок и делается их конъюнкция то с ходу понять какое условие не прошло не ясно. Не говоря уже о том, что код теста усложняется и создаются условия для появления ошибок в самих тестах.
особенно интересно насчет окончания места на диске — вам не кажется, что в таком случае то уже и смысла нет в его дальнейшей работе как таковой

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

о да, а если выключится компьютер, планета остановится, или того хуже — у меня закончится кофе!

тогда и пишите во введении, что у вас пост про код с кучей концептуальных!!! багов (дедлок, это как раз концептуальный баг в многопоточной программе) а не про «понимания основных принципов работы многопоточных приложений»
Да, вы правы. У вас 100% говонокод.
Что будет с вашими потоками, если отвалиться сеть, или гугл начнет отдавать 404? Они повиснут, т.к очередь никогда не отчиститься.
Что будет, если кончится место на диске? Потоки зависнут, т.к после взятия лока вылетит исключение на open(), и лок уже не будет освобожден.

То, что код работает и в нем много комментариев — не причина демонстрировать его, называя статью «основы работы с потоками».

Хороший пример работы с потоками — github.com/svetlyak40wt/couchdb-performance-tests/blob/master/couchdb_bulk_perf.py
имел ввиду не 60 000, а 6000, конечно
было это достаточно давно, могу наврать сильно. на практике при вставке в 10 потоков получалось около то ли 10000, то ли 60000 вставок в секунду. ни параметров стенда, не конфигурации базы я и подавно не помню. нужно стрелять в конкретно вашу кофнигурацию.
«много вставок» абстрактное понятие. нужно провести нагрузочное тестирование и посмотреть, сколько конкурентных вставок держит база. на моей практике цифра получилась ооочень достойная, перекрывшая прогнозируемую потребность на порядок.

в принципе, таблицу очереди тоже можно побить на шарды, например по id пользователя, создавшего событие. хотя при этом схема получается по сложнее.
Более того, я предлагаю чистить таблицу с очередью
не совсем понял, что такое центральная БД. если вы имели ввиду, что таблица с очередью будет в центральной БД — то конечно нет, ее нужно выносить в отдельную базу.
1. Как связан формат данных и место, где они хранятся?
2. Если правильно выбрать способ хранения, ничего никуда передавать не потребуется.
Проходить по всем пользователям не нужно. Нужно проходить только по пользователям, чья лента изменилась.

Модель, которая мне кажется более удачной:

Есть таблица с очередью, в которую заносится событие вида «Пользователь1 сделал запись в блог», «Пользователь2 загрузил фото». Очередь централизованная без шардов.
Есть таблица с лентами пользователей. Таблица разбита на шарды по тому же принципу что и пользователи.
Есть таблица с подписками вида (Пользователь3 читает Пользователя1 и Пользователя2)

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

Плюсы, по сравнению с вашей схемой — нет избыточности в хранении события в N очередях, где N-число подписчиков, не нужно обходить всех пользователей для построения ленты. Доставку сообщения в ленту можно ускорить, если вместо крона использовать демона.
А если в 3.14159 раз хуже — то плохая. Поделитесь результатами тестов?
Еще один непонятный момент. В примере вы в кроне выгребаете все события из очереди для конкретного пользователя. Получается, для того чтобы обновить все ленты на сайте нужно пройтись по всем пользователям?? А если их N * 10 ^6?
Еще вопрос, к чему абзац о пропуске первых 14тысяч сообщений после отпуска, если сообщения достаются из очереди кроном каждый час?
Или пример не удачный, или вы используете инструмент не по назначению. RabbitMQ используется для обмена сообщениями, где кроме надежности требуется еще и низкая задержка доставки. А в примере у вас он — просто persistence для модели publish-subcribe, который можно легко реализовать на нескольких таблицах в БД.

Например, у вас есть пользователь с 1000 знакомых, которые хотят прочитать его события. Когда он делает запись в блог — RabbitMQ придется доставить 1000 сообщений подписчикам (я конечно надеюсь, что он не хранит 1000 экземпляров в памяти). Судя по примеру — скорость доставки вам не важна. Тогда зачем держать очередь на доставку 1000 сообщений, если можно хранить 1 запись о событии и в кроне распихивать уведомления в ленты подписчиков?
А по вашему, сообщения, извлеченные из очереди, сохраняются не в БД для дальнейшего отображения пользователю?

Information

Rating
Does not participate
Registered
Activity