Учебная комната Cabbage Java охватывает основные знания
Сложность в подбазе данных и подтаблице (1) Пейджинг по таблице/кросс-базе сложно воспроизвести, но это не значит, что нет возможности воспроизвести
Проблема подбазы данных и подтаблицы (2) Соединение между базами данных и экземплярами не должно полагаться на промежуточное программное обеспечение.
1. Горизонтальная сегментация данных
Многим интернет-компаниям необходимо извлекать данные путем подкачки, например:
- На операционной стороне системы торгового центра электронной коммерции потяните список заказов, чтобы просмотреть его постранично;
- Просматривайте сообщения в системе сообщества Tieba и извлекайте ответы на сообщения, просматривая страницы;
- Нажмите красную точку в правом верхнем углу мобильного приложения, нажмите, чтобы открыть список сообщений;
Если эти бизнес-сценарии реализуются с помощью баз данных, они часто имеют следующие общие черты:
- Объем данных часто относительно велик;
- Как правило, создается идентификатор первичного ключа бизнеса;
- Страничная сортировка сортируется не по первичному ключу, а по времени создания;
Когда объем данных невелик, вы можете построить индекс по времени поля сортировки и использовать функцию смещения/ограничения, предоставляемую SQL, для удовлетворения требований запроса на подкачку:
SELECT * FROM `table` ORDER BY `time` LIMIT #{offset}, #{limit}
Требования к подбиблиотеке и подтаблице
Когда бизнес-данные достигают определенного уровня (например:В одной таблице MySql записано более 10 миллионов), «сегментация базы данных и таблицы» обычно считается для распределения данных по разным базам данных или таблицам (горизонтальная сегментация данных), что может значительно повысить производительность чтения/записи.
В архитектуре Интернета с высоким параллелизмом и большим трафиком доступ к базе данных обычно осуществляется через сервисный уровень.По мере увеличения объема данных базу данных необходимо разделить по горизонтали.После разделения базы данных данные распределяются по разным экземплярам базы данных. (даже физические машины), чтобы достичь цели уменьшения объема данных и увеличения количества экземпляров. Когда задействована подбиблиотека, выхода нет».«Ключ раздела» (ключ раздела)понятие, какое поле использовать для разделения базы данных по горизонтали: в большинстве бизнес-сценариев будет использоваться идентификатор первичного ключа бизнеса.
После определения ключа раздела следует определить алгоритм сегментирования: в большинстве бизнес-сценариев будет использоватьсяАлгоритм получения по модулю идентификатора первичного ключа бизнесав подбиблиотеку, поэтомуОн может не только обеспечить единообразие распределения данных каждой библиотеки, но и обеспечить единообразие распределения запросов каждой библиотеки., действительно хороший способ просто реализовать балансировку нагрузки, и этот метод широко используется в архитектуре Интернета.
Но вот возникает вопрос, дляSELECT * FROM table ORDER BY time LIMIT #{offset}, #{limit}
С этим методом подкачки вещи, которые можно просто сделать с помощью одного оператора, станут очень сложными.В этой статье мы обсудим с вами новые проблемы, с которыми сталкивается "подкачка" после подбазы данных и подтаблицы.
Уведомление: В этой статье в основном обсуждаются проблемы, с которыми сталкивается "пейджинг" (Сценарий горизонтального среза данных), это всего лишь пример простейшего алгоритма подтаблицы подбазы данных.Реальная производственная среда будет намного сложнее, и решение подтаблицы подбазы данных необходимо определять в соответствии с конкретными потребностями бизнеса.
2. Метод глобального видения
Как показано на рисунке, после того, как сервисный слой распределяет данные двум базам данных по Modulo Modulo, каждая база данных теряет свой глобальный вид. После того, как данные частично отсортированы по времени, независимо от того, какая подзабанда находится на третьей странице, это не обязательно то же самое. Является ли 3-й страничные данные глобального сортировки.
database1 (id%2=0) | database2 (id%2=1) |
---|---|
db0-page1 | db1-page1 |
db0-page2 | db1-page2 |
db0-page3 | db1-page3 |
... (order by time) | ... (order by time) |
(1) В крайних случаях данные двух библиотек точно совпадают
Если данные двух библиотек абсолютно одинаковы, требуется только половина смещения каждой библиотеки, а затем извлекается половина страницы, что является окончательными желаемыми данными (как показано на рисунке):
database1 (id%2=0) | database2 (id%2=1) |
---|---|
db0-page1 | db1-page1 |
db0-page2 | db1-page2 |
db0-page3 (взять половину) | db1-страница3 (взять половину) |
... (order by time) | ... (order by time) |
(2) В крайних случаях все данные результатов поступают из одной и той же библиотеки.
Также возможно, что распределение данных двух библиотек несбалансировано.Например, время всех данных в db0 больше, чем время всех данных в db1.Может показаться, что данные на третьей странице библиотеки данные на третьей странице после глобальной сортировки (как показано на рисунке):
database1 (id%2=0) | database2 (id%2=1) |
---|---|
db0-page1 | db1-page1 |
db0-page2 | db1-page2 |
db0-page3 (та же библиотека) | db1-page3 |
... (order by time) | ... (order by time) |
(3) Как правило, данные каждой базы данных содержат часть
При нормальных обстоятельствах третья страница данных глобального порядка, каждая библиотека будет содержать часть (как показано):
database1 (id%2=0) | database2 (id%2=1) |
---|---|
db0-page1 | db1-page1 |
db0-page2 (содержит часть) | db1-page2 |
db0-page3 | db1-страница3 (содержит часть) |
... (order by time) | ... (order by time) |
Поскольку не ясно, это,Каждая библиотека должна возвращать 3 страницы данных, а полученные 6 страниц данных сортируются в памяти на сервисном уровне., получить глобальное представление данных, а затем взять данные третьей страницы, вы можете получить желаемые глобальные данные пейджинга.
Подытожим этапы этой схемы:
- Буду
order by time offset X limit Y
, переписанный какorder by time offset 0 limit X+Y
;- Уровень службы отправляет переписанный оператор SQL в каждую подбазу данных: то есть в примере каждая из них извлекает 3 страницы данных;
- Предполагая, что он разделен на N библиотек, сервисный уровень получит N*(X+Y) фрагментов данных: в примере 6 страниц данных;
- Сервисный уровень сортирует полученные N*(X+Y) фрагментов данных в памяти, а затем берет Y записей после смещения X после сортировки памяти, которая является страницей данных, необходимой для глобального представления.
Преимущества программы:
- Изменяя оператор SQL на уровне службы и увеличивая объем отзыва данных, можно получить глобальное представление, бизнес без потерь и требуемые данные могут быть возвращены точно.
Недостатки схемы (очевидные):
- Каждая подбаза данных должна возвращать больше данных, что увеличивает объем сетевой передачи (потребление сети);
- В дополнение к сортировке базы данных по времени сервисный уровень также необходимо сортировать дважды, что увеличивает объем вычислений (потребление ЦП) сервисного уровня;
- Самое фатальное, что производительность этого алгоритма будет резко падать с увеличением номера страницы, потому что каждая подбаза данных должна возвращать X+Y строк данных после перезаписи SQL: возврат на страницу 3, X=200 по смещению ; Вернитесь на страницу 100, X=9900 по смещению, то есть каждая подбаза данных будет возвращать 100 страниц данных, объем данных и объем сортировки значительно увеличатся, а производительность снизится прямоугольно.
3. Компрометация бизнеса
Несмотря на то, что "метод глобального просмотра" имеет низкую производительность, его бизнес работает без потерь, а данные точны. Это решение. Есть ли решение с большей производительностью? "Любой архитектурный проект, отделенный от бизнеса, - это хулиган. Техническое решение должно быть скомпрометировано. В случае технических трудностей компромисс с требованиями бизнеса может значительно упростить техническое решение".
(1) Компрометация бизнеса 1: Запрет запроса перехода на страницу
Когда объем данных велик, а количество просматриваемых страниц велико, многие продукты не предоставляют функцию «перехода непосредственно на указанную страницу», а предоставляют только функцию «следующая страница». чрезвычайно Значительно снижает сложность технических решений.
Как показано на рисунке, переход по страницам не допускается, тогда в первый раз можно проверить только первую страницу:
- будет запрашивать
order by time offset 0 limit 100
, переписанный какorder by time where time > 0 limit 100
;- Вышеупомянутое переписать и
offset 0 limit 100
Эффект тот же, каждая подбаза данных возвращает страницу данных (как показано на рисунке);- Служба обслуживания получает 2 страницы данных, сортирует память и вынимает первые 100 штук данных в качестве окончательной первой страницы данных. Эта глобальная первая страница данных, в целом, в целом, каждая субъекта содержит часть данных (как показано на рисунке);
database1 (id%2=0) | database2 (id%2=1) |
---|---|
DB0-Page1 (Первая страница) | db1-страница1 (Первая страница) |
db0-page2 | db1-page2 |
db0-page3 | db1-page3 |
... (order by time) | ... (order by time) |
сомневаться:Это решение также требует сортировки памяти сервера, разве это не то же самое, что и «метод глобального просмотра»?? Извлечение первой страницы данных действительно одинаково, но план извлечения «следующей страницы» каждый раз разный.
Когда вы нажимаете «Следующая страница», вам нужно вытащить вторую страницу данных.На основе первой страницы данных вы можете найти максимальное значение времени первой страницы данных:
database1 (id%2=0) | database2 (id%2=1) |
---|---|
db0-page1 (максимальное время) | db1-page1 |
db0-page2 | db1-страница2 (максимальное время) |
db0-page3 | db1-page3 |
... (order by time) | ... (order by time) |
Значение time_max, записанное на предыдущей странице, будет использоваться в качестве условия запроса для извлечения данных на второй странице:
- будет запрашивать
order by time offset 100 limit 100
, переписанный какorder by time where time > > $time_max limit 100
;- Вместо того, чтобы на этот раз возвращать 2 страницы данных («Метод глобального представления будет переписан как
offset 0 limit 200
»), каждая подбаза данных по-прежнему возвращает страницу данных (как показано на рисунке);- Сервисный уровень получает 2 страницы данных, сортирует их в памяти и извлекает первые 100 фрагментов данных в качестве конечных данных страницы 2. Эти глобальные данные страницы 2, вообще говоря, каждая подбаза данных содержит часть данных ( как показано на рисунке);
- Таким образом, при запросе данных на странице 100 глобального представления вместо перезаписи условий запроса как
offset 0 limit 9900+100
(возвращает 100 страниц данных), но переписывается какtime > $time_max99 limit 100
(Каждая подбаза данных по-прежнему возвращает страницу данных), чтобы объем передаваемых и сортируемых данных не снижал производительность, поскольку страницы постоянно перелистываются.
(2) Компрометация бизнеса 2: допущение потери точности данных
"Метод глобального просмотра" может возвращать точные данные без потери бизнеса. При запросе большого количества страниц, например 100-й страницы, будут проблемы с производительностью. В настоящее время, приемлемо ли это для бизнеса, возвращаемые 100 страницы не являются точными данными, но позволяют. Есть ли некоторая предвзятость данных?
Подбаза данных базы данных - принцип баланса данных
При использовании ключа патриции для подбазы данных, когда объем данных велик и распределение данных достаточно случайное, распределение данных и статистическая вероятность всех атрибутов ключа, не относящегося к патриции, в каждой подбазе данных в каждой подбазе данных согласованы.
Например, в случае случайного uid используйте uid по модулю для разделения на две библиотеки, db0 и db1:
- Атрибут пола: если доля пользователей мужского пола в базе данных db0 составляет 70 %, доля пользователей мужского пола в базе данных db1 также должна составлять 70 %;
- Возрастной признак, если доля 18-28-летних девушек по базе db0 составляет 15%, то доля девушек по db1 тоже должна быть 15%;
- Атрибут времени, если доля пользователей, которые входят в систему до 10:00 каждый день в базе данных db0, составляет 20%, то такой же статистический закон должен быть и в базе данных db1;
database1 (id%2=0) | database2 (id%2=1) |
---|---|
db0-page1 | db1-page1 |
db0-page2 | db1-page2 |
db0-page3 (взять половину) | db1-страница3 (взять половину) |
... (order by time) | ... (order by time) |
Используя этот принцип, чтобы запросить глобальные 100 страниц данных,
offset 9900 limit 100
переписать какoffset 4950 limit 50
, каждая подбаза данных смещается на 4950 (половина) и получается 50 фрагментов данных (полстраницы).Объединение полученных наборов данных в принципе можно рассматривать как глобальные данные.offset 9900 limit 100
Данные,Конечно, точность данных на этой странице не соответствует действительности..
Согласно реальному бизнес-опыту, пользователям приходится запрашивать данные 100-й страницы веб-страниц, сообщений и электронных писем.Потеря точности данных на этой странице часто приемлема в бизнесе, но сложность технического решения значительно в настоящее время уменьшено. , не нужно ни возвращать больше данных, ни обслуживать сортировку памяти.
4. Дополнительный метод запроса (рекомендуется)
Существует ли техническое решение, которое может удовлетворить конкретные потребности бизнеса без ущерба для бизнеса и высокопроизводительный метод? Это окончательное оружие, которое будет представлено позже: «второй метод запроса».
Для удобства примера, предполагая, что на странице всего 5 элементов данных, оператор SQL для запроса страницы 200 выглядит так:select * from T order by time offset 1000 limit 5
;
Шаг 1. Запросите переписывание SQL
Буду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
, чтобы быть более интуитивным, мы следуем примеру 3 подбиблиотек для демонстрации, а время представлено простым 8-значным числом (как показано на рисунке):
database1 (id%3=0) | database2 (id%3=1) | database3 (id%3=2) |
---|---|---|
10000123 | 10000133 | 10000143 |
10000223 | 10000233 | 10000243 |
10000323 | 10000333 | 10000343 |
10000423 | 10000433 | 10000443 |
10000523 | 10000533 | 10000543 |
Как видите, в каждой подбиблиотеке возвращаются своего рода временные данные.
Шаг 2: Найдите минимальное значение, которое возвращает все данные на 3 страницах.
- Для первой библиотеки минимальное время для 5 частей данных составляет 10000123;
- Для второй библиотеки минимальное время для 5 частей данных составляет 10000133;
- Третья библиотека, минимальное время 5 частей данных 10000143;
database1 (id%3=0) | database2 (id%3=1) | database3 (id%3=2) |
---|---|---|
10000123 (минимум) | 10000133 | 10000143 |
10000223 | 10000233 | 10000243 |
10000323 | 10000333 | 10000343 |
10000423 | 10000433 | 10000443 |
10000523 | 10000533 | 10000543 |
На этих трех страницах данных минимальное значение времени исходит из первой библиотеки,time_min = 10000123
, в этом процессе нужно только сравнить первые данные каждой подбазы данных, и временная сложность очень мала.
Шаг 3. Запросите переписывание SQL
Первый переписанный оператор SQL:select * from T order by time offset 333 limit 5
;
Во второй раз его необходимо переписать в оператор между, начальная точка между — это time_min, а конечная точка между — это минимальное значение исходных данных, возвращаемых каждой подбазой данных (между относится к >= и
- Первая подбаза данных, time_min, расположена в первой подбазе данных, поэтому нет необходимости запрашивать ее напрямую.
- Вторая подбиблиотека, переписанная как
select * from T order by time where time between time_min and 10000133
; - Третья подбиблиотека, переписанная как
select * from T order by time where time between time_min and 10000143
;
Для второго запроса предположим, что данные, возвращаемые этими тремя подбазами данных, выглядят следующим образом (конечно, нам нужно запросить только 2 базы данных):
database1 (id%3=0) | database2 (id%3=1) | database3 (id%3=2) |
---|---|---|
- | - | 10000141 |
- | 10000132 | 10000142 |
10000123 | 10000133 | 10000143 |
Шаг 4. Анализ результатов вторичного запроса
Мы сохраняем временной порядок неизменным и объединяем наборы результатов вторичного запроса, чтобы получить последний набор результатов (как показано на рисунке):
database1 (id%3=0) | database2 (id%3=1) | database3 (id%3=2) |
---|---|---|
- | - | 10000141 (второй раз) |
- | 10000132 (второй раз) | 10000142 (второй раз) |
10000123 | 10000133 | 10000143 |
10000223 | 10000233 | 10000243 |
10000323 | 10000333 | 10000343 |
10000423 | 10000433 | 10000443 |
10000523 | 10000533 | 10000543 |
Теперь давайте проведем простое умственное рассуждение:
- Нашим первоначальным требованием было
select * from T order by time offset 1000 limit 5
;- Затем из-за подбиблиотеки мы разделили три подбиблиотеки
select * from T order by time offset 333 limit 5
;- В этот момент мы получаем минимальное значение time_min, поэтому мы можем сначала предположить, что в этих трех подбазах данных имеется 333 * 3 = 999 результатов, которые меньше, чем time_min (смещение первого результата оператора SQL равно 0, а смещение = 333 на самом деле является первым результатом оператора SQL. 334 результата), поэтому скажем, смещение = 999 для time_min;
- Не выполняя второй запрос, мы не можем получить результаты для офсет = 1000 ~ 1004, потому что я не могу сказать, есть ли другие результаты между time_min (10000123) и (10000133), time_min (10000123) и (10000143), а также Не может получить глобальный вид;
- Выполните второй запрос, вторую подбазу данных, перепишите как
select * from T order by time where time between time_min and 10000133
, третья подбиблиотека, переписанная какselect * from T order by time where time between time_min and 10000143
, чтобы получить глобальное представление, мы можем сортировать и маркировать в памяти;- Перед вторым запросом предполагается, что есть 999 результатов, меньших, чем time_min.Поскольку второй запрос дает результаты, три результата (10000132, 10000141, 10000142) учитываются в наших предполагаемых 999, то есть эти три результата должны быть сместиться назад, в это время, смещение time_min = 996 = 999 - 3;
Шаг 5: Маркировка результатов глобального просмотра
Получение глобального смещения time_min эквивалентно глобальному видению.По сумме двух наборов результатов можно получить глобальное.offset 1000 limit 5
запись о.
database1 (id%3=0) | database2 (id%3=1) | database3 (id%3=2) |
---|---|---|
- | - | 10000141 (смещение=999) |
- | 10000132 (смещение=997) | 10000142 (смещение=1000) |
10000123 (смещение=996) | 10000133 (смещение=998) | 10000143 (смещение=1001) |
10000223 (смещение=1002) | 10000233 (смещение=1003) | 10000243 (смещение=1004) |
10000323 (смещение=...) | 10000333 | 10000343 |
10000423 | 10000433 | 10000443 |
10000523 | 10000533 | 10000543 |
Преимущества программы:
- Он может точно возвращать данные, необходимые для бизнеса, и объем данных, возвращаемых каждый раз, очень мал, и объем возвращаемых данных не будет увеличиваться при перелистывании страниц.
Недостатки схемы:
- Требуются два запроса к базе данных, которые потребляют определенный объем базы данных, но потребляют меньше ресурсов сети и ЦП, чем метод глобального представления.
Сложность в подбазе данных и подтаблице (1) Пейджинг по таблице/кросс-базе сложно воспроизвести, но это не значит, что нет возможности воспроизвести
Проблема подбазы данных и подтаблицы (2) Соединение между базами данных и экземплярами не должно полагаться на промежуточное программное обеспечение.