Здравствуйте, Sinclair, Вы писали:
S>Как устроено повторное выполнение такого запроса? S>В наивной схеме мы снова бежим на сервер (500+50+100мс), на этот раз нужные 3GB у нас в страничном кэше, и мы отдаём ответ примерно за 750мс. S>Нюанс: это значение мало зависит от того, в той же таймзоне новый клиент или нет, т.к. в худшем случае в кэше не хватает данных за 1 день, а это в пределах 10 мегабайт или 160 чтений — 100 мс. Естественно, мы предполагаем, что уж 3ГБ памяти у нас есть — обычные машинки, отданные под базы такого размера, тащат от 16 до 32ГБ RAM.
Фееричный детский лепет (ну или же гипернаглая демагогия), написанный из предположения бесконечности процессорных ресурсов. Все обсуждаемые оптимизации (и включение кэширования и убирание лишних накладных расходов от вещей типа linq и всё остальное) делают очевидно не для того, чтобы сократить время одиночного запроса на клиенте с 750 мс до 651 мс, а для того, чтобы позволить серверу обрабатывать десятки таких одновременных запросов (и тут мы имеем уменьшение времени обработки запроса в БД с 100мс до 1мс позволяющее очень существенно повысить количество одновременно обрабатываемых запросов).
S>В простой, но надёжной схеме мы отдаём данные с expiration: never, потому что 2014 год закончился больше 1го квартала назад, и изменений в нём не будет.
В таком случае нормальные люди просто сгенерируют html отчёт, который будет отдавать nginx. )))
Здравствуйте, Mamut, Вы писали:
_>>Такими темпами он может когда-нибудь выйти в однозначные лидеры и тогда можно будет спокойно затачиваться под него — вот будет счастье для авторов всяких движков. ))) Но пока до этого ещё далеко.
M>Мдеее. Теоретики такие теоретики. «Нормальные базы данных», «всего лишь реализовать функционал», «однозначные лидеры». M>Достаточно того, что на первых трех местах несовместимые друг с другом по функционалу базы данных. M>Можно начать, например, с hierarchical queries и windowing functions. Ну или, повторю, с generate_sequence.
Ты читай внимательнее. Я же ясно написал "пока до этого ещё далеко". Просто направление развития у PostgreSQL очень интересное стало на мой взгляд. Они движутся в сторону добавления к себе всех возможностей nosql баз, при этом не отказываясь от полноценной функциональности реляционных. Вроде бы больше никто из популярных продуктов не движется в эту сторону — остальные sql/nosql базы держатся строго в своих классических рамках. Так что если у PostgreSQL всё получится, то это может быть очень интересной заявкой на будущее. Но пока ничего такого нет и поэтому нет никакого обоснования для поддержки строго одной СУБД при написание какого-то нового движка.
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Если не подходит реляционная модель, значит не подходит и РСУБД.
Да, в случае БД это правильный ответ. А что у нас в случае работы с коллекциями? )
_>>Ну меня больше интересует не конкретный синтаксис, а изменит ли это накладные расходы по отношению к варианту с просто int'ом. НС>С точностью до времени выделения памяти и работы конструктора.
Хм, ну т.е. на практике в C# такое использовать тоже сомнительно. Но это уже вина не linq, а clr, правильно? )
_>>Ну естественно подразумевается, что и весь остальной доступ к БД реализован через подобные функции. НС>Ну вот за это, если ты еще не понял, и надо расстреливать.
Обоснуй. )
_>>А дальше возможно сделать несколько альтернативных реализаций, в зависимости от используемого движка для хранения данных. НС>Возмоно, но на практике никому не нужно. Итого овердизайн в чистом виде.
Только почему-то весь веб именно так и устроен. )))
_>> На практике большинство известных движков реализовано именно с помощью подобного слоя абстракции бд и отлично работают. НС>Каких движков? О чем ты?
Ну например большинство веб-движков работают со многими СУБД именно благодаря такому подходу.
НС>Чем он удобный? Тем что его на каждый чих править надо? Или тем что классы в возвращаемом результате провоцируют на нарушение инвариантов?
Как раз удобнее мыслить в рамках объектов приложения, а не таблиц БД. И именно слой абстракции позволяет это делать (работать с объектами не являющимися полным отображением таблиц).
_>> и отсутствие никчемных накладных расходов — это ненужная и вредная работа? НС>Лишний слой это не отсутствие, это наоборот — присутствие.
Это смотря в каких языках. ))) Да, но самое забавное, что даже в языках не гарантирующих нулевых накладных расходов при введение уровня абстракции, всё равно идут на это ради удобства от правильной архитектуры.
Здравствуйте, Ночной Смотрящий, Вы писали:
_>>Никто и не просит точные цифры. Но по порядку величины НС>Порядок я тебе сказал.
Где? Ты назвал порядок процентов от времени запроса. А при этом само время запроса может отличаться на несколько порядков. Назови порядок величины накладных расходов в секундах и тогда будет более менее предметный разговор.
Здравствуйте, alex_public, Вы писали:
_>Я тут уже спрашивал у других собеседников... Чем нам поможет гениальный sql в случае скажем работы с графами? ) А это очень часто встречающаяся вещь — деревья с данными, настройками и т.п. чуть ли не в каждом приложение есть. Это не говоря уже о файловых системах, реестрах и т.п.
С 2008 год (уже 7 лет как) есть herarchyid в SQL Server. Аналог есть в postgres, но появился значительно позже. Про оракл не в курсе, но скорее всего там тоже есть на эту тему.
Для графов произволного вида универсальных средств нет. Так как в зависимости от алгоритма могут понадобиться разные обходы. Обычно делается рекурсивный запрос, который делает транзитивное замыкание с нужными свойствами, которое кешируется в таблице.
Здравствуйте, gandjustas, Вы писали:
G>>>Время раундтрипа до базы окажется выше разницы между отдачей результата из кеша и из страниц в памяти. Даже при высоком hit ratio. EP>>1. На обработку данных может понадобится десятки миллисекунд. Например для dummy пробежки одним ядром по ста магабайтам требуется около десяти миллисекунд. Roundtrip может быть намного меньше. G>Никто в здравом уме по сотням мегабайт не бегает кадыйм запросом.
Я не говорил про каждый запрос.
EP>>2. Даже если roundtrip намного больше, то всё равно есть преимущество — процессор/память базы не нагружается, соответственно больше свободных ресурсов для обработки других задач. То есть даже при большом latency всё равно для хорошего throughput много применений G>А кеш значит бесплатен?
Конечно нет.
G>Хранение результатов
Хранение результатов занимает только объём памяти, но не отнимает её throughput в отличии от повторного вычисления.
G>и поиск по ключу ничего не стоят, так?
Конечно нет, но это крайне дёшево.
EP>>Даже для обработки сотен мегабайт, что совсем немного по меркам современных объёмов RAM — требуется десятки миллисекунд (одним ядром), а никакие не "доли" G>Никто в здравом уме не делает запросов, которые должны в реальном времени лопатить сотни мегабайт.
Почему?
EP>>Речь о том, что не нужно делать чрезмерно общие заявления, справедливые только для некоторых частных случаев. G>Вообще-то ты пытаешься обобщить.
Где?
G>Если в точечном случае автокэш
Что ты подразумеваешь под "автокэш"? Я же практически сразу сказал:
G>>>Также очевидно что при равной вероятности любых запросов hit ratio будет нулевым и кеш по факту не будет работать, а при неравномерном распределении та же проблема решается индексами. Но тебе это тоже неочевидно. EP>>Конечно это не очевидно, так как контрпример строится элементарно. G>Давай, вперед. Желательно с доказательствами твоих слов.
Есть K равновероятных запросов, результаты которых помещаются в кэш. После того как каждый запрос был вызван по разу, hit ratio будет стопроцентным
EP>>>>То есть без практических примеров ты не можешь понять утверждение №1? G>>>Понять != поверить. EP>>Поясни. Что конкретно тебе понятно, и во что ты "не веришь" для утверждения №1? G>Объясняю еще раз. Я не верю твоим словам о том, что автокэш в базе может быть эффективен. У тебя доказательств обратного нет, ты тупо теоретизируешь.
Да причём тут "автокэш" Разговор про "автокэш" закончился уже давно:
EP>>>А я не говорил что нужно кэшировать все запросы.
G>>А вот a_alex_public_ утверждал что автокеш в базе — хорошее решение.
EP>>>Хотя можно представить случаи где и автоматический кэш будет эффективен
G>>Представить вообще можно что угодно, а вот на практике встретить не всегда.
EP>Кто-то встретит, кто-то нет — для этого есть настройки.
ЕМНИП больше реплик про "автокэш" не было, но ты почему-то вспомнил о нём сейчас
EP>>Аргументы либо верные, либо нет — разница в опыте тут совершенно ортогональна. G>Твои аргументы недоказанные. Я не буду даже пытаться их опровергать. Просто буду их игнорировать, пока ты сам не докажешь их верность, ок?
Не собираюсь угадывать что ты там не понял или с чем не согласен в моих аргументах.
G>Не пиши больше без результатов тестов.
Не хочешь — не отвечай, дело-то. Здесь форум, а не личная переписка — на сообщение может ответить любой.
Здравствуйте, gandjustas, Вы писали:
EP>>>>Здесь под динамическими фильтрами и предикатами — подразумеваются выражения неизвестные во время сборки приложения. Их "специальность" в том, что для них нельзя построить индексы заранее, а не в том что у них какой-то особенный синтаксис. G>>>Ты предполагаешь, что любой запрос равновероятен? EP>>Необязательно. G>Да или нет?
"Необязательно" означает что запросы могут быть как равновероятны, так и нет.
G>>>Тогда чем поможет кеш? EP>>Закэширует равновероятные запросы (которые помечены например как "result cache"). G>То есть всетаки ручной кэш?
Да, смотри цитаты в предыдущем сообщении.
G>Тогда зачем его держать в базе? Sinclair наглядно показал бесполезность этого подхода.
Он этого не показывал. Он лишь показал что в некоторых конкретных случаях, при определённых условиях (типа expiration: never), целесообразно использовать внешний кэш.
G>>>А если не равновероятен, то в чем проблема построить индексы? EP>>1. Например акцент распределения меняется со временем — индекс сегодня подходящий для 95%, завтра может подходить лишь для 5% запросов. G>Ну ок, поменяй индексы. Это не проблема.
Пока будешь собирать статистику и менять их — распределение может опять измениться.
G>А вот поправить программу, которая говорит базе какие результаты кешировать, а какие нет — сложнее. G>Так что кэш в базе и с точки зрения удобства использования оказывается хуже.
Опять же, зависит от.
Ставить внешний кэш и возможно следить за тем чтобы данные в нём не прокисли может быть неудобней чем просто поправить пару строчек кода
EP>>2. Другой пример: ок, выделили 80% типичных запросов, построили для них индексы — но под остальные запросы они никак не подходят, и паттерны доступа там меняются со временем. Так вот, кэши могут ускорить оставшиеся 20%, чтобы они повторно не грузили систему. G>Ты говоришь об автокеше или о ручном? Если ты кешируешь все, то hit ratio низкий и кеш бесполезен.
Конкретно здесь про ручной и запросы с динамическими формулами.
G>Если ты кешируешь выборочно, то твой кеш будет ориентироваться на те же вероятности. Только когда паттерны доступа изменятся (что на практике не происходит само по себе), то твой выборочный кеш потребует пересборки приложения, а индексы в базу добавить проблем нет.
Здесь обсуждаются не просто паттерны и типичные запросы, а в контексте запросов с динамическими формулами.
EP>>3. Набор покрывающих индексов может оказаться слишком дорог. Причём даже если не брать в рассмотрение место на дисках, то они отнимают RAM, что увеличивает чтения с диска — так как для разных "индексированных" запросов требуются разные индексы, и помимо этого требуется сама таблица для менее частых (но всё же актуальных) "не индексированных" запросов. G>Ты всетаки считаешь что запросы равновероятны?
Конкретно в этой ветке мы обсуждаем не равновероятные:
G>А если не равновероятен, то в чем проблема построить индексы?
G>Если нет, то зачем делать много индексов?
Тут даже не важно много их или нет. Важно то, что нам всё равно нужны и индексы (причём возможно с лишними колонками) и сама таблица (для тех редких запросов), что забивает память.
Ок, определились. Запросы кешируются выборочно, такая возможность есть только в оракле.
G>>>>Также очевидно что при равной вероятности любых запросов hit ratio будет нулевым и кеш по факту не будет работать, а при неравномерном распределении та же проблема решается индексами. Но тебе это тоже неочевидно. EP>>>Конечно это не очевидно, так как контрпример строится элементарно. G>>Давай, вперед. Желательно с доказательствами твоих слов.
EP>Есть K равновероятных запросов, результаты которых помещаются в кэш. После того как каждый запрос был вызван по разу, hit ratio будет стопроцентным
Нет, hit ratio будет 0, потому что у тебя еще ни одни запрос не отдался из кеша. При этом кэш уже скушал M памяти.
И чем сложнее запросы, чем больше параметров, данных и пользователей, тем меньше будет hit ratio расти, при этом отбирать память будет все больше. В итоге легко получить ситуацию когда hit ratio будет незаметно отличаться от нуля при гигабайтах кеша (вполне достаточно чтобы количество разных запросов было сильно больше, чем количество кешируемых ответов и все запросы были равновероятны). Если кеш внеший к базе это какбы и не проблема, можно еще один инстанс кеша поставить. А когда кеш отбирает ресурсы у базы, то cache misses требуют все больше чтений с диска, что замедляет систему.
То есть то, что ты рассматриваешь работает только на маленьких базах, простых запросах и небольшом количестве пользователей.
Здравствуйте, gandjustas, Вы писали:
G>>>>>Также очевидно что при равной вероятности любых запросов hit ratio будет нулевым и кеш по факту не будет работать, а при неравномерном распределении та же проблема решается индексами. Но тебе это тоже неочевидно. EP>>>>Конечно это не очевидно, так как контрпример строится элементарно. G>>>Давай, вперед. Желательно с доказательствами твоих слов. EP>>Есть K равновероятных запросов, результаты которых помещаются в кэш. После того как каждый запрос был вызван по разу, hit ratio будет стопроцентным G>Нет, hit ratio будет 0, потому что у тебя еще ни одни запрос не отдался из кеша. При этом кэш уже скушал M памяти.
Я когда писал думал переформулировать это место, но решил что достаточно написать "будет стопроцентным" вместо "станет стопроцентным".
Ок, переформулирую: После того как каждый запрос был вызван по разу, hit ratio для всех последующих запросов, исключая начальные, будет стопроцентным, то есть каждый следующий запрос попадёт в кэш
Здравствуйте, gandjustas, Вы писали:
_>>Так мы же не про деньги говорили, а про количество программистов. ))) G>Тем более. В яндексе, ЛК, майлру суммарно работает больше чем во всех банках вместе взятых. А если еще посчитать интеграторов... G>Банально взгляни вакансии на HH. Большая часть это софтовые конторы и корп. разработка.
Всё же ты не в реальном мире живёшь. ) Одно IT подразделение Сбербанка больше 3000 человек, что больше численности ЛК или маил.ру. А в России около 800 банков. ) И это ещё если забыть о том, что маил.ру и яндекс слабо напоминают производителей корпоративного ПО.
_>>Ну ну) Пока что единственное, что тебе не продемонстрировали (причём это не означает, что с этим есть какие-то проблемы), это переброску запроса между dll. Но кстати говоря это ты и сам не продемонстрировал, а только анонсировал. ))) G>И это значимое различие. В .NET любой экземпляр любого типа может спокойно передаваться в другую сборку, так что даже демонстрировать не буду. Если хоть немного .net знаешь,то даже писать бы такое не стал.
Это абсолютно никчемная возможность. Но даже если бы она и была важной... В каком-то языке с подобным (вызов функции из dll, с параметром в виде объекта некого класса) есть проблемы? )
Здравствуйте, gandjustas, Вы писали:
G>С чего ты взял что в большинстве? Если кеш не учитывает распределение запросов, то его hit ratio будет крайне низок и в среднем вряд ли ускорит приложение. Только в примитивных случаях (один клиент и малое количество запросов) может помочь. А если ты о ручном кеше, то его лучше отдельно делать и интегрировать с кешем на клиенте.
Хы, любой кэш вообще учитывает распределение просто по своему построению. А с твоей логикой и дисковый кэш тогда не нужен — он же ведь всегда намного меньше размера диска, а значит вероятность попадания как будто бы тоже очень мала.
G>Изучай как базы работают. Разбор sql делается один раз при построении плана, план потом из кеша достается.
Здравствуйте, gandjustas, Вы писали:
G>Linq не выбирает варианты запросов, он просто генерирует что ему сказали. Но у linq есть средства дкомпозиции, а у SQL нет. G>Представь что ты бы писал на языке, на котором нет функций, то есть ты все должен сделать в одной функции main, а потом у тебя появилась возможность разбивать программу на функции, сможешь писать более сложные программы после этого? Очевидно да. Та же ситуация с linq.
Декомпозиция ради уменьшения сложности (а не ради повторного использования компонентов) становится интересной только при больших объёмах кода. У тебя часто встречаются sql запросы на несколько экранов кода? )
_>>А мы разве уже разбирали хотя бы один конкретный частный случай? ) G>Стой, ты уже утверждаешь, что "всегда хуже". То есть в любом частном случае ты подберешь вариант лучше linq. G>Ты уже не смог это сделать, зачем дальше обсуждать?
Каким образом я не смог это сделать, если мы ещё не рассматривали ни один частный случай? )
G>Ты написал sql с помощью склейки строк и пропустил там sql-инъекцию. Ты сам прекрасно продемострировал, что linq сработал лучше человека. Почему продолжаешь спорить?
Кстати не факт. Если указанные в том запросе строки приходили не от пользователя, а циркулировали только внутри кода, то как раз такой вариант является более оптимальным. )))
G>А также помни, что в linq есть средства декомпозиции, которые позволяют строить более сложные запросы, чем человек сможет осилить.
Угу, единственный вменяемый подход заключается в извращение со строковыми путями. "Замечательное" решение. )))
G>С 2008 год (уже 7 лет как) есть herarchyid в SQL Server. Аналог есть в postgres, но появился значительно позже. Про оракл не в курсе, но скорее всего там тоже есть на эту тему.
G>Для графов произволного вида универсальных средств нет. Так как в зависимости от алгоритма могут понадобиться разные обходы. Обычно делается рекурсивный запрос, который делает транзитивное замыкание с нужными свойствами, которое кешируется в таблице.
G>Придумано все 10-15 лет назад.
Любой подход, который для полного (на всю глубину) обхода поддерева заставляет генерировать рекурсивные запросы к БД, можно сразу выкидывать на помойку.
Здравствуйте, gandjustas, Вы писали:
G>Ок, определились. Запросы кешируются выборочно, такая возможность есть только в оракле.
Вообще то и в mysql так можно. Только там обратная схема. Там включается автоматическое кэширование всего, а в конкретном запросе можно указать не кэшировать его.
НС>Все именно так просто. Я проверял. Строго-типизированный вариант прекрасно работает. Нерешенных неприятностей на момент, когда я покинул проект не было.
Прикольно.
НС>Это все сравнительно легко решаемо. В конце концов cast никто не отменял. Ну и на практике подобное встречается совсем нечасто.
Может быть я преувеличенно паранойю. Каст он, конечно, каст, но как раз не хочется постоянно кастить. Было бы интересно почитать про строготипизированный вариант SQL подробнее — чисто понять, как избегать постоянных перекастов между char(n)/varchar(m)/text/ntext/etc.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали: _>Я тут уже спрашивал у других собеседников... Чем нам поможет гениальный sql в случае скажем работы с графами? ) А это очень часто встречающаяся вещь — деревья с данными, настройками и т.п. чуть ли не в каждом приложение есть. Это не говоря уже о файловых системах, реестрах и т.п.
А что конкретно вас смущает? Есть N способов работать с графами в SQL. можно — через CTE, можно — через транзитивное замыкание.
В целом, работу с графом обычно инкапсулируют в отдельное место — точно так же, как обход дерева спрятан в коде, возвращающем IEnumerable.
Так и тут — вызываем GetEmployeesByDepartment(Guid departmentId), получаем IQueryable<Employee>. А то, как там внутри происходит вычисление всех вложенных департаментов — личное дело разработчика.
Это позволяет нам начинать с какой-нибудь простой схемы хранения дерева — например, с CTE, и оптимизировать её по мере надобности, не ломая остальной код. Только на этом сайте есть, емнип, четыре статьи про то, как хранить деревья в SQL.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, alex_public, Вы писали:
_>Фееричный детский лепет (ну или же гипернаглая демагогия), написанный из предположения бесконечности процессорных ресурсов.
facepalm. _>Все обсуждаемые оптимизации (и включение кэширования и убирание лишних накладных расходов от вещей типа linq и всё остальное) делают очевидно не для того, чтобы сократить время одиночного запроса на клиенте с 750 мс до 651 мс, а для того, чтобы позволить серверу обрабатывать десятки таких одновременных запросов
Это не демагогия, а практический опыт.
Ресурсы — не бесконечны. Они имеют разную стоимость, в зависимости от того, где мы их пытаемся найти.
Например, добавить процессоров в машину, на которой работает СУБД — дорого. Потому, что у одной машины есть естественный предел, а переход к кластеру — это до сих пор весьма тяжелое приключение, требующее пересмотра архитектуры. Добавление "ещё одного ядра" может вам запрсто обойтись в полмиллиона долларов. Более того, даже кластерная архитектура — не панацея: с ростом размера кластера объем затрат на синхронизацию начинает расти нелинейно; сейчас нет никаких способов неограниченного наращивания мощности кластеров для OLTP-приложений.
Добавить ещё ядро к стейтлесс веб-фарме — почти ничего не стоит. Просто потому, что там нет никаких особенностей. Просто деплоим ещё одну машинку за лоад-балансером — и поехали. Амортизированная стоимость одного ядра — копейки.
А мощности клиента вообще достаются нам бесплатно вместе с каждым клиентом.
То же самое — с памятью. Вы предлагаете, грубо говоря, тратить на кэш ресурсы по $1000/мегабайт, чтобы не тратить ресурсы по $10/мегабайт.
Деревья выражений разбираются на дешёвых машинах. Если меня не устроит количество одновременных соединений, то я просто добавлю в кластер ещё одну машину, и получу линейный рост bandwidth.
_>(и тут мы имеем уменьшение времени обработки запроса в БД с 100мс до 1мс позволяющее очень существенно повысить количество одновременно обрабатываемых запросов).
Вряд ли.
S>>В простой, но надёжной схеме мы отдаём данные с expiration: never, потому что 2014 год закончился больше 1го квартала назад, и изменений в нём не будет. _>В таком случае нормальные люди просто сгенерируют html отчёт, который будет отдавать nginx. )))
Я и говорю — отдадим наш респонс (не обязательно HTML) по HTTP, с хидером expiration:never. Это позволит клиенту вообще не обращаться на сервер при последующих запросах. А для тех, кто всё же пойдёт на сервер, поставим reverse proxy (не обязательно nginx).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
M>>Достаточно того, что на первых трех местах несовместимые друг с другом по функционалу базы данных. M>>Можно начать, например, с hierarchical queries и windowing functions. Ну или, повторю, с generate_sequence.
_>Ты читай внимательнее.
Давай ты применишь этот совет к себе
_>Я же ясно написал "пока до этого ещё далеко". Просто направление развития у PostgreSQL
Ему про Фому, он про мне про Ерему.
Я ему по то, что никакой у всех баз данных несовместимый функционал, он мне про «PostgreSQL еще не будущее».
Я про то, что любое приложение почти сразу начнет использовать функционал, предоставляемый конкретной базой данных, потому что движок сможет предоставить лишь общий для всех баз функционал, он мне про «PostgreSQL еще не будущее».
Я про то, что даже в тройке лидеров БД (Oracle, MySQL, MS SQL) несовместимый функционал между всеми тремя, и любой движок будет ограничен только общим функционалом, а приложение, даже использующее такой движок, почти сразу начнет завязываться на возможности базы, а он мне про «PostgreSQL еще не будущее».
Я ему говорю: посмотри хотя бы на windowing functions и hierarchical queries (помимо generate_sequence), а он мне про «PostgreSQL еще не будущее».
_> Всё же ты не в реальном мире живёшь. ) Одно IT подразделение Сбербанка больше 3000 человек, что больше численности ЛК или маил.ру. А в России около 800 банков.
Тебе рассказать как банки работают? Ты будешь плакать кровавыми слезами.
Раз в день банки заливают друг другу на FTP-сервера файлы в кривых форматах, созданных еще в 60-х. После чего эти файлы пакетно обрабатываются. Более того, у всех есть cut-off time. Если запрос пришел после, скажем 19:00, он будет обработан после 19:00 на следующий день.
Редко какой банк может похватстаться хоть каким-то высоким уровнем что разработчиков что системы. И подавляющее большинство из этих 3000 программистов занято постоянным подпиливанием всего этого говна и изобретением все новых костылей, чтобы создавалась видимость «современного динамично развивающегося банка».
У нас есть целая команда, которая постоянно пилит парсеры для payment files, которые мы получаем из банков. Пять банков своими криворукими программерами, неспособными допилить свои говно-кобол и говно-ява системы, чтобы они генерировали корректные по формату файлы, загружают команду из пяти человек на полный рабочий день на протяжение уже нескольких лет.
Банки даже рядом не валялись с Яндексом и Мейл.ру, если что.