жарить! Проблемы отрасли, несколько распространенных решений для пейджинга между базами данных

база данных MySQL

Зачем нужно изучать пейджинг между библиотеками?

Многим интернет-компаниям необходимо извлекать данные путем подкачки, например:

(1) Когда сообщений WeChat слишком много, перетащите сообщение на страницу N;

(2) Когда JD.com размещает слишком много заказов, заказ на странице N удаляется;

(3) Просмотрите 58.com и проверьте сообщение на странице N;

Таблица сообщений, таблица заказов и требования к вытягиванию подкачки таблицы сообщений, соответствующие этим бизнес-сценариям, имеют следующие общие характеристики:

(1)Существует идентификатор первичного ключа компании., msg_id, order_id, tiezi_id;

(2)Разбивка на страницы сортируется по идентификатору первичного ключа, не связанного с бизнесом., в бизнесе порядок часто сортируется по времени;

Когда объем данных невелик, как реализовать требование пейджинга между базами данных?

(1) Построить индекс по времени поля сортировки;

(2) Это может быть достигнуто с помощью смещения/предела, предоставляемого SQL;

Например:

select * from t_msg order by time offset 200 limit 100;

select * from t_order order by time offset 200 limit 100; 

select * from t_tiezi order by time offset 200 limit 100;

Голос за кадром: здесь предполагается, что на странице находится 100 фрагментов данных, и третья страница данных извлекается.

Зачем нужна подбиблиотека?

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

После того, как задействована подбиблиотека, ключ доступа «подбиблиотека на основе» не может быть экранирован.Какое поле использовать для разделения базы данных по горизонтали?

В большинстве бизнес-сценариев будет использоваться идентификатор первичного ключа бизнеса.

После определения ключа доступа к подбиблиотеке следующим шагом являетсяКак определить алгоритм подбиблиотеки?

В большинстве бизнес-сценариев для разделения базы данных используется алгоритм бизнес-первичного ключа по модулю.Преимущества этого:

(1) То есть он может обеспечить равномерное распределение данных каждой библиотеки;

(2) Он также может гарантировать, что распределение запросов каждой библиотеки будет однородным;

Это действительно хороший способ просто реализовать балансировку нагрузки, и этот метод широко используется в архитектуре Интернета.

Более конкретный пример:

Пользовательская библиотека разделена на две библиотеки после горизонтального разделения:

(1) Подбиблиотека основана на ключе доступа — uid;

(2) Алгоритм подбазы данных является uid по модулю: данные с более чем 0 в uid%2 попадут в db0, а данные с более чем 1 в uid%2 попадут в db1;

После разделения базы данных по горизонтали, если компания хочет запросить «самого последнего зарегистрированного пользователя на странице 3», то есть запрос на пейджинг между базами данных,Как это сделать?

В одной библиотеке вы можете

select * from t_user order by time offset 200 limit 100;

Став двумя библиотеками, подбиблиотека основана на uid, а сортировка основана на времени Уровень базы данных теряет глобальное представление сортировки по времени, и данные распределяются по двум библиотекам.Что нам теперь делать?

Как выполнить требования запроса «разбивка баз данных на несколько уровней, а основа базы данных и основа сортировки — это разные атрибуты, и их необходимо разбить на страницы», чтобы достичь:

select * from T order by time offset X limit Y;

Этот тип SQL с подкачкой между базами данных является технической проблемой, которая будет обсуждаться позже.

Вариант 1: Метод глобального видения

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

Итак, какие данные являются данными третьей страницы глобальной сортировки?

Необходимо обсудить три ситуации.

(1) В крайних случаях данные двух библиотек точно совпадают

Если данные двух библиотек абсолютно одинаковы, требуется только половина смещения каждой библиотеки, а затем берется половина страницы, что является окончательными желаемыми данными (как показано в розовой части данных выше). .

(2) В крайних случаях результирующие данные поступают из библиотеки

Также возможно, что распределение данных двух библиотек несбалансировано.Например, время всех данных в db0 больше, чем время всех данных в db1.Может показаться, что данные на третьей странице библиотеки данные на третьей странице после глобальной сортировки (как показано в розовой части данных на рисунке выше).

