Комментарии 189
Если UPDATE-запрос на таблице приводит к пересчету индекса, то ни один использующий этот индекс SELECT до окончания пересчета (ну или во время переключения, если вы верите в ровные руки авторов своей СУБД) выполнится, увы. В PostgreSQL при использовании immutable tuples любой UPDATE приводит к пересчету всех индексов таблицы.
Непонятно, что вы имеете в виду. Что такое «пересчет» индекса? UPDATE, конечно же апдейтит индекс, но это вполне уживается с SELECT'ом.
The core PostgreSQL system obtains AccessShareLock on the index during an index scan, and RowExclusiveLock when updating the index (including plain VACUUM). Since these lock types do not conflict, the access method is responsible for handling any fine-grained locking it might need. An exclusive lock on the index as a whole will be taken only during index creation, destruction, or REINDEX.
https://www.postgresql.org/docs/9.6/static/index-locking.html
Если под «пересчетом» вы понимаете REINDEX, то нет, конечно же при UPDATE никакой REINDEX не делается.
Насколько я понимаю обычно путь джедая к светлой стороне такой
1) Замена update -> insert & delete
2) Если первый пункт не помог, аккумулирование изменений в очереди/кэше и отложенный multi insert/ multi update
3) Если же объем модифицирующих запросов на столько велик, что ничего не помогло, надо уходить с MySQL. Здесь сложно что то посоветовать куда уходить. Для примера можно посмотреть Cassandra, Click House итд
И перед сменой основной СУБД я бы все-таки попытался выжать поболе из используемой. А то все технологии со своими минусами, а с минусами этой мы вроде хоть знакомы.
Сейчас погуглил, не нашел подтверждению пункту 1, так что можно его считать не актуальным. Если не хочется возиться с новой технологией можно рассмотреть вариант репликации master/slave. Пишем в master читаем со slave. Правда при большом объеме модификаций возможно отставание реплик. В 5.7 появился cluster https://dev.mysql.com/doc/refman/5.7/en/faqs-mysql-cluster.html
и вытекающих из этого проблем с оверпересчетом индексов при апдейтах даже непроиндексированных полей.
Это не так. По неизвестной причине уберовцы написали просто вызывающе неверную информацию в своей статье и она, к сожалению, пошла в народ. При апдейте непроиндексированных полей срабатывает HOT-оптимизация и индекс не трогает ( с 2007 года так). Вообще в той статье убера, наряду с несколькими действительно разумными аргументами, есть несколько просто WTF-points.
HOT (Heap-only tuples) is a major performance feature that was added in Postgres 8.3. This allowed UPDATES to rows (which, owing to Postgres's MVCC architecture, are implemented with a deletion and insertion of physical tuples) to only have to create a new physical heap tuple when inserting, and not a new index tuple, if and only if the update did not affect indexed columns.
https://wiki.postgresql.org/wiki/Index-only_scans#Interaction_with_HOT
Ну и собственно, все что угодно по запросу «hot-optimisation postgres», это же не какой-то секрет
А по умолчанию опция выключена? Или они там в Uber совсем тормозят?
В случае убера мы можем попытаться предположить, что у них там большое количество индексов на таблице и большинство апдейтов все-таки затрагивают проиндексированные колонки, но это догадки.
я правильно понял что Uber уехали с PostgreSQL из-за проблем с пересчетом индексов? не разобрались как настроить? Такая очевидная справка?
или системные проблемы с пониманием СУБД?
помогает?
Безусловно.
В убере, по-моему, отдел БД просто любит движуху, вот и мигрируют туда-сюда. Не удивлюсь, если завтра они начнут переезжать куда-нибудь на VoltDB.
в этом подкасте упоминается что переход убера(и вброс статьи) был не только из-за технических вопросов, но и из-за вопроса кадров.
Нужен практический пример, когда вы столкнулись с такой ситуацией в реальной жизни.
Скорее всего можно предложить другую архитектуру хранения и использования данных для такого случая.
Стоимость развязки SELECT — INSERT чуть выше, чем SELECT — UPDATE, не согласны?
Ваше предложение пока что конкуриет по своей непродуманности с развязкой через кластер: UPDATE на мастере, SELECT со слейва. Надеюсь, не надо рассказывать почему такая развязка не развязка?
Как в такой схеме реализовать, к примеру, поиск товара по описанию, если описание — в журнале?
Выборка товаров для покупателей должна происходить из одной таблицы (user_table), а изменение-добавление продавцами в другой (main_table).
Периодически, по мере накопления изменений в main_table данные программно компилируются в один большой запрос типа:
INSERT INTO user_table (key_field, field_1, field_2, ...)
VALUES (key1 , ...), (key2, ...), (key3, ...), ...
ON DUPLICATE KEY UPDATE
field_1 = VALUES (field_1), field_2 = VALUES (field_2), ...
для синхронизации таблиц main_table и user_table.
теперь UPDATE-запросы идут не поодиночке, а предварительно группируются в «журнальной» main_table? и можно ли считать INSERT… ON DUPLICATE KEY UPDATE одним большим запросом?
просто bunch?Да
теперь UPDATE-запросы идут не поодиночке, а предварительно группируются в «журнальной» main_table?Да, но я не стал бы ее называть журнальной, скорее это основная таблица, а user_table — просто ее копия и желательно, чтобы она была вообще на другом сервере для изоляции буферов БД.
и можно ли считать INSERT… ON DUPLICATE KEY UPDATE одним большим запросом?Да. Особенно если запустить его в отдельной транзакции. Такой подход даст существенную экономию на операциях слива буферов изменений в сравнении с кучей отдельных запросов «однострочных» изменений.
Суммарный оверхед от этого должен вырасти, но мы получаем механизм контроля над потоком UPDATE для изначальной точки — и даже можем попытаться коррелировать его с интенсивностью SELECT для той же таблицы.
Мне не очень нравится как скейлится такой подход — три точки встречи, четыре? — и поэтому как архитектурное решение он мне не нравится. Но вот в качестве экстренной аварийной меры может быть очень даже эффективным
А насчет дешевизны INSERT в контексте пересчета индексов уже отписывался
Первая часть не учитывает, что довольно часто сайты пишутся на каких-то фреймворках, в которых заложены данные архитектурные проблемы и без костылей их не порешать.
Dependency Injection — это паттерн, позволяющий легко подсовывать моки при юнит-тестах и/или строить приложение с помощью конфиг файла, в стиле ZF 1.x. Иначе — атипаттерн.
Слабая связанность, гибкость и расширяемость, лучшая читаемость и переиспользуемость — это теперь зовется «атипаттерн»? SOLID, не?
Самый презираемый класс программистов — яваскриптовики
У Вас какие-то комплексы на этот счет? Так-то адекватные люди не разделяют коллег по языку программирования.
Я не понимаю как веб-разработчик вообще может на рабочей машине держать не линукс. Да, интерфейс ужасен, шрифты слетают, окна уродливы. Иксы — прекрасный пример отвратительной архитектуры. Да, приходится думать и/или гуглить там, где в винде и/или макоси достаточно жмакать кнопочки.
А какие-либо объективные плюсы линукса, как веб-разработчик, Вы можете назвать? Или только «мы ж и не дизайнеры»?
— внезапных проблем с \r \n
— проблем с путями "\"
— проблем с путями, отличающихся лишь регистром
и даже больше, на ходу вспомнилось пока это
Вот вы ниже в ответ на
А какие-либо объективные плюсы линукса, как веб-разработчик, Вы можете назвать?
пишете
А линукс заставляет думать. И уметь.
А тут получается если нужно задумываться про разные разделители путей, новой строки и регистрозависимость файловой системы — это минусы.
посыл изначально был о том, что под линухами даже конечным пользователям приходится решать проблемы, достаточно сходные с деплоем web проекта, к примеру. как мимнимум тренирует навыки StackOverflow-driven-development.
Я вот с переходом на Windows испытываю проблемы:
1) С кодировкой (да да, шиндовс до сих пор держит зоопарк из UTF8, cp1251 и даже IBM866 на выдаче VC компилятора)
2) Со злополучными \r\n, в то время как другие ОС принимают любой из вариантов виндовс верен своим стандартам и без \r часто убирает переносы строк, в разном софте по разному, не угадаешь.
3) После шиндовспрограммистов приходится долго и муторно править регистры путей, а бэкслэши вместо слэшей у всех остальных ОС добавляют смеху, ведь CMake (и много других сборщиков и не только) и под шиндовсом принимает стандартный '/', а шиндовая консоль нет.
Итого: если у вас сервера на винде — могу вам только посочувствовать, а если на *nix, то вы огребёте проблем при деплое после разработки на винде. Где тут профит я не вижу.
Я вообще негативно отношусь к Windows и Windows программистам так как считаю, что хорошее ПО должно быть кроссплатформенно и для этого сейчас есть всё, что необходимо, а разрабатывать под виндой это как кактус есть хотябы потому, что консоль и кодировки.
Не очень понял чем работа в Windows мешает кроссплатформенности. Наоборот, если вся команда на linux, кто тогда делает порт на Windows?
Консоль… вы можете поставить любую консоль. Bash, powershell, etc
Как и окружение. Все прекрасно настраивается, кастомизируется. Заметьте, Linux из коробки тоже не огонь.
Чтож, пусть каждый пишет где ему нравится, я как и прежде буду считать, что это АД.
А Linux из коробки (без GUI) для серверов норм.
Вообще смотря на чём, я сталкивался только с C++, так вот кто-то мне уже тут говорил, что если писать в соответствии со стандартом, то никаких проблем не будет, а платформозависимые функции стандартом не назовёшь, не говоря уже о неопределённом поведении.
да да, шиндовс до сих пор держит зоопарк из UTF8, cp1251 и даже IBM866
А вы хоть раз смотрели список кодировок, которые предлагаются некоторыми линуксовыми дистрибутивами при установке в качестве возможных системных? Если хоть выбрать любую из них, то потом в крокозяблы превращаются даже маны… Интересно, зачем вообще в настройки добавляют опцию, которая не работает? :-)
Что же до проблем с кодировкой на винде — то на самом деле проблема не в винде, а в американских разработчиках, которые эти кодировки игнорируют. Почему-то мои программы проблем с кодировками не испытывают.
Со злополучными \r\n, в то время как другие ОС принимают любой из вариантов виндовс верен своим стандартам и без \r часто убирает переносы строк, в разном софте по разному, не угадаешь.
Не путайте Windows и Notepad. Это немного разные программы.
ведь CMake (и много других сборщиков и не только) и под шиндовсом принимает стандартный '/', а шиндовая консоль нет
На самом деле понимает, только надо не забывать заключать пути в кавычки.
А вы хоть раз смотрели список кодировок, которые предлагаются некоторыми линуксовыми дистрибутивами при установке в качестве возможных системных?
Ниразу не видел, увы. В любом случае есть возможность «сделать хорошо», в винде такой возможности нет совсем.
Почему-то мои программы проблем с кодировками не испытывают.
Мне сложно говорить за всех, я тут в установщиках стабильно наблюдаю кракозябры. И повторюсь про VC компилятор, IBM866 ни в какие рамки, пришлось использовать английский, иначе не лечится.
Не путайте Windows и Notepad. Это немного разные программы.
Я вас, вероятно, огорчу, но разработчик один и Notepad входит в стандартную поставку без возможности выпилить. Да и были программы (за давностью лет не помню какие), которые делали то же самое.
На самом деле понимает, только надо не забывать заключать пути в кавычки.
К сожалению часто берутся относительные пути, а комбинации '\' и '/' винда не приветствует даже с кавычками. Во всяком случае у меня не вышло, но может руки неоттуда?
Вообще всё это холивар, который по факту не приведёт к моей любви к этой ОС или вашей ненависти. Вы либо работаете только с Windows, либо не программист, ну я не знаю других причин почему её можно любить.
На самом деле есть еще вариант кросс платформенного приложения под Win/OS X + веб сервисы. Разрабатывать под винду из под Wine то еще "удовольствие". Для комфортной разработки под OS X так или иначе желателен мак. Зато весь веб стек заводится с полпинка на Windows. Вопрос c консолью тоже закрывается очень легко. У меня скажем есть в консоли bash, все утилиты типа grep, awk и прочие. Сейчас вот появилась еще Windows Subsystem for Linux. Вопрос \n vs \r\n тоже закрывается прямо при установке git (checkout \r\n push \n). Раньше еще был плюс в виде Notepad++ — на глаз один из самых быстрых редакторов в плане открытия файла. С выходом VSCode это уже не так актуально.
Правда есть один нюанс. win10 ужасно не стабильная и тормозящая ось. А вот win7 была вполне себе ничего
Зато весь веб стек заводится с полпинка на Windows
Увы, я против веб. Не везде он применим и бэкэнд во многих случаях даже у веба далеко не js.
А если это был упрёк, что веб-стэк трудно завести где-то ещё, то вы снова сильно ошибаетесь, на windows его завести по моему опыту сложней всего в сравнении с другими ОС. И да, win10 невозможно пользоваться, я уже второй месяц в этом убеждаюсь.
Раньше еще был плюс в виде Notepad++
Плюс куда? Винде? Простите, кроссплатформенные JetBrains и Sublime мне гораздо ближе. А код в текстовом редакторе я бы даже не пытался писать.
У меня скажем есть в консоли bash, все утилиты типа grep, awk и прочие
Осталось добавить их в стандартную поставку, были проблемы с установкой дополнительного софта в одной организации.
Простите, кроссплатформенные JetBrains и Sublime мне гораздо ближе. А код в текстовом редакторе я бы даже не пытался писать.
Ну и в чем в таком случае проблема?
К тому, что вы вольны не использовать эти решения, если они приносят больше проблем, чем пользы.
Если вы используете JetBrains или Sublime — то наличие в винде кривого Notepad вашей проблемой не является.
А если это был упрёк, что веб-стэк трудно завести где-то ещё
Нет как раз наоборот. Веб стэк легко завести на чем угодно OS X/Win/Ubuntu/CentOS итд
Увы, я против веб. Не везде он применим и бэкэнд во многих случаях даже у веба далеко не js.
Я лично без проблем заводил под Win node.js, php/nginx, php/apache, golang, rust(правда на ранних версиях была проблема с openssl), java бэкенд. Мне кажется это покрывает процентов 80 всех вариантов
Плюс куда? Винде? Простите, кроссплатформенные JetBrains и Sublime мне гораздо ближе.
JetBrains тяжеловат, плюс к тому будучи написанным на java работает на любой оси. Sublime — да, неплох
Осталось добавить их в стандартную поставку, были проблемы с установкой дополнительного софта в одной организации.
мне кажется не сложнее установки нужных пакетов из aptitude, brew итд.
мне кажется не сложнее установки нужных пакетов из aptitude, brew итд.
Вы не в ту сторону подумали. Права, согласовать, заставить с этим работать всех разработчиков (когда ты один на Маке, целевая Android, но тестовый интерфейс на Qt должен работать на винде, ибо частично тебе с базой «помогает» Windows-программист). Не тривиальная задача настроить сборку в три платформы с минимумом доп утилит и одним методом, ещё и чтоб это работало у каждого в своей IDE.
По вашему комментарию (https://habrahabr.ru/post/329478/?reply_to=10241628#comment_10241608) понял о чем Вы говорите. Да с C++ есть проблемы в области кроссплатформенности. Есть какие то подвижки в правильном направлении (например при использовании CMake) к унификации, но в плане организации сборки, нормального кроссплатформенного решения я не нашел. Хотя мне кажется здесь проблема глубже. В С++ не хватает общего пакетного менеджера и нормального управления зависимостями. Может быть если бы приняли модули в 20 стандарте стало бы проще организовать сборку
а комбинации '\' и '/' винда не приветствует даже с кавычками
Ничего подобного, они работают в любых сочетаниях.
C:\Users\rucku>Xcopy /Y /E "../rucku/SDK.h" «F:/»
0 File(s) copied
C:\Users\rucku>dir
…
07.04.2017 13:34 204 709 SDK.h
…
C:\Users\rucku>Xcopy /Y /E "..\rucku\SDK.h" «F:\»
..\rucku\SDK.h
1 File(s) copied
Конечно, работает, только не везде видать.
Если Вас интересует именно вопрос копирования можно использовать http://gnuwin32.sourceforge.net/
c:\GnuWin32>cp ../GnuWin32/readme.txt ./var
c:\GnuWin32>cp ..\GnuWin32\readme.txt .\var
Обе команды делают одно и то же
Есть еще cygwin, MinGW32 и WSL
Я серьёзно сталкивался с этой проблемой и серьёзно решал её через родные средства (за исключением make/cmake).
А вообще-то имелась в виду ситуация, когда бекенд-разработчики презрительно относятся к фронтенд-разработке. Особенно это комично в случаях, когда последние получают больше.
По поводу Dependency Injection — покажите как вы его используете. И сколько программистов и пилят именно тот код, в котором используется DI?
+ очень удобно подцеплять, отцеплять декораторы и перехватчики
А так у нас есть общая бизнес логика, которая подстраиваться под запускаемую платформу
это отсылает к аргументу phgrey —
и/или строить приложение с помощью конфиг файла, в стиле ZF 1.x..
Если потратить на solid немного больше времени — начинаешь замечать, что часть принципов противоречит друг другу, и тянет архитектуру приложения в разные стороны. D тянет в слабую связанность, но на связность влияет скорее отрицательно. S повышает связность, но может негативно сказываться на связанность.
D+S+O дают много лишних интерфейсов, связанных с абстракцией реализации, а не абстракцией предметной области.
D+S+O+I легко нарушают kiss & yagni. Всё равно приходится идти на некоторые компромиссы.
А еще DI одинаково легко развязывает слои приложения и превращает код в di-лапшу из интерфейсов и реализаций, наследующих друг друга.
Зачем конфиг-то? Достаточно настраивать DI в Composition Root.
Я напримар использую автоконфигурирование, после явную регистрацию через код для сложный моментов. После идет конфигурация через конфиг файл, но мне это потребовалось всего один раз за всю карьеру(по сути это было больше для тестера, что бы он мог сравнивать несколько конфигураций кода, когда ему нужно было. когда было принято решение это улетело в автоконфигурацию)
И никаких проблем. Вообще. И шрифты в IDE приятные, да и в прочих программах тоже :) Ну да, нужно всего-лишь хотеть чуть чуть разобраться и может быть где-то потратить час на то что-бы исправить какую-то шероховатость один раз потому что разработчики оголтелые маководы и на линуксе у вас будет та же самая проблема :D
Серьёзно, оголтелые маководы последнее время становятся хоть и мелкой, но назойливой проблемой.
Если пользователь Windows разобрался с vagrant — то это наш человек, просто зачем-то насилующий себе разум.
Линуксоиды, по какой-либо причине юзающие иногда Окошечки — игры, фотожаба, мультимедиа, ie — не в счет.
git config --system core.ignorecase false
потому что они умудрялись в одной директории называть файлы с однотипными префиксами а-ля OneTwo* в названии всеми возможными комбинациями заглавных букв.OneTwoABBASD — рандом или цикл, не? к /tmp не приучены?
или OneTwoCamelCase в именах файлов напрягает?
Лучше обоснуйте свой тезис про потраченное время, я как-то не замечаю чтоб из-за выбора оси я тратил по четыре лишних часа в день.
Вы это про какой?
Линукс заставляет тратить много времени. И это дорого. Очень дорого.
Repository + Entity — driven db access в 100% наблюдаемых мною случаев превращается в непригодный к дальнейшему использованию legacy код.
Если репозиторий не нагружать лишними функциями, то вполне себе рабочий вариант. Репозиторий должен кэшировать результаты и выполнять запросы в базу. Все остальное лишнее. Мне кажется куда более часто встречающаяся проблема это увлечение god object и не умение найти баланс в делении кода на атомарные логические сущности
Скорее всего причиной можно считать то, что репозитории используются в stateless режиме — как группа функций схожего назначения. В отличии от конкуриющего с ним паттерна ActiveRecord, в котором сразу ясно что именно является состоянием.
При активной работе над кодом нескольких программистов зачастую приходится специально договариваться по вопросу какие функции считать лишними, а какие — нет. В AR действительно получается проще договориться что к чему относить.
ну вот же — 1, 2, 3, 4 — списки проблем которые нужно проверить. с пояснениями.
тащемта в основном используется в смысле «вообще-то». И вы так спрашиваете, как будто это что-то плохое.
что делать? внимательно перечитать комментарии и искать специалиста. я могу двух показать. договариваться об удаленном аудите за сколько скажут.
не можете? обнять коленки и плакать.
это мне чек-лист если что.
в 99% случаев правильно поставленный вопрос получает ответ на гугле. Это называется StackOverflow driven development. Оставшийся один процент придется задать.
ну и правило «зачем?»: если ты не понимаешь зачем это — оно тебе не нужно.
Если можно, заголовок бы подправить: «чек-лист» пишется через тире. Это составное слово, такое, как всем известное со школы «диван-кровать», они всегда пишутся через тире, ибо правило гласит:
Сложные существительные, образованные без соединительной гласной, каждая часть которых может употребляться как самостоятельное слово, пишутся через дефис.
Замечаю просто сейчас в последнее время какую-то нездоровую тенденцию к их употреблению исключительно в таком виде, что, если честно, реально вымораживает. Ладно бы если изначально они писались бы верно, то тенденция пошла бы правильная, как это часто бывает, однако кому-то стоило начать писать не верно, с тех времен и клонируется… Заранее благодарен!
В русском с этими дефисами в заимствованных словах что-то странное.
Вот взять хотя бы «дедлайн» вполне можно употреблять отдельные части самостоятельно.
Но дефис не пишут.
А насчет дедлайна — да, согласен, так уж завелось, так все и пишут. Но в любом случае, никак не раздельно)
они всегда пишутся через тире, ибо правило гласит: "… пишутся через дефис"
Что-то я не понимаю...
Repository + Entity — driven db access в 100% наблюдаемых мною случаев превращается в непригодный к дальнейшему использованию legacy код.Автор, можете аргументировать более развернуто? Согласен с предыдущим комментарием: если не пихать в репо все подряд методы, код получается вполне чистым.
Запрос к 10 таблицам в вебе в продакшне может служить поводом для увольнения его автора и ревьювера, ИМХО. Господа, юнион, джоины и подзапросы 3-го уровня вложенности — это неплохой способ повыпендриваться.
Не очень понял альтернативу. Вот есть данные, лежат в 10 таблицах, надо их всех показать.
Вместо запроса к 10 таблицам делать 10 запросов?
А можно какие то пруфы данного утверждения? Просто если с подзапросами я согласен, то join при правильном проектировании БД обычно проблем не вызывает. Обычно на мускуле самая большая проблема group by. Уже на 20млн записей посчитать статистику становится проблемой
Не сразу понял про соединение.
Положительний результат можно било получить только в условиях полного «топорного» использования БД.
По-хорошему, такие агрегаты должны храниться и обновляться отдельно если они действительно часто запрашиваться.
Напомню, речь шла не о редких аналитических запросах, а об основных запросах веб-приложения к базе. Такие запросы нельзя держать настолько сложными.
У меня в статье?
И, кстати, не вижу никаких причин, по которым данные, хранящиеся отдельно, не могут быть актуальными в любой момент времени.
Что вы подразумеваете под «хранящиеся отдельно»? Если речь про кеши, то аргумент трудно принять. Если про посчитанные агрегаты, то это не всегда применимо — для разных пользователей будут свои значения агрегатов в каждый момент времени, их нет смысла считать заранее.
система медицинских заказов на целый край хранит данные, наверное, в чем-нибудь максимально энтерпрайзном? я, к сожалению, не умею проводить «агрерацию в pipeline mode по покрывающим индексам» привычными для веба инструментами.
и какая, если не секрет, нагрузка на систему?
Вообще «никогда не делайте join руками, умные дяди-разработчики движкоа баз даных потратили миллион человекочасо что-бы делать это максимально эффективно» — это совершенно капитанский совет, референом звучащий в абсолютно любом «проблемы перформанса для детсадовцев».
вам, простите, приходилось поддерживать что-то со сходным с mysql-query-plan-builder legacy? Или с его же переменчивым набором требований? Как вы думаете, много там багов?
хотите влет пример JOIN, который я руками гарантированно сделаю быстрее, чем используемая на проде версия MySQL сервера?
Но ето возможно только если вы неправильно «готовите» БД.
О обемах с которими работаю > 600 Gb OLTP база с некоторими елементами DW редологов за сутки около 50-80Gb. Да и вся бизнес логика >500 000 строк в БД. И ето все крутитца всего на 2 ядрах Power 7+. При етом некоторие запросы на несколько екранов и десятки таблиц. Перед етим я работал с MYSQL с базами > 50Gb правда и сервера были послабее. Но я не могу представить ситуацию когда обединение таблиц будет быстрее вне БД. ( ведь будут накладние расходы — сеть, преобразование)
Судя по "… редологов..", имеется ввиду Оракл, это его термин для бинарных логов.
А так да, join вне базы, это антипаттерн сравнимый с характеру с вашим примером «Проблема «n+1»»
Такая бомба замедленного действия.
Я так понимаю Вы имеете ввиду, что у вас есть большая зашарденная табличка, а справочники лежат все на одном инстансе в одном месте, и вот потом Вы пытаетесь на клиенте сопоставить данные вытащенные с шардов с данными из справочников. И тут надо смотреть насколько эффективно Вы это делаете, может оказаться так, что дублирование справочников по шардам — может оказаться эффективнее централизованного хранения, а может и хуже.
Тут ведь проблема с JOIN на клиенте в объемах, которые вы пытаетесь обрабатывать. Грубо говоря, вы сделали запрос с фильтрацией (WHERE) в БД из основной таблицы, а потом начинаете в полном объеме (без WHERE) подтягивать справочники чтобы сделать ручной JOIN. И, ВДРУГ, в какой-то момент оказывается, что у справочники то большие, а в результате фильтрованного запроса часть данных справочника вообще не используется. И в итоге вы нагибаете базу заставляя её уходить в чтение с дисков на больших справочниках, нагибаете сеть — заставляя гонять кучу данных, нагибаете клиента — отъедая ОЗУ и проц на ручной JOIN.
А можно было сделать JOIN в БД и сразу отфильтровать только нужные данные.
В общем, складывается впечатление, что автор не смог разобраться с БД и почему там хреновый план выполнения запроса, и решил в лоб на клиенте сделать JOIN, потому что лень переписывать неэффективный SQL.
На эту и смежные темы написаны сотни статей, подготовлены презентации для десятков конференций Highload и прочих
Если лень гуглить:
http://www.myshared.ru/slide/9793/ (слайд 38)
http://highload.guide/blog/sharding-patterns-and-antipatterns.html (к тезису про справочники, и вашему предположению, что все нужные данные на одном шарде)
http://www.myshared.ru/slide/9793/ (слайд 38)
Поглядел. И не понял почему они вообще решили при этом использовать реляционную БД. Выключить все что дает движок, и использовать СУБД как Key-Value хранилище к которому можно писать запросы на SQL, что выглядит мягко говоря странным, так как SQL это еще один дополнительный слой, который можно в такой системе выкинуть.
Давайте сразу определимся, есть хайлод в котором данные не важны, ну в некоторой степени не важны — потеряем мы комментарий пользователя, или данные сессии похерим, ничего страшного — пользователь перенаберет/перезайдет.
А есть хайлод в котором транзакции, ACID, нормализация и вот это вот все называемое реляционной моделью данных. А данные там критически важные — как самый яркий пример — финансовые транзакции. А теперь попробуйте объяснить заказчику системы, почему у вас данные не консистентны из-за того, что Вы не используете механизм транзакций. Или данные пропали, потому что не успели зафиксироваться на дисках. Или топовое серверное железо загибается, из-за того, что программер решил всю базу к клиенту гонять и обратно, вместо работы с данными в самой базе. И таких примеров много.
Статья «Чек-лист по выживанию сайта».
Я про join и шардинг (не всегда данные влазят в одну базу и обилие join серьезно усложняет шардирование), а вы мне про справочники и транзакции.
Почему вы решили что я не использую транзакции, опять фантазия?
Не вижу смысла продолжать обсуждение.
Просто Вы не хотите посмотреть шире, и рассматриваете шардинг как размазывание одного объекта по кучи хостов из которого «магическим» образом вытаскиваются данные, и накладывание не который JOIN чревато проблемами.
Но если посмотреть на шардинг как на комплекс независмых хостов, в каждом из которых есть все необходимые данные для работы хоста — то проблема джойнов исчезает. Вы просто заранее решаете какой хост предпочтителен в данном конкретном случае, для доступа к конкретным данным.
JOIN на шарде — вполне годная тема, особенно если архитектура изначально предрасположена к шардированию. Это не отменяет того, что возможно придется сделать довыборку данных из другого источника и в этом нет ничего страшного. Транзакции нужно использовать для финансовых операций с этим никто не будет спорить.
Есть другая крайность с которой мне приходится часто сталкиваться — 1 сервер БД который не в состоянии переварить все данные и запросы, блокировки и прочее. Когда приложение написано с огромным кол-вом объединений. Чтобы растащить такую базу нужно очень сильно поднапрячься. Именно поэтому в вебе join больше зло. Потому как даже просто вынос конкретной таблицы на отдельный сервер представляет сложную задачу.
наибольшая табличка > 550 000 000 строк ежедевно увеличиваєтся 300 000 строк и ето не логи а таблица влияющая на остатки.
Что такое "RDB таблица", которую нельзя использовать для организации очереди? Гуглится только RGB :-)
Забавно, что в первой части ActiveRecord упоминается как приводящий к проблеме "n + 1", а во второй — как отличный паттерн организации кода.
С бизнесом можно разговаривать только на языке бабла. Он не восприимчив к красоте решений, нормализации базы, CAP-теоремам и прочим IT-ценностям. Он понимает деньги и сроки.
Попытка спросить какую нормальную форму использкует разработчик или ваша БД приведена к третьей нормальной форме — как правило ставит в тупик. Люди не знают кто такой Эдгар Кодд!!! Поэтому есть СУБД, но баз данных нет. Отсюда все проблемы и так называемым электронныи правительством, госуслугами и т.д.
Dependency Injection — это паттерн, позволяющий легко подсовывать моки при юнит-тестах и/или строить приложение с помощью конфиг файла, в стиле ZF 1.x. Иначе — атипаттерн.
Святые, слова.
Расскажите это разработчикам Angular
Буду ссылаться вместо того, чтобы каждый раз объяснять, почему до сих пор пишу все запросы руками.
В плане базы я бы сделал акцент на то, что большинство систем работают в основном на чтение (1 запись на 100 чтений). Поэтому простота чтения должна быть обеспечена в первую очередь. Академические нормальные формы, например, отношения many-to-many в отдельных таблицах, должны быть продуманы, нужны ли они вообще в каждом конкретном случае.
5 копеек про фронт: я бы выделил 3 периода: до jquery, с jquery, с mvvm (knockout/angular/react/vue). Если система не в 3-ем периоде и хочет развиваться, то нужно переходить. Внутри mvvm переход едва ли оправдан — несмотря на различную внутреннюю логику, нет ничего на angular/react, чего нельзя написать на старичке knockout в тех же строчках кода и той же сложности. Новеньким я бы советовал vue.js как последователя, который включил все лучшее от предшественников.
Фанаты реакт хвалятся виртуальным dom-деревом — мол самые затратные операции — операции с dom, поэтому прослойка, которая фильтрует изменения dom, делает реакт очень быстрым. Однако реакт тоже прекрасно вешается, если не думать. А если думать, то любая универсальная прослойка будет медленнее, чем нативный специализированный код, который не делает ничего лишнего.
Такая нагрузка на таблицу предполагает, что это явно не последняя таблица в проекте. И для оптимизации этих запросов вы готовы потратить времени чуть больше, чем просто создать пару индексов.
Тогда возможно стоит добавить микросервис (простой рест сервис) над этой таблицей, через который пойдут наиболее тяжёлые и частые запросы (select), пусть даже не все, и пусть там данные кэшируются хотя бы секунд 5-10 (20), и пусть он выполняет какие-нибудь несложные фильтрации с этими данными — разве это не стандартное решение для микросервисной архитектуры?
От мастер-слейв это решение отличается объёмом используемых ресурсов (микросервис будет сильно скромнее и более интегрированным в ваш проект и бизнес логику) и тем что вы получаете механизм регулирования нагрузки через изменения времени кеша.
- Подопытный: MySQL 5.6
- Данные кешируются в набор однотипных таблиц с разделением по одной из характеристик данных
- У каждой записи есть поле с меткой времени Unix
- В нескольких самых больших таблицах в районе 1 млн записей, длина записи чаще всего 8...30 КБ
- Скорость записи данных в таблицы достигает до 6...10 зап/с
- Устаревшие данные, старее заданной временной метки и отвечающие определенному критерию, на регулярной основе удаляются 1 раз в сутки в момент минимальной нагрузки от посетителей скриптом, запускаемым по крону. Доля таких данных в общем объеме записей в заданном временном интервале (сутки за пределами заданной временной метки) составляет 5...50%
- Сейчас по этому полю индекса нет, т.к. фактически оно используется только для этой цели и еще сортировки результатов запроса DESC (99.99% случаев в результирующем сете 1 строка, но иногда может быть 2 или даже 3)
- Работа скрипта-мусорщика занимает 405...415 сек
Так ставить на этом поле индекс для ускорения работы скрипта-мусорщика или нет?
Работа скрипта-мусорщика занимает 405...415 сек
Все зависит исключительно от того, устраивает ли время работы мусорщика.
Если я правильно понимаю, то без этого индекса работа скрипта-мусорщика будет замедляться по мере разрастания таблиц (накопления данных, которые не подлежат удалению). В год добавляется примерно 200-300 миллионов записей, из них от 100-290 миллионов будут оставаться в базе навсегда.
Это довольно странная цифра, если вы говорите, что сейчас у вас всего миллион записей. Но если это правда — то за первый год мусорщик замедлится не менее чем в сотню раз, надо это учитывать.
Все зависит исключительно от того, устраивает ли время работы мусорщика.
Уже не устраивает, но не могу для себя решить, что важнее — мириться со временем работы мусорщика или добавлять накладных расходов к инсерту данных.
В год добавляется примерно 200-300 миллионов записей, из них от 100-290 миллионов будут оставаться в базе навсегда.
Сейчас годовой темп прироста 4...5 млн записей на 10+ таблиц с постоянной тенденцией к росту. Но Ваши цифры мне нравятся — заработки будут выше :)
Глубокой ночью раз в неделю зачищаются все данные к которым за последние 2 года не обращались повторно. Будет расти база — буду зажимать возраст невостребованных данных, но сейчас более 80% данных запрашиваются повторно хотя бы раз в интервале от 6 мес после добавления в БД (обсчитывал на дампе на ноуте, фиксируется только метка времени последнего обращения).
Если вас не устраивает время работы мусорщика — то без индекса вы ну никак не обойдетесь.
Что же до накладных расходов — то их можно быстро прикинуть сли знать сколько индексов уже есть. Если индексов нет — то считайте, что все операции вставки от появления первого индекса замедлятся в два раза. Если у вас десять индексов — то добавление одинадцатого замедлит вставки всего на 10%.
PS если вы думаете построить индекс по времени последнего чтения записи — то надо обновлять это поле только если обращений не было последний месяц
Но пока что склоняюсь к тому, что лучше его добавить.
Этой ночью скрипт-мусорщик отработал за 234 сек вместо 405...415 сек ранее. Каких-то лагов с работой основного функционала не заметил. Дальше, похоже, надо переходить на хостинг с SSD. :)
старее заданной временной метки и отвечающие определенному критерию
лично я бы организовал составной индекс — из timestamp и полей, участвующих в определенном критерии, если таковой индексируем.
Чек-лист по выживанию сайта