Лучшая практика для репликации SQL / управления нагрузкой

#sql #database #mariadb #load #database-performance

#sql #База данных #mariadb #загрузка #база данных-производительность

Вопрос:

В настоящее время я использую сервер Ubuntu с Mariadb на нем. Он обслуживает все sql-запросы для веб-сайта (с большим количеством запросов на нем).

Несколько раз в день мы импортируем большие CSV-файлы в базу данных для обновления наших данных. Проблема в том, что эти csv загружают базу данных (импорт занимает около 15 минут).

Кажется, что используется только 1 ядро из 4, но, тем не менее, веб-сайт (или, лучше, его запросы sql в течение этого времени) становятся смехотворно медленными. Теперь у меня вопрос: что я могу здесь сделать, чтобы повлиять на веб-сайт в меньшей степени? Я рассматривал репликацию базы данных на другой сервер, но я ожидаю, что это будет использовать такое же количество ресурсов во время импорта, так что никакой реальной пользы здесь, я думаю?

Другая вещь, которую я рассмотрел, — это иметь 2 базы данных SQL, и во время импорта все запросы должны быть переключены на другой сервер базы данных, и я бы в основном выполнял каждый импорт дважды, один на сервере 1 (в течение этого времени сервер 2 должен обслуживать сайт), как только это будет сделано, веб-сайт должен быть удаленна сервер 1, а импорт выполняется на сервере 2. Хотя это сработало бы, кажется, что это довольно сложно для неидеального решения (например, как обрабатываются запросы при переключении с сервера 1 на сервер 2 и так далее.

Итак, какие решения существуют здесь, желательно несколько доступные. Все идеи и подсказки приветствуются.

Заранее спасибо с наилучшими пожеланиями

Menax

Комментарии:

1. Что касается проблемы с 1 потоком, которая, по-видимому, решаема с помощью решения здесь, определенно собираюсь попробовать. dba.stackexchange.com/questions/5666 /…

2. «SQL Server» — это название конкурирующего продукта. Пожалуйста, не используйте его при обращении к MariaDB; это сбивает с толку.

Ответ №1:

Является ли импорт заменой всей таблицы? Если это так, загрузите его в отдельную таблицу, а затем замените ее на место. По существу нулевое время простоя, а именно во время RENAME TABLE . Подробнее см. http://mysql.rjweb.org/doc.php/deletebig или , возможно, http://mysql.rjweb.org/doc.php/staging_table

Если импорт выполняет что-то еще, пожалуйста, предоставьте подробную информацию.

Одно соединение использует одно ядро, не более.

Подробнее (из комментариев)

 SELECT  id, marchants_id
    from  products
    WHERE  links LIKE '%https://´www.merchant.com/productsite_5'
    limit  1
  

Это сложно оптимизировать из-за ведущего подстановочного знака в LIKE . Это действительно то, что вам нужно? В нынешнем виде этот запрос должен сканировать таблицу.

 SELECT  id, price
    from  price_history
    WHERE  product_id = 5
    order by  id desc
    limit  1 
  

Это выиграло бы от INDEX(product_id, id, price) — в таком порядке. С этим индексом запрос будет максимально приближен к мгновенному.

Пожалуйста, предоставьте оставшуюся часть транзакции с обновлением и вставкой, а также SHOW CREATE TABLE . Вполне возможно, что есть способ «пакетного» выполнения действий, а не указывать цену одного продукта за раз. Это может ускорить работу в 10 раз.

Переключение между двумя серверами — только если данные доступны только для чтения. Если вы иным образом изменяете таблицы, это было бы большим кошмаром.

Для полной замены таблицы,….

  1. СОЗДАЙТЕ новую ТАБЛИЦУ
  2. Заполните его
  3. ПЕРЕИМЕНУЙТЕ ТАБЛИЦУ, чтобы заменить новую таблицу на место.

(Но я все еще недостаточно хорошо понимаю вашу обработку, чтобы сказать, лучше ли это. Когда вы говорите «переключить действующую базу данных», вы имеете в виду сервер (компьютер), БАЗУ ДАННЫХ (схему) или только одну ТАБЛИЦУ?

Комментарии:

1. Сайт в основном является своего рода сайтом сравнения цен (не на 100%, но я думаю, что это ближе всего к нему без особых объяснений) В базе данных есть таблица с ценами и ее идентификатором продукта и идентификатором поставщика Дата. Старые цены хранятся для pricehistory в другой таблице, и всякий раз, когда мы получаем обновленный csv-файл от любых поставщиков с новыми ценами, мы его импортируем. У нескольких поставщиков большинство из них имеют от 30 000 до 50 000 продуктов (в формате csv). И поскольку существуют разные продавцы, не вся таблица обменивается (обновляется) только ее частями.

2. @Menaxerius — Как вы узнаете, какие строки заменяются? (Мои предложения все еще актуальны, но «частичная» замена добавляет некоторую сложность.) И все ли обновления поступают одновременно? Или вы заменяете данные от одного поставщика за раз?

3. да, это известно (в основном все строки от этого поставщика с идентификатором поставщика), они заменяются у одного поставщика за раз. Итак, если я правильно понимаю, вы предлагаете мне импортировать их в другую таблицу, а затем переместить все записи от указанного поставщика в таблицу, где они фактически используются сайтом? Большое спасибо за ваши предложения!

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

5. @Menaxerius — Включает ли эта «замена» удаление некоторых строк (например, товары, которые больше не продаются), вставку некоторых строк (новые товары) И обновление некоторых строк (изменения цен и т. Д.)? Или … нет новых строк? или нет удаленных строк?