(3) Как правило, данные каждой базы данных содержат часть

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

Поскольку непонятно, в чем дело, необходимо:

(1) Каждая библиотека возвращает 3 страницы данных;

(2) Полученные 6 страниц данных сортируются в памяти на сервисном уровне для получения глобального представления данных;

(3) Возьмите третью страницу данных, чтобы получить желаемые глобальные данные пейджинга.

Подытожим шаги этой программы:

(1) Перепишите оператор SQL, т.е.

order by time offset X limit Y;

переписать как

order by time offset 0 limit X+Y;

(2) Уровень службы отправляет переписанный оператор SQL в каждую подбазу данных;

(3) Предполагая, что всего имеется N библиотек, сервисный уровень получит N*(X+Y) фрагментов данных;

(4) Сервисный уровень сортирует полученные N*(X+Y) фрагментов данных в памяти;

(5) Памятьпосле сортировкиЗатем возьмите записи Y после смещения X, которое является страницей данных, необходимой для глобального представления;

Каковы преимущества метода глобального обзора?

Изменяя оператор SQL на уровне службы и увеличивая объем отзыва данных, можно получить глобальное представление, бизнес без потерь, а требуемые данные могут быть точно возвращены.

Каковы недостатки метода глобального обзора?

Недостатки очевидны:

(1) Каждая подбаза данных должна возвращать больше данных, что увеличивает объем сетевой передачи (потребление сети);

(2) Помимо сортировки базы данных по времени, сервисный уровень также необходимо сортировать дважды, что увеличивает объем вычислений (потребление ЦП) сервисного уровня;

(3) Самое опасное, что производительность этого алгоритма будет резко падать по мере увеличения номера страницы, потому что каждая подбаза данных должна возвращать X+Y строк данных после перезаписи SQL: вернитесь на страницу 3, X=200 в offset ; Если вы хотите вернуть 100-ю страницу, X=9900 в смещении, то есть каждая подбаза данных должна вернуть 100 страниц данных, объем данных и объем сортировки значительно увеличатся, а производительность уменьшится. уменьшить прямо.

Несмотря на то, что «метод глобального видения» имеет низкую производительность, его работа осуществляется без потерь, а данные точны, поэтому его можно рассматривать как решение.Есть ли решение с лучшей производительностью?

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

Вариант 2: Запрет метода запроса перехода на страницу

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

Как показано на рисунке выше, вы не можете пропускать страницы, поэтому вы можете проверить только первую страницу в первый раз:

(1) будет запрашивать

order by time offset 0 limit 100;

переписать как

order by time where time>0 limit 100;

(2) Эффект вышеописанной перезаписи такой же, как и у ограничения смещения 0 100. Каждая подбаза данных возвращает страницу данных (розовая часть на рисунке выше);

(3) Уровень службы получает 2 страницы данных, сортирует память и извлекает первые 100 фрагментов данных в качестве последней первой страницы данных.Эта глобальная первая страница данных, вообще говоря, каждая подбаза данных содержит часть данных (как показано розовым цветом на картинке выше. часть);

Это решение также требует сортировки памяти сервера, разве это не то же самое, что и «метод глобального просмотра»? Извлечение первой страницы данных действительно одинаково, но план извлечения «следующей страницы» каждый раз разный.

При нажатии "Далее" нужно подтянуть вторую страницу данных.На основе первой страницы данных можно найти максимальное значение времени первой страницы данных:

этозаписано на предыдущей странице time_max**, будет использоваться в качестве условия запроса для получения данных второй страницы**:

(1) будет запрашивать

order by time offset 100 limit 100;

переписать как

order by time where time>$time_max limit 100;

(2) На этот раз вместо того, чтобы возвращать 2 страницы данных («метод глобального видения, он будет переписан как смещение 0, предел 200»), каждая подбаза данных по-прежнему возвращает одну страницу данных (как показано в розовой части в рисунок выше);

(3) Сервисный уровень получает 2 страницы данных, сортирует память и извлекает первые 100 фрагментов данных в качестве конечных данных страницы 2. Вообще говоря, каждая подбаза данных содержит часть данных (как показано на рисунке). выше).розовая часть);

