Pull to refresh
11
0
Send message

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

А вы знакомы с концепциями TDD, для чего вообще нужны по Вашему юнит тесты?

Какое такое поведение они фиксируют, зачем его фиксировать? Вот Вы написали или сгенерировали какой-то класс с помощью chatgpt, затем сгенерировали тесты и "зафиксировали" поведение. А Вы уверены, что вы зафиксировали то что надо? Как можно полагаться на зафиксированное поведение сгенеренного по реализации теста? Рефакторинг строго говоря бывает разный и не всегда это добавить еще один if в метод и радоваться, что старые тесты не упали, написав еще один новый тест. Что Вы делаете с этими сгенерированными по прошлой реализации тестами? Вы их не писали, получается их можно выкидывать в мусорку и заново генерить, если рефакторинг или добавление новой фичи выливается в что-то чуть большее чем пару строк кода в конце метода? А если бы вы их писали ( возвращаясь к практикам TDD), то они бы Вам в этом рефакторинге помогли, а вот эти Ваши сгенерированные вряд ли помогут. Есть еще такой момент, что масштаб вызываемой боли при написании юнит теста обычно коррелирует с тем насколько нехорошо собственно написана реализация и декомпозирован код, а генерация тестов не дает шанса подумать об этом ( концепции TDD).

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

Современные AI инструменты бесспорно мощные и нужные инструменты, с помощью которых можно оптимизировать работу, но все надо делать с умом и вот эти конкретные фичи в таком виде как рекламируется в статье их использовать - на мой взгляд не имеет ничего общего с повышением эффективности работы разработчика и улучшением качества продукта, а скорее пыль в глаза. Я бы даже сказал, что такая реклама такого использования copilot и др скорее даже вредна для неопытных разработчиков.

Мне одному непонятна ценность таких сгенерированных тестов? Т.е. разработчик пишет реализацию. Затем отдает AI инструменту, AI инструмент успешно генерирует тесты которые проходят без участия разработчика. И какой выхлоп от таких тестов? Даже если опустить за скобки, что в целом хорошо бы работать если не по TDD, то по крайней мере писать тесты параллельно с кодом. Тесты разработанные AI без участия программиста не несут никакой смысловой нагрузки. Сегодня я написал реализацию и сгенерил тесты, завтра мне нужно подправить реализацию - я иду и тоже сгенерю тесты, получается от этих тестов мир лучше не стал. А вот если я как разработчик вложил в реализацию и в тесты этой реализации хоть какую-то идею, дальше при изменении реализации есть шанс, что я отловлю что-то, что я забыл или не продумал, даже если это и приведет к правке тестов - все равно заставит меня критически оценить логику тестов которые были и правда ли я меняю реализацию так, что эти сценарии тоже меняются.

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

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

исходя из вышеизложенного нас как раз таки и интересуют только последние данные по ключу, старые данные нас не интересуют. Для того, чтобы топик с одной стороны не разрастался бесконечно, так одной записи в БД может соотв несколько записей в топике, если мы будем ее обновлять, с другой - чтобы все данные по актуальным ключам не почистились как раз таки и выбрана cleanup.policy = compacted.

вас и предыдущего комментатора я не понял, думал вопрос по поводу что все записи удаляются по времени, это было бы проблемой для представленного подхода. То что старые данные ПО КЛЮЧУ удаляются, изза этого осознанно выбран режим compacted. Никаких проблем при этом не будет, реплика будет актуальна независимо от того, будет ли в топике по ключу несколько значений или только последнее.

данные по ключу в режиме compacted могут быть полностью удалены из топика, если послать recrod с value = tombstone.

Вы обладаете знаниями которых у меня нет. Выше все объяснено и приведены ссылки на оф сайт, там можно изучить как работает режим cleanup.policy=compacted. Да я видел, что был какой-то KIP, где можно задачать cleanup.policy=compacted,delete, но вряд ли вы про это

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

я повторюсь, я не хочу думать и фантазировать об эффектах и рисковать, мне просто не нужна такая оптимизация, использовать HM или CHM для меня скорей всего при тестировании будет даже статистически неразличимым. Главная оптимизация уже сделана, за данными не ходим в редис, а обращаемся к In-Memory структуре.

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

