SpringBoot2.x + Shardingsphere реализует подставную базу данных и подсуду

Java

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

Анализ концепции

вертикальное разделение

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

file

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

Горизонтальная фрагментация

Также известен как горизонтальное фрагментационное боковое разрешение. Относительно вертикального среза, это больше не классифицирует данные в соответствии с логикой обслуживания, но через поле (или несколько полей), данные в соответствии с определенными правилами или диспергированы в множество таблиц базы данных, каждый фрагмент, содержащий только часть данные. Например: ломтик первичного ключа, первичный ключ в библиотеки 0 (или таблицу), нечетные записи нечетные записи в основной ключ (или таблицу), как показано ниже.

file

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

подготовка к разработке

Обычно используемый компонент для подбазы данных и подтаблицы — это shardingsphere, который уже является проектом верхнего уровня apache.На этот раз мы используем springboot2.1.9 + shardingsphere4.0.0-RC2 (обе последние версии) для завершения операции подбаза данных и подтаблица.

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

  • 172.31.0.129
    • blog
      • t_order_0
      • t_order_1
      • t_order_2
  • 172.31.0.131
    • blog
      • t_order_0
      • t_order_1
      • t_order_2

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

DROP TABLE IF EXISTS `t_order_0;
CREATE TABLE `t_order_0` (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) DEFAULT NULL COMMENT '名称',
  `type` varchar(255) DEFAULT NULL COMMENT '类型',
  `gmt_create` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

Обратите внимание, что правило генерации первичного ключа не должно быть установлено на саморост, и первичный ключ должен быть сгенерирован в соответствии с определенными правилами.Здесь для генерации первичного ключа используется SNOWFLAKE in shardingsphere, широко известный как алгоритм снежинки.

Код

  • Измените pom.xml и добавьте соответствующие компоненты.
<properties>
        <java.version>1.8</java.version>
        <mybatis-plus.version>3.1.1</mybatis-plus.version>
        <sharding-sphere.version>4.0.0-RC2</sharding-sphere.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>${sharding-sphere.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-namespace</artifactId>
            <version>${sharding-sphere.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • настроить mysql-плюс
	@Configuration
	@MapperScan("com.github.jianzh5.blog.mapper")
	public class MybatisPlusConfig {

			/**
			 * 攻击 SQL 阻断解析器
			 */
			@Bean
			public PaginationInterceptor paginationInterceptor(){
					PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
					List<ISqlParser> sqlParserList = new ArrayList<>();
					sqlParserList.add(new BlockAttackSqlParser());

					paginationInterceptor.setSqlParserList(sqlParserList);
					return new PaginationInterceptor();
			}


			/**
			 * SQL执行效率插件
			 */
			@Bean
			// @Profile({"dev","test"})
			public PerformanceInterceptor performanceInterceptor() {
					return new PerformanceInterceptor();
			}
	}
  • Напишите порядок класса сущности
	@Data
	@TableName("t_order")
	public class Order {
			private Long id;

			private String name;

			private String type;

			private Date gmtCreate;

	}
  • Напишите слой DAO, OrderMapper
	/**
	 * 订单Dao层
	 */
	public interface OrderMapper extends BaseMapper<Order> {

	}
  • Написать интерфейс и реализацию интерфейса
	public interface OrderService extends IService<Order> {

	}

	/**
	 * 订单实现层
	 * @author jianzh5
	 * @date 2019/10/15 17:05
	 */
	@Service
	public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

	}
  • Файл конфигурации (см. примечания для инструкций по настройке)
	server.port=8080

	# 配置ds0 和ds1两个数据源
	spring.shardingsphere.datasource.names = ds0,ds1

	#ds0 配置
	spring.shardingsphere.datasource.ds0.type = com.zaxxer.hikari.HikariDataSource
	spring.shardingsphere.datasource.ds0.driver-class-name = com.mysql.cj.jdbc.Driver
	spring.shardingsphere.datasource.ds0.jdbc-url = jdbc:mysql://192.168.249.129:3306/blog?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
	spring.shardingsphere.datasource.ds0.username = root
	spring.shardingsphere.datasource.ds0.password = 000000

	#ds1 配置
	spring.shardingsphere.datasource.ds1.type = com.zaxxer.hikari.HikariDataSource
	spring.shardingsphere.datasource.ds1.driver-class-name = com.mysql.cj.jdbc.Driver
	spring.shardingsphere.datasource.ds1.jdbc-url = jdbc:mysql://192.168.249.131:3306/blog?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
	spring.shardingsphere.datasource.ds1.username = root
	spring.shardingsphere.datasource.ds1.password = 000000

	# 分库策略 根据id取模确定数据进哪个数据库
	spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column = id
	spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression = ds$->{id % 2}

	# 具体分表策略
	# 节点 ds0.t_order_0,ds0.t_order_1,ds1.t_order_0,ds1.t_order_1
	spring.shardingsphere.sharding.tables.t_order.actual-data-nodes = ds$->{0..1}.t_order_$->{0..2}
	# 分表字段id
	spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column = id
	# 分表策略 根据id取模,确定数据最终落在那个表中
	spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$->{id % 3}


	# 使用SNOWFLAKE算法生成主键
	spring.shardingsphere.sharding.tables.t_order.key-generator.column = id
	spring.shardingsphere.sharding.tables.t_order.key-generator.type = SNOWFLAKE

	#spring.shardingsphere.sharding.binding-tables=t_order

	spring.shardingsphere.props.sql.show = true
  • Напишите модульные тесты, чтобы проверить, верны ли результаты.
	public class OrderServiceImplTest extends BlogApplicationTests {
		@Autowired
		private OrderService orderService;


		@Test
		public void testSave(){
			for (int i = 0 ; i< 100 ; i++){
				Order order = new Order();
				order.setName("电脑"+i);
				order.setType("办公");
				orderService.save(order);
			}
		}

		@Test
		public void testGetById(){
			long id = 1184489163202789377L;
			Order order  = orderService.getById(id);
			System.out.println(order.toString());
		}
	}
  • Просмотрите данные в таблице данных и убедитесь, что данные вставлены нормально

    file

  • На данный момент разработка подбазы данных и подтаблицы завершена.

прошлый обзор

SpringBoot+Mysql8 реализует разделение чтения и записи

Для получения дополнительной информации, пожалуйста, обратите внимание на публичный номер: JAVA Daily Record

微信公众号