Тема раскрыта не очень, не хватает детальности, и фокуса на каком-то одном направлении. Или обзор решения с точки зрения бизнеса, или технические показатели, или же обзор что умеет datafactory, и как его можно применить. Смешиваются понятия databricks/spark, насколько могу судить.
Например, при прочтении возник вопрос, почему в одном пайплайне используется и DataFactory и Databricks, и Synapse? При том что Synapse по сути своей приёмник datafactory и адаптация databricks разрабатываемая microsoft. Почему не получилось обойтись одним Synapse? Это ведь должно было как упростить логику, так и снизить косты?
А можно для людей не в теме какой-нибудь пример «квантовой программы» и задачи которую она решает?
Не на уровне «пишем в консоль hello world, но из квартовой программы», а что-то более применимое в реальной жизни?
В случае Like — индекс не выйдет использовать, если like написан как «like '%a%'». В случае «like 'a%'» — он может быть использован. Это ограничение исходит из того, что индекс — по сути справочник со ссылками на «части» данных. Для строк — он строится начиная с начала строки, грубо говоря:
— index root.
— s[0]<«n» — go to index_1
— s[0] == «n» — go to index_2
— s[0] > «n» — go to index_3
В случае like %a% — неизвестно с чего начинается строка и SQL не может пойти в нужное поддерево индекса, надо обойти все записи в таблице.
В случае like a% — начало известно, по нему можно отсечь те ветки индекса которые точно не подходят, и проверить только оставшиеся.
Clustered Index — по сути определяет то как данные хранятся на диске, и содержит в себе все данные таблицы. С точки зрения выполнения Scan по нему — это почти аналогично Table Scan'у (который на MSSQL будет только в случае таблицы без кластерного индекса).
Странно что SQL не пытается использовать созданный индекс по DisplayName. Зависит от таблицы, объема столбцов и селективности выборки конечно, но как вариант, для полноты эксперимента — можно попробовать указать его в запросе хинтом принудительно и посмотреть план исполнения. Возможно что-то не так с индексом, и он не подходит для этого запроса.
Несколько странно говорить сначала про то какая у Azure хорошая инфраструктура, и как много продуктов она в себя включает, а потом делать тест производительности сайта без использования всей этой специфики.
Используемый в статье вариант — безусловно гибкий, консольное приложение + SQL можно развернуть где угодно, но в этом же и проблема этого теста.
Если же подходить к вопросу с точки зрения «cloud-first», можно было бы:
1) Вместо AppService, воспользоваться Static Web Apps, которые на порядок дешевле. Как понимаю по описанию, какой-то сложной логики на серверной части *клиентского приложения* — нет.
2) Вместо классического SQL — взять Azure Blob Storage, либо CosmosDB. Consumption-based планы обойдутся дешевле при ограниченной аудитории приложения. Да и при большой, чтение одного блоба с данными с Blob Storage — будет дешевле запросов к SQL.
3) Обновление данных с сайтов магазинов — сделать через Azure Function. Из коробки Durability, триггеры срабатывающие по расписанию, опять же Consumption-based биллинг. Учитывая что джоб выполняется раз в сутки и не CPU-heavy — ценник будет небольшой.
Хм, а интересно, если IP — персональные данные — то внешность человека — тоже персональные данные, ведь так? По лицу ведь можно идентифицировать человека довольно точно (всяко точнее чем по динамическому IP).
То есть, если я продавец в булочной, запомнил какого-нибудь покупателя который каждый день утром заходит за круассаном, и решил дать ему скидку (предложил бесплатно кофе) как постоянному клиенту — я нарушаю GDPR, если не возьму с него письменное согласие на это?
А если я не дай бог случайно узнаю его имя и потом упомяну его в разговоре с соседом — то я еще и распространяю его персональные данные без его согласия?
Надо ли у всех моих друзей срочно собрать согласия на обработку персональных данных, на случай если я вдруг увижу их на улице и узнаю какие магазины они посещают и в какое время? Если нет — то в чем разница между сайтом и магазином в этом контексте? Факт дружбы? Так он довольно относителен, чтобы узнать человека на улице — многим достаточно просто увидеть его N раз, в случае соседей это работает даже без персонального знакомства.
Если бы государство хотело вас загнобить оно бы не стало вводить материнский капитал
Если бы государство хотело поддержать заводящих детей родителей — государство могло бы посмотреть как выдается мат. капитал в той-же Чехии, и сделать аналогично. Честными ежемесячными выплатами, пропорционально зарплате родителей (итоговая сумма фиксированна, просто при минимальном размере — она будет выплачиваться 3 года, при «программистской» зарплате родителя — быстрее чем за год), которые можно потратить на ежедневные нужды ребенка. А не под абстрактное «формирование накопительной пенсии для мамы».
Используем LiteDB в своём проекте уже несколько лет (около 15 тыс установок у клиентов, довольно небольшая нагрузка, порядка 1 rps вида «прочитать состояние из бд, внести изменения, сохранить назад обновлённую версию», размер базы порядка 10-100мб).
Мигрировали с LocalDb, во время миграции сравнивали с SQLite по производительности/удобству.
Основной плюс — работает очень быстро. Как мы не тюнили SQLite — litedb из коробки обгонял его по нашему workflow работы (без изменения основной логики приложения) в разы. Оба они на порядок обгоняли localdb.
Главный минус — я бы не назвал litedb production-ready. Периодически всплывают баги, приводящие к нарушению структуры базы и делающие её нечитаемой. Уже по-моему третья «мажорная» версия вышла которая обещает что вот теперь то мы их все исправили, но на нашей клиентской Бахе все равно раз в пару месяцев у кого-нибудь что-то ломается. В другом use-case где мы используем её чисто как кеш (под достаточно объемные данные часто изменяющиеся) — у неё течёт размер и раз в несколько месяцев приходится руками сносить Файлы, потому что размер бд вырастает до десятка Гб.
Своя структура работы, нет поддержки популярными Orm, нет транзакций (по крайней мере когда мы её выбирали, потом их добавили, потом отказались, в общем политика меняется от версии к версии).
В целом — для собирания Proof of concept проекта с последующей переделкой, или под данные которые если что не жалко потерять или можно восстановить из других источников — очень удобно. Настраивается быстро, работа интуитивная, все летает. Но как полноценную единствннную БД в серьезном проекте — я бы не стал использовать.
В Чехии решили эту проблему проще, купленный через приложение билет начнет действовать только через 2 минуты после покупки. Поэтому видя контроллера покупать билет уже как правило поздно.
На электричках конечно время на проверку всех билетов в вагоне/поезде может быть больше, но разве нельзя было бы это решить адаптивной задержкой на активацию? Активировать билеты только в фиксированные моменты времени, синхронизированные с временем отправления электричек со станции на которой куплен билет.
Прочитал бегло про ActiveRecord и если правильно понял, то да, была и такая идея изначально, ориентироваться на классы объявленные в приложении и генерировать все по ним. Было 2 проблемы:
— Были сложности с тем, чтобы получить в Compile-time информацию об объявленных в проекте классах и их иерархии (T4 из коробки поддерживает это только достаточно костыльным образом, через промежуточную компиляцию библиотеки), либо разбираться с Roslyn и генерировать все в рантайме, но хотелось сохранить возможность отладки по сгенерированному коду, что в этом случае было бы делать тяжелее.
— Увы, на существующие классы и схему БД это не совсем ложилось, вылезало много ньюансов вызванных тем что изначально маппинги NHibernate писали руками, как и код слоя общения с БД. Если начинать новый проект — да, скорее всего изначально можно было бы сделать так. А тут пришлось бы вносить куда больше изменений и миграция не проходила бы так мягко.
Помогло ли в плане нагрузки на БД — сложно сказать. Делали параллельно много вещей, направленных на оптимизацию тяжелых мест, и какая именно как повлияла увы не оценить.
Но если раньше в статистике БД регулярно на позициях 5-10 были обращения к «справочникам» — сейчас их нет в топе совсем. Репликация БД на чтение уже давно настроена, часть тяжелых запросов на чтение которым не столь принципиальна сиюсекундная актуальность данных — ходят на slave-ноду SQL.
Сильно помогло в плане среднего времени ответа на часть API запросов (которую удалось целиком закрыть кешем, и переставшую соответственно обращаться к БД) и уменьшении количества рутины в разработке при добавлении новых сущностей, не отличающихся большими объёмами данных.
Тема раскрыта не очень, не хватает детальности, и фокуса на каком-то одном направлении. Или обзор решения с точки зрения бизнеса, или технические показатели, или же обзор что умеет datafactory, и как его можно применить. Смешиваются понятия databricks/spark, насколько могу судить.
Например, при прочтении возник вопрос, почему в одном пайплайне используется и DataFactory и Databricks, и Synapse? При том что Synapse по сути своей приёмник datafactory и адаптация databricks разрабатываемая microsoft. Почему не получилось обойтись одним Synapse? Это ведь должно было как упростить логику, так и снизить косты?
Не на уровне «пишем в консоль hello world, но из квартовой программы», а что-то более применимое в реальной жизни?
— index root.
— s[0]<«n» — go to index_1
— s[0] == «n» — go to index_2
— s[0] > «n» — go to index_3
В случае like %a% — неизвестно с чего начинается строка и SQL не может пойти в нужное поддерево индекса, надо обойти все записи в таблице.
В случае like a% — начало известно, по нему можно отсечь те ветки индекса которые точно не подходят, и проверить только оставшиеся.
Странно что SQL не пытается использовать созданный индекс по DisplayName. Зависит от таблицы, объема столбцов и селективности выборки конечно, но как вариант, для полноты эксперимента — можно попробовать указать его в запросе хинтом принудительно и посмотреть план исполнения. Возможно что-то не так с индексом, и он не подходит для этого запроса.
Используемый в статье вариант — безусловно гибкий, консольное приложение + SQL можно развернуть где угодно, но в этом же и проблема этого теста.
Если же подходить к вопросу с точки зрения «cloud-first», можно было бы:
1) Вместо AppService, воспользоваться Static Web Apps, которые на порядок дешевле. Как понимаю по описанию, какой-то сложной логики на серверной части *клиентского приложения* — нет.
2) Вместо классического SQL — взять Azure Blob Storage, либо CosmosDB. Consumption-based планы обойдутся дешевле при ограниченной аудитории приложения. Да и при большой, чтение одного блоба с данными с Blob Storage — будет дешевле запросов к SQL.
3) Обновление данных с сайтов магазинов — сделать через Azure Function. Из коробки Durability, триггеры срабатывающие по расписанию, опять же Consumption-based биллинг. Учитывая что джоб выполняется раз в сутки и не CPU-heavy — ценник будет небольшой.
То есть, если я продавец в булочной, запомнил какого-нибудь покупателя который каждый день утром заходит за круассаном, и решил дать ему скидку (предложил бесплатно кофе) как постоянному клиенту — я нарушаю GDPR, если не возьму с него письменное согласие на это?
А если я не дай бог случайно узнаю его имя и потом упомяну его в разговоре с соседом — то я еще и распространяю его персональные данные без его согласия?
Надо ли у всех моих друзей срочно собрать согласия на обработку персональных данных, на случай если я вдруг увижу их на улице и узнаю какие магазины они посещают и в какое время? Если нет — то в чем разница между сайтом и магазином в этом контексте? Факт дружбы? Так он довольно относителен, чтобы узнать человека на улице — многим достаточно просто увидеть его N раз, в случае соседей это работает даже без персонального знакомства.
Если бы государство хотело поддержать заводящих детей родителей — государство могло бы посмотреть как выдается мат. капитал в той-же Чехии, и сделать аналогично. Честными ежемесячными выплатами, пропорционально зарплате родителей (итоговая сумма фиксированна, просто при минимальном размере — она будет выплачиваться 3 года, при «программистской» зарплате родителя — быстрее чем за год), которые можно потратить на ежедневные нужды ребенка. А не под абстрактное «формирование накопительной пенсии для мамы».
Используем LiteDB в своём проекте уже несколько лет (около 15 тыс установок у клиентов, довольно небольшая нагрузка, порядка 1 rps вида «прочитать состояние из бд, внести изменения, сохранить назад обновлённую версию», размер базы порядка 10-100мб).
Мигрировали с LocalDb, во время миграции сравнивали с SQLite по производительности/удобству.
Основной плюс — работает очень быстро. Как мы не тюнили SQLite — litedb из коробки обгонял его по нашему workflow работы (без изменения основной логики приложения) в разы. Оба они на порядок обгоняли localdb.
Главный минус — я бы не назвал litedb production-ready. Периодически всплывают баги, приводящие к нарушению структуры базы и делающие её нечитаемой. Уже по-моему третья «мажорная» версия вышла которая обещает что вот теперь то мы их все исправили, но на нашей клиентской Бахе все равно раз в пару месяцев у кого-нибудь что-то ломается. В другом use-case где мы используем её чисто как кеш (под достаточно объемные данные часто изменяющиеся) — у неё течёт размер и раз в несколько месяцев приходится руками сносить Файлы, потому что размер бд вырастает до десятка Гб.
Своя структура работы, нет поддержки популярными Orm, нет транзакций (по крайней мере когда мы её выбирали, потом их добавили, потом отказались, в общем политика меняется от версии к версии).
В целом — для собирания Proof of concept проекта с последующей переделкой, или под данные которые если что не жалко потерять или можно восстановить из других источников — очень удобно. Настраивается быстро, работа интуитивная, все летает. Но как полноценную единствннную БД в серьезном проекте — я бы не стал использовать.
Получится как минимум более расширяемо в будущем, чем в примере.
На электричках конечно время на проверку всех билетов в вагоне/поезде может быть больше, но разве нельзя было бы это решить адаптивной задержкой на активацию? Активировать билеты только в фиксированные моменты времени, синхронизированные с временем отправления электричек со станции на которой куплен билет.
— Были сложности с тем, чтобы получить в Compile-time информацию об объявленных в проекте классах и их иерархии (T4 из коробки поддерживает это только достаточно костыльным образом, через промежуточную компиляцию библиотеки), либо разбираться с Roslyn и генерировать все в рантайме, но хотелось сохранить возможность отладки по сгенерированному коду, что в этом случае было бы делать тяжелее.
— Увы, на существующие классы и схему БД это не совсем ложилось, вылезало много ньюансов вызванных тем что изначально маппинги NHibernate писали руками, как и код слоя общения с БД. Если начинать новый проект — да, скорее всего изначально можно было бы сделать так. А тут пришлось бы вносить куда больше изменений и миграция не проходила бы так мягко.
Но если раньше в статистике БД регулярно на позициях 5-10 были обращения к «справочникам» — сейчас их нет в топе совсем. Репликация БД на чтение уже давно настроена, часть тяжелых запросов на чтение которым не столь принципиальна сиюсекундная актуальность данных — ходят на slave-ноду SQL.
Сильно помогло в плане среднего времени ответа на часть API запросов (которую удалось целиком закрыть кешем, и переставшую соответственно обращаться к БД) и уменьшении количества рутины в разработке при добавлении новых сущностей, не отличающихся большими объёмами данных.