Я если честно вас не понимаю, особенно про 'ложную надежду' в chm. Данные именно что обновляются в рантайме и перестройка структуры может произойти в любой момент. Моё понимание java memory model и ваши обьяснения на данный момент не позволяют с вами согласиться. Повторюсь chm или hm в рамках моих сервисом будут не различимы, но предпочитаю использовать при малейшем сомнении thread safe структуру. Не важно могут ли быть спецэффекты которые я могу предположить или такие, которые я не могу. Я вот честно не хочу даже об этом думать, есть thread safe структура из стандартной библиотеки и если с ней будут спецэффекты, то я по крайней мере буду уверен, что это не из-за того, что я использовал не thread safe структуру.

спасибо за оценку!

"По умолчанию Кафка - это журнал сообщений, и я знаю довольно много людей, которые использовать её даже в роли key value storage считают извращением. " - кажется что ваши знакомые не пользуются всеми возможностями кафки, т.к. confluent в целом пропагандирует другое и много докладов в том числе про это, даже есть такая ksqlDB - где DB прям в названии, хотя конечно это не совсем про DB :)

Я с вами полностью согласен, что представленное мной решение очень специфической для кейса с множеством предусловий и оговорок. В целом такая идея возникла после изучения примеров на сайте confluent по построению kafka stream application и прочтения Kafka Streams In Action. Даже думал начать использовать kafka streams. Но во первых понял, что у нас уже 10ки сервисов написаны с использованием реактивного клиента, которые просто так не перепишешь и кажется, что следуя рекомендациям этих гайдов эти сервисы надо немного по другому организовывать и разбивать на сервисы. Также мне на самом деле не очень понравилось то, как написан код как раз таки с этими Store, из-за иерархии наследования, которая была там, очень сложно кастомизировать так, как мне хотелось. Поэтому пока отложил этот и решил для начала взять оттуда принцип для одного специфичного кейса со справочниками. Т.е. сам kafka streams framework на первый взгляд субъективно не понравился, но с точки зрения описания принципов построения архитектуры приложения на базе Kafka - очень вдохновило, так что сейчас от этого активно использую kafka connect и вот представленное решение.

Я уже упомянул в другом комментарии, что изначально на этапе mvp эти справочники вообще велись в Redis. Но Redis это:

1) это дополнительная точка отказа ( сам кластер надо содержать и поддержать, у нас кстати на проде пару раз была потеря кластера)

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

3) неудобство ведения ( можно конечно пофиксить это с помощью такой же репликации из postgres через кафку)

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

у меня сомнение на этот счет. hash map не tread safe. любое добавление элемента в hash map может привести к перестройке внутренней структуры, таким образом не уверен, что не будет спецэффектов при чтении из других потоков. возможно вы что-то лучше меня знаете или понимаете и в кейсе когда только один поток пишет, а другие читают должно работать или я пропустил какие-то изменения в новых версиях jdk.
В любом случае даже если так, я обычно следую принципу: если есть сомнения - используй thread safe классы, такие как Atomic*, ConcurrentHashMap и др. По-моему на каком-то очень крутом докладе на joker, где разбиралось эффекты влечет объявление volatile и какие можно не помечать volatile, в конце был дан совет - при сомнениях лучше использовать оптимизированные под это спец классы, такие как Atomic* ConcurrentHashMap и др, потому что даже зная все детали того, как компилируется и оптимизируется код в jvm, можно не туда свернуть в рассуждения и прийти к неправильному выводу. Так что если мне нужна HashMap в многопоточное приложение, то я даже если честно долго не думаю и беру CHM.
Кажется, что даже если вы правы и я что-то упускаю и недопонимаю, вряд ли выигрыш от использования HashMap будет вообще различим в такого рода сервисах, а вот риск получить спецэффекты при работе с HashMap, когда по логам значение будет записано, а в итоге не будет вычитано, точно не хочется потом разбираться с этим.

Нет не сравнивал, т.к. не особо интересно. Убежден, что такую выгрузку можно сделать быстрее, но для меня это не так важно. Мне нужно было убедиться, что на кратно большем объеме инициализация справочника выполняется за удовлетворительное время, т.е. время не сильно отличимое на фоне запуска spring boot сервиса который работает с кафкой ( в самом лучше случае это тоже занимает секунду, но иногда и больше, т.к. требуется время на то, пока консьмерам назначаться партиции, пока произойдет ребалансировка - это может занять и 10ки секунд).

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

При желании при таком подходе можете реализовать такую структуру, которая будет индексировать по разному, насколько хватит вашей фантазии, но это да нетривиально. По умолчанию да согласен, Kafka это key value store и в kafka streams как раз таки на это упор, все реализации хранилищ строятся вокруг того, что это key-value store и даже в Rocks DB Java Api я не нашел ничего, кроме как put(key) get(key) remove(key), хотя в c++ api там есть и про диапазон тоже. Не каждое решение универсально, с этим спорить не буду. У нас кстати есть пару справочников, которые предоставляют api поиска по ключу и активным датам и по диапазону ключей и по префиксу, конечно же там не такая простая ConcurrentHashMap.

