обзор сюжета
Ранее мы узнали о разделении чтения-записи, вертикальном разделении, вертикальном разделении + разделении чтения-записи. Соответствующие статьи таковы:
Sharding-JDBC: как оптимизировать объем запросов?
Sharding-JDBC: как сделать вертикальное разделение?
Благодаря приведенной выше оптимизации большинство потребностей было удовлетворено. Есть только одна ситуация, когда нам нужно снова оптимизировать, то есть количество одиночных таблиц резко возросло, превысив 10 миллионов и более.В это время таблицы должны быть разбиты по горизонтали.
Что такое горизонтальное разделение таблицы?
Это значит разделить стол на N столов, как большой камень, который нельзя сдвинуть, а затем разрезать на 10 частей, чтобы его можно было сдвинуть. Принцип тот же.
Помимо того, что он может разделить давление количества, он также может распределить давление запросов на чтение и запись. Конечно, это зависит от вашего алгоритма сегментирования. Разумный алгоритм может равномерно распределять данные и повышать производительность.
Сегодня мы в основном говорим о разбиении таблиц в единой базе данных, то есть не о разделении базы данных, а только о разделении таблицы.
Работа как с подбазой данных, так и с подтаблицей будет обсуждаться позже.Давайте сделаем снимок, чтобы увидеть неподтаблицу:
Затем сделайте еще один снимок, чтобы почувствовать разделенную таблицу:
Из приведенного выше рисунка видно, что пользовательская таблица разделена на 4 от исходной, и данные будут равномерно распределены в этих 3-х таблицах, то есть исходный пользователь=user0+user1+user2+user3.
Конфигурация подтаблицы
Сначала нам нужно создать 4 пользовательские таблицы следующим образом:
CREATE TABLE `user_0`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_1`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_2`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_3`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Количество подтаблиц, которые вам необходимо оценить, исходя из объема ваших данных и роста в ближайшие несколько лет.
Конфигурация правила подтаблицы:
spring.shardingsphere.datasource.names=master
# 数据源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=master.user_${0..3}
# inline 表达式
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
- фактические узлы данных Для настройки информации подтаблицы используемые здесь встроенные выражения переводятся как master.user_0, master.user_1, master.user_2, master.user_3.
- inline.sharding-столбец Поля подтаблицы, здесь используйте подтаблицу id
- inline.алгоритм-выражение Выражение строки алгоритма разбиения таблицы должно соответствовать синтаксису groovy.Вышеуказанная конфигурация предназначена для использования идентификатора для разбиения по модулю.
Если у нас есть более сложные требования к фрагментации, мы можем настроить алгоритм фрагментации для достижения:
# 自定义分表算法
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.cxytiandi.sharding.algorithm.MyPreciseShardingAlgorithm
Класс алгоритма:
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
return tableName;
}
}
throw new IllegalArgumentException();
}
}
В методе doSharding можно выполнить некоторую обработку по параметру shardingValue и, наконец, вернуть имя таблицы, для которой эти данные необходимо сегментировать.
Помимо сегментирования полей в один столбец, также поддерживается шардирование в несколько полей, вы можете зайти в документ и управлять им самостоятельно.
Те, которые нужно разбивать на таблицы, настраивать не нужно, а те, что не нужно разбивать на таблицы, не нужно настраивать, и одну строчку кода работы БД менять не нужно.
Если мы хотим разделить чтение и запись на основе одиночной базы данных и подтаблиц, это также очень просто, нам нужно только настроить еще один подчиненный источник данных, конфигурация следующая:
spring.shardingsphere.datasource.names=master,slave
# 主数据源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 从数据源
spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
spring.shardingsphere.datasource.slave.username=root
spring.shardingsphere.datasource.slave.password=123456
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user_${0..3}
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
# 读写分离配置
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=slave
Наконец
Вы обнаружите, что, в конце концов, очень просто решить этот сложный сценарий разделения таблицы с помощью фреймворка. По крайней мере, это намного лучше, чем таблица, которую вы используете для расчета маршрута по полям, для суммирования и запроса этой формы.
Ссылка на исходный код:GitHub.com/Йинджи Хуан/Да…
Если вы считаете, что это хорошо, не забудьте обратить внимание и поставить звезду!