Прошли два месяца работы с тарантулом, и я наконец осознал (и отладил) адекватный способ хранить там слабо структурированную информацию: отправлять туда массив байтов byte[] из c#, а внутри тарантула соответствующее поле - string.
Принимать - тоже byte[]. string в тарантуле лежит просто как произвольная последовательность байт. Соответственно, никто не мешает хранить в этой куче байтов guid, который иначе без лишних преобразований из c# в тарантул не прокинуть.
Или - сериализовать в байты структуру (struct в c#, что-то типа класса, но хранится в стеке), или, вообще, использовать protobuf.
#tarantool
#кодинг
Принимать - тоже byte[]. string в тарантуле лежит просто как произвольная последовательность байт. Соответственно, никто не мешает хранить в этой куче байтов guid, который иначе без лишних преобразований из c# в тарантул не прокинуть.
Или - сериализовать в байты структуру (struct в c#, что-то типа класса, но хранится в стеке), или, вообще, использовать protobuf.
#tarantool
#кодинг
👍3
В условиях микросервисной архитектуры важную роль играют брокеры сообщений - обычно RabbitMQ или Kafka.
В кратце, соотношение плюсов и минусов между такое:
RabbitMQ - просто и сердито.
Kafka - сложнее, но лучше масштабируемо + возможность хранить историю прошедших сообщений.
Узнал еще преимущество Kafka: она оказывается умеет напрямую работать с базами данных: MongoDB, Tarantool, PostgreSQL, без самописных прослоек.
В кратце, соотношение плюсов и минусов между такое:
RabbitMQ - просто и сердито.
Kafka - сложнее, но лучше масштабируемо + возможность хранить историю прошедших сообщений.
Узнал еще преимущество Kafka: она оказывается умеет напрямую работать с базами данных: MongoDB, Tarantool, PostgreSQL, без самописных прослоек.
👍3
Впервые нашёл применение такому паттерну синхронизации межпоточного взаимодействия как семафор. Если в 2х словах, он ограничивает число потоков, проходящих через него. Поставил условные 50, и если к нему придут одновременно 1000 потоков, возникнет затор из ожидающих.
Я умудрился положить монгу большим числом параллельных запросов, при некоторых условиях их выстреливало больше 1000 сразу, после чего монга начинала кричать "остановись, демон" и кидала исключение. Семафор на 60 потоков меня спас, теперь всё отлично.
Я умудрился положить монгу большим числом параллельных запросов, при некоторых условиях их выстреливало больше 1000 сразу, после чего монга начинала кричать "остановись, демон" и кидала исключение. Семафор на 60 потоков меня спас, теперь всё отлично.
Docs
Semaphore Class (System.Threading)
Limits the number of threads that can access a resource or pool of resources concurrently.
👍3
Погружаюсь в зловонную яму бездны фронтенда, а если точнее - React.js
Вообще забавно, вроде бы фреймворк и фреймворк. Но по факту - отдельный язык для описания юзер интерфейса. При том, внутри самого реакта есть как минимум два совершенно разных (стилистически) подхода к написанию кода: функциональный и псевдо-ООП.
Пока псевдоООП кажется каким-то уродством, но под него больше примеров и учебников, так что пока кушаю кактус.
#front
#react
Вообще забавно, вроде бы фреймворк и фреймворк. Но по факту - отдельный язык для описания юзер интерфейса. При том, внутри самого реакта есть как минимум два совершенно разных (стилистически) подхода к написанию кода: функциональный и псевдо-ООП.
Пока псевдоООП кажется каким-то уродством, но под него больше примеров и учебников, так что пока кушаю кактус.
#front
#react
👍5
Самый любимый человек - жена - завела канал, про книги, детские и взрослые.
Если кому интересна квантовая механика 0+ или развлекательное фентази - добро пожаловать.
P.S. Мы теперь семья блоггеров:)
Если кому интересна квантовая механика 0+ или развлекательное фентази - добро пожаловать.
P.S. Мы теперь семья блоггеров:)
Telegram
Фига с книгой
О том, как я повелась на рекламу и потом пожалела о покупке книг: часть 1
📚 Крис Ферри "Квантовая физика для малышей", "Электромагнетизм для малышей"
Мой муж физик по образованию. Да и я сама целых три семестра в университете учила физику, на экзаменах…
📚 Крис Ферри "Квантовая физика для малышей", "Электромагнетизм для малышей"
Мой муж физик по образованию. Да и я сама целых три семестра в университете учила физику, на экзаменах…
👍6❤1
В одном чате была затронута тема электробезопасности, потому выложу сюда байку по теме.
В далёкие светлые времена, когда я учился на инженера-оптика, в мае, во время сдачи лабораторных работ, сидел я в лабе и что-то делал за компом. По-моему, колдовал с цифровым осциллографом, но это не точно.
Комп был между двумя лабораторными стендами: здоровенными заземленными чугуниевыми рэльсами, на которых стояли всякие оптические компоненты.
В какой-то момент, пошевелившись, я дотронулся локтями до обоих стендов сразу и меня от души шарахнуло током. Выяснил, что бьётся левый.
Одногруппники мне не поверили, потому трое по очереди брались за стенд под напряжением одной рукой и за "землю" - второй стенд - другой. Все соответственно получили. Откопали мультиметр - померяли - 220В.
Пришел завкаф, принимавший у нас лабы, не поверил. Взялся за стенды и выдал что-то про эмпирический опыт.
Причина нашлась быстро: для простоты подключения земли к стендам его сделали в виде обычной пары вилка-розетка и вот наконец настал момент, когда вилку на одном из стендов воткнули не туда.
В далёкие светлые времена, когда я учился на инженера-оптика, в мае, во время сдачи лабораторных работ, сидел я в лабе и что-то делал за компом. По-моему, колдовал с цифровым осциллографом, но это не точно.
Комп был между двумя лабораторными стендами: здоровенными заземленными чугуниевыми рэльсами, на которых стояли всякие оптические компоненты.
В какой-то момент, пошевелившись, я дотронулся локтями до обоих стендов сразу и меня от души шарахнуло током. Выяснил, что бьётся левый.
Одногруппники мне не поверили, потому трое по очереди брались за стенд под напряжением одной рукой и за "землю" - второй стенд - другой. Все соответственно получили. Откопали мультиметр - померяли - 220В.
Пришел завкаф, принимавший у нас лабы, не поверил. Взялся за стенды и выдал что-то про эмпирический опыт.
Причина нашлась быстро: для простоты подключения земли к стендам его сделали в виде обычной пары вилка-розетка и вот наконец настал момент, когда вилку на одном из стендов воткнули не туда.
🔥19
Эшу быдлокодит
Погружаюсь в зловонную яму бездны фронтенда, а если точнее - React.js Вообще забавно, вроде бы фреймворк и фреймворк. Но по факту - отдельный язык для описания юзер интерфейса. При том, внутри самого реакта есть как минимум два совершенно разных (стилистически)…
Превращение человека в дачника во фронтендера стремительно и необратимо (с)
Вроде бы начал осознавать функциональные компоненты вместе с хранилищем состояний - Redux-ом. А React-то прикольный! Похоже, в стадиях заражения js-ом как мыслевирусом я сразу перепрыгнул на 5ю ступень.
На задворках сознания появилось желание вернуться к диссертации и сделать UI десктопного приложения на связке react + electron.
#front
#кодинг
Вроде бы начал осознавать функциональные компоненты вместе с хранилищем состояний - Redux-ом. А React-то прикольный! Похоже, в стадиях заражения js-ом как мыслевирусом я сразу перепрыгнул на 5ю ступень.
На задворках сознания появилось желание вернуться к диссертации и сделать UI десктопного приложения на связке react + electron.
#front
#кодинг
Хабр
JavaScript как мыслевирус
Вообще я стараюсь не писать статьи и комментарии не на технические темы, но коль скоро появились не совсем технические по духу статьи «JavaScript как явление» и...
👍1
Тут в одном чатике помянули, что в программировании чудес не бывает, в отличие от электроники. Небольшой пример из тёмного прошлого.
Класс интерпретатора js внутри c# с вероятностью 10% создаётся косячным и при попытке использования (то есть интерпретации километрового js-скрипта) плюёт пустой эксепшн (без описания проблемы).
Воспроизводится только на 64 битах, 32 битная (которая использовалась при дебаге в те времена по дефолту) версия отрабатывает идеально.
При этом, ошибка несмертельна: происходит циклическая обработка некритичных данных, одна итерация завалилась - переварится на следующей итерации.
И вот наступил момент запуска в прод, 64 бита и нагрузка. Пиковая нагрузка, внезапно съедается 100% ЦПУ, машина виснет (эксепшн - довольно тяжёлая операция). На поиск проблемы у меня-джуна ушло около месяца.
P.S. Это было в легаси коде.
#байки
Класс интерпретатора js внутри c# с вероятностью 10% создаётся косячным и при попытке использования (то есть интерпретации километрового js-скрипта) плюёт пустой эксепшн (без описания проблемы).
Воспроизводится только на 64 битах, 32 битная (которая использовалась при дебаге в те времена по дефолту) версия отрабатывает идеально.
При этом, ошибка несмертельна: происходит циклическая обработка некритичных данных, одна итерация завалилась - переварится на следующей итерации.
И вот наступил момент запуска в прод, 64 бита и нагрузка. Пиковая нагрузка, внезапно съедается 100% ЦПУ, машина виснет (эксепшн - довольно тяжёлая операция). На поиск проблемы у меня-джуна ушло около месяца.
P.S. Это было в легаси коде.
#байки
🔥3
Эшу быдлокодит
Тут в одном чатике помянули, что в программировании чудес не бывает, в отличие от электроники. Небольшой пример из тёмного прошлого. Класс интерпретатора js внутри c# с вероятностью 10% создаётся косячным и при попытке использования (то есть интерпретации…
Да, починилось всё очень просто: вместо создания экземпляра интерпретатора для каждого запуска скрипта (хз зачем так было сделано) я стал использовать синглтон, который создавался рекурсивно и проверялся простым скриптом "а = 0".
Небольшая ремарка о монге.
Некоторое время назад меня поразило поведение массовой записи в MongoDB (это когда ты берешь несколько тысяч документов и кидаешь их на запись одной командой).
Если появляются дублирующиеся ключи - кидается исключение. Логично было бы ожидать, что запись всей пачки будет отменена. Но нет: все документы, которые могут провалятся в базу.
А если эксплуатировать эту особенность для очистки данных от дублей - при некотором критическом пороге монга просто падает.
Возможно, есть обходные пути, но поведение "из коробки" - такое.
#кодинг
#mongodb
Некоторое время назад меня поразило поведение массовой записи в MongoDB (это когда ты берешь несколько тысяч документов и кидаешь их на запись одной командой).
Если появляются дублирующиеся ключи - кидается исключение. Логично было бы ожидать, что запись всей пачки будет отменена. Но нет: все документы, которые могут провалятся в базу.
А если эксплуатировать эту особенность для очистки данных от дублей - при некотором критическом пороге монга просто падает.
Возможно, есть обходные пути, но поведение "из коробки" - такое.
#кодинг
#mongodb
Наткнулся на подборку небольших околонаучных бложиков от уважаемого @trueresearch
Читал еще не все каналы, но подборка прям огонь:
Читал еще не все каналы, но подборка прям огонь:
Forwarded from Русский research
Наступает пора конференций и отпусков, когда мой канал традиционно снижает активность. Тем не менее, я остаюсь на связи в комментариях и через @RResearcherBot, а посты продолжат иногда выходить — просто не слишком регулярно.
Тем временем мир научно-образовательного телеграма продолжает расцветать, и я хочу познакомить подписчиков с небольшими (пока) каналами, которые порекомендовали неравнодушные читатели и авторы в комментариях под недавним постом. Я убрал из подборки агрегаторы, официальные каналы организаций и просто крупные каналы, отдав предпочтение неформальному авторскому жизнеописанию и лёгкому научпопу. Привожу в произвольном порядке, иногда вместе с личным впечатлением по последним постам.
Авторское о жизни в науке и образовании:
https://www.tg-me.com/seryogaBombit - задорно-ироничный блог новоиспечённого кандидата технических наук
https://www.tg-me.com/consordino - блог почвоведа, личные мысли автора, рассказы о работе и немного научпопа
https://www.tg-me.com/VetusDepartment - замолкавшая и восставшая недавно Старая кафедра
https://www.tg-me.com/kavunnaya - блог квантово-механического теоретика
https://www.tg-me.com/sciencylife - живой канал биолога, немного в стиле Твиттера
https://www.tg-me.com/mikhail_ignatov31 - канал преподавателя философии из Белгорода
https://www.tg-me.com/tisnu_channel - о книгах и науке
https://www.tg-me.com/ragootootoo - блог преподавателя, с честными историями из жизни родной кафедры
https://www.tg-me.com/kantius - канал Анны Кулешовой об этике публикаций и многом другом
https://www.tg-me.com/Halls_of_Pilipenko - канал сурового проректора (наиболее живой из виденных мной аналогичных каналов)
https://www.tg-me.com/TiberiusRu - канал химика-материаловеда из Швейцарии
С уклоном в научпоп:
https://www.tg-me.com/newbioethics – блог о биотехнологиях
https://www.tg-me.com/sciscent - научный канал о духах (которые во флаконе, а не на спиритическом сеансе)
https://www.tg-me.com/ananikovlab - канал научной школы академика Ананикова
https://www.tg-me.com/memory_studies - про исследования памяти и истории, с юмором
https://www.tg-me.com/tozhe_nauka - прекрасный микроскопический канал о математических методах в литературоведении
https://www.tg-me.com/courageous_geologist - фоточки и мемы от геологов
https://www.tg-me.com/macevagram - исследования еврейских кладбищ
https://www.tg-me.com/georg_chronicles - что-то на инженерном
https://www.tg-me.com/radio_73 - ламповейший канал радиолюбителя, если не сказать радиофила
Тем временем мир научно-образовательного телеграма продолжает расцветать, и я хочу познакомить подписчиков с небольшими (пока) каналами, которые порекомендовали неравнодушные читатели и авторы в комментариях под недавним постом. Я убрал из подборки агрегаторы, официальные каналы организаций и просто крупные каналы, отдав предпочтение неформальному авторскому жизнеописанию и лёгкому научпопу. Привожу в произвольном порядке, иногда вместе с личным впечатлением по последним постам.
Авторское о жизни в науке и образовании:
https://www.tg-me.com/seryogaBombit - задорно-ироничный блог новоиспечённого кандидата технических наук
https://www.tg-me.com/consordino - блог почвоведа, личные мысли автора, рассказы о работе и немного научпопа
https://www.tg-me.com/VetusDepartment - замолкавшая и восставшая недавно Старая кафедра
https://www.tg-me.com/kavunnaya - блог квантово-механического теоретика
https://www.tg-me.com/sciencylife - живой канал биолога, немного в стиле Твиттера
https://www.tg-me.com/mikhail_ignatov31 - канал преподавателя философии из Белгорода
https://www.tg-me.com/tisnu_channel - о книгах и науке
https://www.tg-me.com/ragootootoo - блог преподавателя, с честными историями из жизни родной кафедры
https://www.tg-me.com/kantius - канал Анны Кулешовой об этике публикаций и многом другом
https://www.tg-me.com/Halls_of_Pilipenko - канал сурового проректора (наиболее живой из виденных мной аналогичных каналов)
https://www.tg-me.com/TiberiusRu - канал химика-материаловеда из Швейцарии
С уклоном в научпоп:
https://www.tg-me.com/newbioethics – блог о биотехнологиях
https://www.tg-me.com/sciscent - научный канал о духах (которые во флаконе, а не на спиритическом сеансе)
https://www.tg-me.com/ananikovlab - канал научной школы академика Ананикова
https://www.tg-me.com/memory_studies - про исследования памяти и истории, с юмором
https://www.tg-me.com/tozhe_nauka - прекрасный микроскопический канал о математических методах в литературоведении
https://www.tg-me.com/courageous_geologist - фоточки и мемы от геологов
https://www.tg-me.com/macevagram - исследования еврейских кладбищ
https://www.tg-me.com/georg_chronicles - что-то на инженерном
https://www.tg-me.com/radio_73 - ламповейший канал радиолюбителя, если не сказать радиофила
Спустя всего 1.5 года работы с докером через Visual Studio я обнаружил, что можно прямо из неё без боли залезть в файловую систему запущенного контейнера и посмотреть, а что там собственно происходит (например - посмотреть логи или конфиги).
Всё это время я шёл true linux-way: цеплялся к контейнеру и прыгал по файловой системе через консоль, для просмотра текста используя vi.
Всё это время я шёл true linux-way: цеплялся к контейнеру и прыгал по файловой системе через консоль, для просмотра текста используя vi.
🔥9
Больше года я ходил вокруг стека ELK, думая, что вот надо, надо. Но никак не складывалось. И вот стукнуло: пора.
ELK - стандартное средство для сбора, хранения и визуализации логов. Расшифровывается как Elasticsearch (поиск и хранение) + Logstash (собор из разнородных источников) + Kibana (Визуализация).
Попытался завести в докере вместе со всем остальным решением образ sebp/elk. Не взлетело: не хватило оперативки (у меня было 16 Гб). Ну чтож, добавил её, стало 64.
Взлетело! Процесс vmmem, который по сути является внутренним линуксом винды, стал есть 36 Гб (!).
Относительно быстро разобрался, как писать логи стандартным инструментом Serilog из c# напрямую в эластик, соответственно Logstash стал мне не нужен, отключил его запуск в контейнере с elk.
В целом, впечатление достаточно приятное, даже при том, что я использую его только на 1%, как средство просмотра логов. Со временем подключу туда данные из Prometheus и можно будет запилить красивеньких дашбордов для мониторинга проекта.
#кодинг
ELK - стандартное средство для сбора, хранения и визуализации логов. Расшифровывается как Elasticsearch (поиск и хранение) + Logstash (собор из разнородных источников) + Kibana (Визуализация).
Попытался завести в докере вместе со всем остальным решением образ sebp/elk. Не взлетело: не хватило оперативки (у меня было 16 Гб). Ну чтож, добавил её, стало 64.
Взлетело! Процесс vmmem, который по сути является внутренним линуксом винды, стал есть 36 Гб (!).
Относительно быстро разобрался, как писать логи стандартным инструментом Serilog из c# напрямую в эластик, соответственно Logstash стал мне не нужен, отключил его запуск в контейнере с elk.
В целом, впечатление достаточно приятное, даже при том, что я использую его только на 1%, как средство просмотра логов. Со временем подключу туда данные из Prometheus и можно будет запилить красивеньких дашбордов для мониторинга проекта.
#кодинг
Elastic
Elastic Stack: (ELK) Elasticsearch, Kibana & Logstash
Reliably and securely take data from any source, in any format, then search, analyze, and visualize it in real time.
Как нормальные люди пишут тесты? Выявляют кейсы, которые надо протестировать, пилят в той или иной форме генератор тестовых данных, покрывают кейсы тестами, а потом гоняют их и радуются.
Если структура данных сложная, а вникать в суть происходящего лень - велик соблазн выгрузить пул данных из базы, сохранить в каком-то виде (например - штук 500 json файликов в специальной папочке в проекте с тестами) и на этой сохраненке и гонять тесты.
Я попробовал, больше не буду идти на поводу у низменных желаний. Тесты написались мгновенно, закрыли существенную часть бизнес логики, всё просто отлично. Я продолжил работу над проектом и каждый раз при провале теста мне приходилось разбирать происшествие с двух сторон: что я сломал? Хм, вроде ничего. А теперь посмотрим юзеркейс и добьёмся воспроизводимости.
Времени на отработку битых данных было потрачено столько, что намного быстрее было бы просто написать нормальные тесты и двигаться дальше.
#кодинг
Если структура данных сложная, а вникать в суть происходящего лень - велик соблазн выгрузить пул данных из базы, сохранить в каком-то виде (например - штук 500 json файликов в специальной папочке в проекте с тестами) и на этой сохраненке и гонять тесты.
Я попробовал, больше не буду идти на поводу у низменных желаний. Тесты написались мгновенно, закрыли существенную часть бизнес логики, всё просто отлично. Я продолжил работу над проектом и каждый раз при провале теста мне приходилось разбирать происшествие с двух сторон: что я сломал? Хм, вроде ничего. А теперь посмотрим юзеркейс и добьёмся воспроизводимости.
Времени на отработку битых данных было потрачено столько, что намного быстрее было бы просто написать нормальные тесты и двигаться дальше.
#кодинг
👍1
Палантир. Часть 25. Рефлексия год спустя.
#палантир@eshu_coding
Описание получившейся системы можно посмотреть по ссылке. Одной из некритичных ошибок была попытка сделать шину данных из костылей и велосипедов на gRPC вместо использования стандартного решения типа RabbitMQ.
Возможно, я сколько-то выиграл в производительности, но ценой этого был отказ от персистентности пропускаемых через шину данных и использование страшненьких костылей для подключения дополнительных потребителей данных.
Если мне надо раздвоить поток данных, уведя копию на другой сервис - в RabbitMQ требуется просто подключиться к нему, указав источник данных и новую очередь.
Мне пришлось вкрячивать внутрь приемника данных от сборщиков сервис подписок, чтобы данные сразу по получении рассылались всем кто подключен. Персистентность? Гарантированная доставка? Не, это не наш метод.
В принципе, ошибка крайне неэстетичная, но на функциональность особого влияния не оказывающая.
#палантир@eshu_coding
Описание получившейся системы можно посмотреть по ссылке. Одной из некритичных ошибок была попытка сделать шину данных из костылей и велосипедов на gRPC вместо использования стандартного решения типа RabbitMQ.
Возможно, я сколько-то выиграл в производительности, но ценой этого был отказ от персистентности пропускаемых через шину данных и использование страшненьких костылей для подключения дополнительных потребителей данных.
Если мне надо раздвоить поток данных, уведя копию на другой сервис - в RabbitMQ требуется просто подключиться к нему, указав источник данных и новую очередь.
Мне пришлось вкрячивать внутрь приемника данных от сборщиков сервис подписок, чтобы данные сразу по получении рассылались всем кто подключен. Персистентность? Гарантированная доставка? Не, это не наш метод.
В принципе, ошибка крайне неэстетичная, но на функциональность особого влияния не оказывающая.
👍4🔥1
Палантир. Часть 26. Рефлексия год спустя.
#палантир@eshu_coding
Описание получившейся системы можно посмотреть по ссылке. Намного менее приятной ошибкой было скатывание к монолиту. Центральный сервис (БД на postgresql + надстройка на шарпе) у меня выполнял четыре основные функции:
1. Прием и укладка данных в БД
2. Анализ БД и выдача заданий сборщикам
3. Поисковые кэш и запросы к нему.
4. Анализ потока входящей информации на наличие ключевых слов и выдача оповещений при обнаружении.
Данные попадали в надстройку над БД, проталкивались в базу огромными транзакциями, заодно обновляя служебные таблицы для выдачи заданий сборщикам. Индекс для полнотекстового поиска был построен прямо в основной таблице, поисковые запросы соответственно летели к ней. Триггер, срабатывающий на вставление новых данных, запускал цепочку других триггеров, в которых осуществлялся анализ добавляемого текста. В случае соответствия забитым в базу поисковым паттернам - база отправляла во внешний мир оповещение с помощью функции pg_notify.
В итоге такой подход вылился в жуткую боль как по администрированию, так и по поддержке. В конечном итоге, я вытащил функционал (4) в отдельный сервис, но боль от этого не сильно уменьшилась.
Как на мой нынешний взгляд надо было сделать:
1. Использовать RabbitMQ вместо самопала на gRPC (см прошлый пост)
2. Отработать запись данных в БД. Накрыть тестами функционал.
3. Запустить отдельным сервисом постановку задач сборщикам. Накрыть тестами функционал. Скорее всего, после окончательной отладки этот сервис сольётся с п. 2. Я начал делать их вместе, в итоге так и не смог до конца искоренить дублирование выгружаемых сообщений.
4. Завести отдельную пару сервис + бд для поискового кэша. Сделать как обновление в реальном времени, отведя с помощью RabbitMQ поток данных в сторону + предусмотреть функционал "перелива" данных из основной базы. Теперь я не привязан в PostgreSQL rum индексу на базе дефолтного словаря! И можно экспериментировать с поисковыми движками как душе угодно, не нарушая функциональность основного сервера. Хоть эластик попробовать, хоть сделать прослойку на питоне для умной обработки текста готовыми инструментами.
5. Отвести поток данных для анализа в реальном времени (для выдачи оповещений пользователям) и экспериментировать сколько душе угодно.
P.S. "Отвести поток данных" в случае RabbitMQ значит добавить несколько символов в месте подключения клиентской библиотеки.
P.P.S. Никто не мешает после отладки функционала по отдельности вернуться к монолиту, например для повышения быстродействия. Если закладывать такую возможность на старте - это дело 1-2 дней.
#палантир@eshu_coding
Описание получившейся системы можно посмотреть по ссылке. Намного менее приятной ошибкой было скатывание к монолиту. Центральный сервис (БД на postgresql + надстройка на шарпе) у меня выполнял четыре основные функции:
1. Прием и укладка данных в БД
2. Анализ БД и выдача заданий сборщикам
3. Поисковые кэш и запросы к нему.
4. Анализ потока входящей информации на наличие ключевых слов и выдача оповещений при обнаружении.
Данные попадали в надстройку над БД, проталкивались в базу огромными транзакциями, заодно обновляя служебные таблицы для выдачи заданий сборщикам. Индекс для полнотекстового поиска был построен прямо в основной таблице, поисковые запросы соответственно летели к ней. Триггер, срабатывающий на вставление новых данных, запускал цепочку других триггеров, в которых осуществлялся анализ добавляемого текста. В случае соответствия забитым в базу поисковым паттернам - база отправляла во внешний мир оповещение с помощью функции pg_notify.
В итоге такой подход вылился в жуткую боль как по администрированию, так и по поддержке. В конечном итоге, я вытащил функционал (4) в отдельный сервис, но боль от этого не сильно уменьшилась.
Как на мой нынешний взгляд надо было сделать:
1. Использовать RabbitMQ вместо самопала на gRPC (см прошлый пост)
2. Отработать запись данных в БД. Накрыть тестами функционал.
3. Запустить отдельным сервисом постановку задач сборщикам. Накрыть тестами функционал. Скорее всего, после окончательной отладки этот сервис сольётся с п. 2. Я начал делать их вместе, в итоге так и не смог до конца искоренить дублирование выгружаемых сообщений.
4. Завести отдельную пару сервис + бд для поискового кэша. Сделать как обновление в реальном времени, отведя с помощью RabbitMQ поток данных в сторону + предусмотреть функционал "перелива" данных из основной базы. Теперь я не привязан в PostgreSQL rum индексу на базе дефолтного словаря! И можно экспериментировать с поисковыми движками как душе угодно, не нарушая функциональность основного сервера. Хоть эластик попробовать, хоть сделать прослойку на питоне для умной обработки текста готовыми инструментами.
5. Отвести поток данных для анализа в реальном времени (для выдачи оповещений пользователям) и экспериментировать сколько душе угодно.
P.S. "Отвести поток данных" в случае RabbitMQ значит добавить несколько символов в месте подключения клиентской библиотеки.
P.P.S. Никто не мешает после отладки функционала по отдельности вернуться к монолиту, например для повышения быстродействия. Если закладывать такую возможность на старте - это дело 1-2 дней.
Telegram
Эшу быдлокодит
Палантир. Часть 24. Итоги, общая архитектура проекта.
#палантир@eshu_coding
По завершении ботов-агрегаторов проект я считаю завершенным, время описать что же получилось и подвести итоги.
На картинке:
DataFair - мастер сервер
DataLoader - сборщик
Пунтиром…
#палантир@eshu_coding
По завершении ботов-агрегаторов проект я считаю завершенным, время описать что же получилось и подвести итоги.
На картинке:
DataFair - мастер сервер
DataLoader - сборщик
Пунтиром…
👍3💩1
Эшу быдлокодит
Палантир. Часть 26. Рефлексия год спустя. #палантир@eshu_coding Описание получившейся системы можно посмотреть по ссылке. Намного менее приятной ошибкой было скатывание к монолиту. Центральный сервис (БД на postgresql + надстройка на шарпе) у меня выполнял…
В общем, если бы я строил Палантир сейчас, у меня вышло бы что-то подобное. Несколько проще, чем на схеме по ссылке, да и технологически беднее.
#палантир
#палантир
👍3
Выложил на гитхаб небольшой проектик - переделку бота-модератора телеграммных чатов. При написании его использовал несколько новых для себя подходов: TDD - test driven development, отказ от хранения состояния в приложении, использование тарантула в качестве персистентной очереди команд.
Бот не хранит никакой информации о собственном состоянии, зная лишь свой id, строку подключения к тарантулу и токен бота. Из телеграма прилетают оповещения об обновлениях, анализируются, после чего ставятся в очередь задач, хранящуюся в Тарантуле. За своим текущим состоянием, ответами на команды и т.д. бот тоже каждый раз ходит в тарантул. Отдельный поток слушает очередь задач в тарантуле, при появлении новых - исполняет.
Тарантул полностью живет в оперативной памяти, для связи по дефолту использует достаточно компактный и шустрый протокол - MessagePack. Это располагает к оптимизациям и работе с отдельными байтиками. Так, задача в очереди - это просто массив байт. Первый байт указывает на тип задачи, в соответствии с которым она и парсится и исполняется. Обычно задачи содержат, кроме первого байта, еще 2-3 int64 айдишника, то есть объем задачи получается во основном 17 или 25 байт. Такие объемы информации летают очень шустро.
К построению хранилища из нескольких инстансов на тарантуле есть два подхода: олдскульный, со сложными манипуляциями с конфигами и более современный, с использованием внешней утилиты - tarantool cartridge и модуля crud, предоставляющего синтаксический сахар над обычными операциями с данными и функционал для шардирования тарантула.
В репозитории по сути выложен шарповый стартер для экспериментов с конфигурацией кластера не выходя из Visual Studio: при запуске из докерфайла билдится контейнер, содержащих заданную конфигурацию кластера (по дефолту - мастер + реплика + балансировщик) и уже готовый к работе.
#tarantool
Бот не хранит никакой информации о собственном состоянии, зная лишь свой id, строку подключения к тарантулу и токен бота. Из телеграма прилетают оповещения об обновлениях, анализируются, после чего ставятся в очередь задач, хранящуюся в Тарантуле. За своим текущим состоянием, ответами на команды и т.д. бот тоже каждый раз ходит в тарантул. Отдельный поток слушает очередь задач в тарантуле, при появлении новых - исполняет.
Тарантул полностью живет в оперативной памяти, для связи по дефолту использует достаточно компактный и шустрый протокол - MessagePack. Это располагает к оптимизациям и работе с отдельными байтиками. Так, задача в очереди - это просто массив байт. Первый байт указывает на тип задачи, в соответствии с которым она и парсится и исполняется. Обычно задачи содержат, кроме первого байта, еще 2-3 int64 айдишника, то есть объем задачи получается во основном 17 или 25 байт. Такие объемы информации летают очень шустро.
К построению хранилища из нескольких инстансов на тарантуле есть два подхода: олдскульный, со сложными манипуляциями с конфигами и более современный, с использованием внешней утилиты - tarantool cartridge и модуля crud, предоставляющего синтаксический сахар над обычными операциями с данными и функционал для шардирования тарантула.
В репозитории по сути выложен шарповый стартер для экспериментов с конфигурацией кластера не выходя из Visual Studio: при запуске из докерфайла билдится контейнер, содержащих заданную конфигурацию кластера (по дефолту - мастер + реплика + балансировщик) и уже готовый к работе.
#tarantool
👍6🔥1