Таким образом, при запросе данных на странице 100 глобального представления вместо перезаписи условий запроса как

смещение 0 ограничение 9900+100 (возврат 100 страниц данных)

Вместо этого перепишите его как

time>$time_max99 limit 100 (по-прежнему возвращает страницу данных)

Чтобы гарантировать, что объем передаваемых данных и объем отсортированных данных не приведет к снижению производительности, так как страницы постоянно перелистываются.

Вариант 3. Разрешение метода потери точности данных

"Метод глобального просмотра" может возвращать точные данные без потерь для бизнеса. Когда количество страниц запроса велико, например, 100-я страница, могут возникнуть проблемы с производительностью.Допустимо ли для бизнеса, что возвращенные 100 страниц не являются точными данными, но допускаются некоторые отклонения данных?

Во-первых, давайте рассмотрим принцип базы данных подбазы данных - баланс данных.

Что такое база данных, подбаза данных - принцип баланса данных?

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

Например, в случае случайного uid используйте uid по модулю для разделения на две библиотеки, db0 и db1:

(1) Атрибут пола: если доля пользователей-мужчин в базе данных db0 составляет 70%, доля пользователей-мужчин в базе данных db1 также должна составлять 70%;

(2) возрастной признак, если доля девушек 18-28 лет в базе данных db0 составляет 15%, то доля девушек в базе данных db1 также должна быть 15%;

(3) Атрибут времени, если доля пользователей, которые входят в систему до 10:00 каждый день в базе данных db0, составляет 20%, такой же статистический закон должен быть и в db1;

Используя этот принцип, чтобы запросить глобальные 100 страниц данных, просто замените:

offset 9900 limit 100;

переписать как

offset 4950 limit 50;

то есть каждыйПодбиблиотека смещена наполовину(4950),Получить данные половины страницы(50 записей),объединение результирующих наборов данных, в основном можно считать, что это данные смещения 9900 предела 100 глобальных данных.Конечно, данные на этой странице не точны.

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

Голос за кадром: если бизнес может это принять, это решение имеет наилучшую производительность и настоятельно рекомендуется.

Вариант 4. Дополнительный метод запроса

Существует ли техническое решение, которое может удовлетворить конкретные потребности бизнеса без ущерба для бизнеса и высокопроизводительный метод? Это окончательное оружие, которое будет представлено позже, «Вторичный метод расследования».

Для удобства примера, предполагая, что на странице всего 5 фрагментов данных, оператор SQL для запроса страницы 200 выглядит следующим образом:

select * from T order by time offset 1000 limit 5;

Шаг 1: переписать запрос

select * from T order by time offset 1000 limit 5;

переписать как

select * from T order by time offset 500 limit 5;

И доставьте его во все подбазы данных.Обратите внимание, что смещение 500 получается из общего смещения глобального смещения 1000, деленного на количество горизонтально разделенных баз данных на 2.

Голос за кадром: из-за относительно большого объема данных и сильной случайности данных это все еще может соответствовать «базе данных подбазы данных - теореме о балансе данных».

Если это 3 подбиблиотеки, это можно переписать как

select * from T order by time offset 333 limit 5;

Предположим, что данные (время, uid), возвращаемые этими тремя подбазами данных, следующие:

Как видите, каждая подбаза данных возвращает страницу данных, отсортированных по времени.

Шаг 2: Найдите минимальное значение всех возвращенных 3 страниц данных

Для первой библиотеки минимальное время для 5 частей данных 1487501123;

Для второй библиотеки минимальное время для 5 частей данных 1487501133;

Третья библиотека, минимальное время 5 частей данных 1487501143;

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

Голос за кадром: Это значение time_min очень важно, и time_min используется на каждом шаге в следующем.

Шаг 3. Запрос вторичной перезаписи

Первый переписанный оператор SQL:

select * from T order by time offset 333 limit 5;

Второй раз — переписать его в оператор between:

  • Начальная точка между time_min

  • Конечная точка между ними — это максимальное значение исходных данных, возвращаемых каждой подбазой данных.

Первая ветка, максимальное значение первых возвращаемых данных — 1487501523.

Таким образом, запрос переписывается как:

select * from T order by time where time between time_min and 1487501523;