По требования возможно дал не так много вводных. Мне они кажутся вполне себе логичными. У нас есть Postgres предоставляемый как сервис. Сказано, что оооооочень редко может быть такое, что ночью нужно сделать какие-то работы, которые приведут к тому, что сервис будет лежать 2-3 часа. По нашему SLA мы не можем обрабатывать поступающую транзакцию более 10 мин ( т.е. нам несмотря на лежащую БД нужно обрабатывать транзакции).

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

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

вкратце - на диске, но это наверное совсем другая история за пределами данного топика

буквально вручную на этапе mvp службой поддержки

да все правильно вы поняли, только не всех топиков, а тех топиков-справочников, которые используются в конкретном сервисе

"данные в кафке хранятся в памяти" - не понял утверждение. Возможно вы имели ввиду данные Из Кафки хранятся в оперативной памяти сервиса - тогда ДА.

Что будет если кластер Кафки перезапуститься?

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

Но повторюсь, Кафка у нас считается высокодоступной, поэтому при таком редком маловероятном кейсе легче все выключить и включить, чем тестировать и поддерживать работу при таком кейсе. Поэтому вдруг для вас это важно, переподключение консюмера при перезапуске KafkaGlobalStore, то возможно его нужно немного доработать. Для нас такое усложнение логики не актуально.

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

Коллега, я ни в коим случае никуда не посылаю, ваше право считать мои ответы неправильными. Я искренне хотел понять и ответить на вопросы предыдущего комментатора. Мне показалось, что я вполне себе ответил, дав ссылку на официальную доку, где можно почитать про разные clenup policy и в скользь упомянул про режиме compaction в статье, возможно не очень удачно, но я и не являюсь профессионалом в этом деле, я всего лишь любитель.

На мой взгляд при желании перейдя по ссылке можно ознакомиться со всеми нюансами, т.к. у человека видно, что нет пока необходимых знаний по этому вопросу, а вот то, что вы называете простым ответом повлекло ,бы за собой еще 10 простых вопросов, исхожу из того, что и в комментарии и в статье это объяснено так, что вы не поняли. Зачем я буду отвечать про ttl, если как вы правильно заметили такая терминология не используется в доках конфигурации - потом кто-то предъявит за ttl, что ввожу в заблуждение. Если есть действительно желание вникнуть в этот момент, то лучше идти к первоисточнику. Моей целью не было осветить все нюансы работы с Кафкой.

Как же не ответил, если написал про retention policy compacted и привёл ссылку и в самой статье и в комментарии, мне показалось что ответил, возможно не подробно, но по ссылке все нюансы описаны

о, да был у нас и даже еще где-то остался кластер редис:)

конечно есть разные подходы и решения, но от redis как раз в какой-то момент отказались

Давайте порассуждаем, уточните, что вы имеете ввиду под распределенным?

Вы имеете ввиду, то, что в каждом инстансе мы запускаем внутри ноду редиса и все их объединяем в кластер? или вы про централизованный кластер редиса?

Данные в редис вести неудобно - это опробовано, служба поддержи писали скрипты на питоне для загрузки и обновления 1000 терминалов, хотят писать sql запросы, т.е. их все равно нужно как-то туда реплицировать из реляционной БД.

Реализация хранилищ ограничена структурами редиса - с этим тоже сталкивались, не хватало.

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

Опять же не претендую на то, что это самое оптимальное и правильное решение. Возможно я не дал всех вводных, возможно есть решения лучше. Но конкретно с Redis пока не вижу как это можно сделать проще и эффективней, не исключаю что можно, но сейчас мы таки отказались от Redis.

к сожалению не понял в такой формулировке вашего вопроса, но попробую додумать и ответить на примере, который приведен

Есть справочник terminal_acquirer. Служба поддержки вводит 100 новых терминалов, первые 50 должны идти в Сбер, вторые в Альфа. Далее у нас есть сервис роутер, в которые приходит транзакция в которой есть terminal_id. С помощью реплики справочник в сервисе мы определяем куда дальше отправлять сообщение или делать запрос.

По ttl тоже непонятно, я вам вроде ответил, что для cleanup.policy=compact нет ttl - перейдите по ссылке.

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

1

Information

Rating
Does not participate
Registered
Activity