Вторая ветвь, максимальное значение первых возвращенных данных — 1487501323.

Таким образом, запрос переписывается как

select * from T order by time where time between time_min and 1487501323;

Третья ветвь, максимальное значение первых возвращаемых данных — 1487501553.

Таким образом, запрос переписывается как

select * from T order by time where time between time_min and 1487501553;

По сравнению с первым запросом условия второго запроса смягчены, поэтому второй запросвернет больше данных, чем набор результатов первого запроса, предполагая, что данные (время, uid), возвращаемые этими тремя подбазами данных, следующие:

можно увидеть:

Набор результатов подбиблиотеки один, поскольку time_min исходит из исходной подбазы данных, возвращаемый набор результатов подбазы данных один совпадает с первым запросом (поэтому это посещение можно опустить);

Результирующий набор подбиблиотеки два, возвращается на 1 данных больше, чем в первый раз, и 1 запись в голове (запись с наименьшим временем) является новой (розовая запись на рисунке выше);

Результирующий набор подбиблиотеки три, возвращается на 2 данных больше, чем в первый раз, и 2 записи в голове (2 записи с наименьшим временем) являются новыми (розовые записи на рисунке выше);

Шаг 4: Создайте виртуальную запись time_min в каждом наборе результатов и найдите глобальное смещение time_min.

в первой библиотеке, смещение time_min в первой библиотеке равно 333;

во второй библиотеке, смещение (1487501133, uid_aa) равно 333 (согласно первому условию запроса), поэтому смещение виртуального time_min во второй библиотеке равно 331;

Голос за кадром: Играйте с 333 и далее.

в третьей библиотеке, смещение (1487501143, uid_aaa) равно 333 (согласно первому условию запроса), поэтому смещение виртуального time_min в третьей библиотеке равно 330;

Голос за кадром: Играйте с 333 и далее.

Таким образом, глобальное смещение time_min равно 333+331+330=994.

Шаг 5: Поскольку получено глобальное смещение time_min, это эквивалентно глобальному представлению.Согласно второму набору результатов, можно получить запись глобального смещения 1000 limit 5.

Набор результатов, возвращаемый вторым запросом в каждой подбазе данных, находится в порядке, и, зная, что глобальное смещение time_min равно 994, легко узнать одностраничную запись глобального смещения 1000 limit 5 (желтая запись в картинку выше).

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

Красавчик не красавчик! ! !

Суммировать

Сегодня мы представляем четыре способа решения сложной проблемы «подкачки по N библиотекам»:

Метод 1: Метод глобального видения

(1) SQL переписать, будет

order by time offset X limit Y;

переписать как

order by time offset 0 limit X+Y;

(2) Сервисный уровень сортирует полученные N*(X+Y) фрагментов данных в памяти, а затем берет Y записей после смещения X после сортировки в памяти;

Производительность этого метода становится все ниже и ниже по мере перелистывания страниц.

Способ 2: Запретить метод запроса перехода на страницу

(1) Используйте обычный метод для получения первой страницы данных и получите time_max записи первой страницы;

(2) Каждый раз, когда страница переворачивается,

order by time offset X limit Y;

переписать как

order by time where time>$time_max limit Y;

Чтобы гарантировать, что за раз возвращается только одна страница данных, производительность является постоянной.

Способ 3: разрешить метод нечетких данных

(1) Переписать запрос SQL, будет

order by time offset X limit Y;

переписать как

order by time offset X/N limit Y/N;

Высокая производительность, но объединенный набор результатов неточен.

Метод 4: метод вторичного запроса

(1) SQL переписать, будет

order by time offset X limit Y;

переписать как

order by time offset X/N limit Y;

(2) многостраничный возврат, найти минимальное time_min;

(3) между вторичным запросом

order by time between timeminandtime_min and time_i_max;

(4) Установите виртуальный time_min, найдите смещение time_min в каждой подбиблиотеке, чтобы получить глобальное смещение time_min;

(5) Получите глобальное смещение time_min и, естественно, получите глобальное смещение X limit Y;

Статья относительно длинная, надеюсь, у каждого есть чему поучиться.

Идеи важнее выводов.

Путь архитектора- Делитесь техническими идеями