当前位置:   article > 正文

SpringBoot + ShardingSphere实现读写分离,分库分表_shardingsphere 分库分表和读写分离的配置

shardingsphere 分库分表和读写分离的配置

分布式项目在通过一定的服务拆分,项目运行一段时间以后,随着用户和使用资源的不断增大,数据库的性能也会面临瓶颈。单表数据量过大,超高并发的读写引发的锁问题,导致系统运行加载越来越慢,不时出现系统假死的现象,数据库的优化已将近极限,几乎没有空间,这时就需要考虑读写分离,分库分表(这里主要是水平的分库分表)的策略,来减少对同一数据库的访问的压力。

一.操作的工程目录

二.读写分离

application.yml

  1. spring:
  2. shardingsphere:
  3. datasource:
  4. names: master,slave
  5. #数据源配置
  6. master:
  7. driver-class-name: com.mysql.jdbc.Driver
  8. type: com.alibaba.druid.pool.DruidDataSource
  9. url: jdbc:mysql://localhost:3306/master0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
  10. username: root
  11. password: 123456
  12. slave:
  13. driver-class-name: com.mysql.jdbc.Driver
  14. type: com.alibaba.druid.pool.DruidDataSource
  15. url: jdbc:mysql://localhost:3306/slave0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
  16. username: root
  17. password: 123456
  18. #读写分离配置(主库写,从库读)
  19. masterslave:
  20. load-balance-algorithm-type: round_robin
  21. name: ms
  22. #写库
  23. master-data-source-name: master
  24. #读库
  25. slave-data-source-names: slave
  26. props:
  27. sql:
  28. show: true
  29. main:
  30. allow-bean-definition-overriding: true

2.1 代码生成的测试

  1. package com.aliyun.readWrite.test.controller;
  2. import com.aliyun.readWrite.test.entity.VideoRoom;
  3. import com.aliyun.readWrite.test.service.IVideoRoomService;
  4. import com.aliyun.util.Result;
  5. import com.aliyun.util.StatusCode;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.web.bind.annotation.*;
  9. /**
  10. * <p>
  11. * 房间表 前端控制器
  12. * </p>
  13. *
  14. * @author haige
  15. * @since 2021-11-24
  16. */
  17. @Slf4j
  18. @RestController
  19. @RequestMapping("/videoRoom")
  20. public class VideoRoomController {
  21. @Autowired
  22. public IVideoRoomService videoRoomService;
  23. @PostMapping("/save")
  24. public Result save(@RequestBody VideoRoom videoRoom){
  25. videoRoomService.save(videoRoom);
  26. return new Result(StatusCode.SUCCESS,"保存成功");
  27. }
  28. @GetMapping("/get/{id}")
  29. public Result get(@PathVariable("id") String id){
  30. VideoRoom videoRoom = videoRoomService.getById(id);
  31. return new Result(StatusCode.SUCCESS,"查询成功",videoRoom);
  32. }
  33. }

实现了接口调用时master库写,slave库读的效果

三.分库分表

application.yml

  1. spring:
  2. shardingsphere:
  3. props:
  4. sql:
  5. show: true
  6. main:
  7. allow-bean-definition-overriding: true
  8. datasource:
  9. names: master0,master1
  10. #数据源配置
  11. master0:
  12. driver-class-name: com.mysql.jdbc.Driver
  13. type: com.alibaba.druid.pool.DruidDataSource
  14. url: jdbc:mysql://localhost:3306/master0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
  15. username: root
  16. password: 123456
  17. master1:
  18. driver-class-name: com.mysql.jdbc.Driver
  19. type: com.alibaba.druid.pool.DruidDataSource
  20. url: jdbc:mysql://localhost:3306/master1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
  21. username: root
  22. password: 123456
  23. #分库分表配置
  24. sharding:
  25. #分库
  26. default-database-strategy:
  27. inline:
  28. sharding-column: age
  29. algorithm-expression: master$->{age % 2} #根据年龄分库
  30. #分表
  31. tables:
  32. tab_user:
  33. actual-data-nodes: master$->{0..1}.tab_user$->{0..1}
  34. table-strategy:
  35. inline:
  36. sharding-column: id
  37. algorithm-expression: tab_user$->{id % 2}

3.1 分库分表数据源及策略配置的注入类

  1. package com.aliyun.config;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
  4. import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
  5. import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
  6. import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
  7. import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
  8. import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
  9. import org.mybatis.spring.SqlSessionFactoryBean;
  10. import org.mybatis.spring.annotation.MapperScan;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.context.annotation.ComponentScan;
  13. import org.springframework.context.annotation.Configuration;
  14. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  15. import javax.sql.DataSource;
  16. import java.sql.SQLException;
  17. import java.util.HashMap;
  18. import java.util.Map;
  19. import java.util.Properties;
  20. @Configuration
  21. @ComponentScan(basePackageClasses = DataSourceConfig.class)
  22. @MapperScan(basePackages = "com.aliyun.shard.mapper")
  23. public class DataSourceConfig {
  24. /**
  25. * SqlSessionFactory注入
  26. */
  27. @Bean
  28. public SqlSessionFactory sqlSessionFactory() throws Exception {
  29. PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  30. SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
  31. sessionFactory.setDataSource(dataSource());
  32. sessionFactory.setFailFast(true);
  33. sessionFactory.setMapperLocations(resolver.getResources("classpath:/mapper/system/*Mapper.xml"));
  34. return sessionFactory.getObject();
  35. }
  36. @Bean
  37. public DataSource dataSource() throws SQLException {
  38. ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
  39. shardingRuleConfig.getTableRuleConfigs().add(getOrderTableRuleConfiguration());
  40. shardingRuleConfig.getBindingTableGroups().add("tab_user");
  41. // shardingRuleConfig.getBroadcastTables().add("t_config");
  42. //TODO 根据年龄分库 一共分为2个库
  43. shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("age", "master${age % 2}"));
  44. //TODO 根据ID分表 一共分为2张表
  45. shardingRuleConfig.setDefaultTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("id", new PreciseModuloShardingTableAlgorithm()));
  46. return ShardingDataSourceFactory.createDataSource(createDataSourceMap(), shardingRuleConfig, new Properties());
  47. }
  48. private static KeyGeneratorConfiguration getKeyGeneratorConfiguration() {
  49. KeyGeneratorConfiguration result = new KeyGeneratorConfiguration("SNOWFLAKE", "id");
  50. return result;
  51. }
  52. TableRuleConfiguration getOrderTableRuleConfiguration() {
  53. TableRuleConfiguration result = new TableRuleConfiguration("tab_user", "master${0..1}.tab_user${0..1}");
  54. result.setKeyGeneratorConfig(getKeyGeneratorConfiguration());
  55. return result;
  56. }
  57. Map<String, DataSource> createDataSourceMap() {
  58. Map<String, DataSource> result = new HashMap<>();
  59. result.put("master0", DataSourceUtil.createDataSource("master0"));
  60. result.put("master1", DataSourceUtil.createDataSource("master1"));
  61. return result;
  62. }
  63. }
  1. package com.aliyun.config;
  2. import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
  3. import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
  4. import java.util.Collection;
  5. /**
  6. * 表分片规则
  7. */
  8. public final class PreciseModuloShardingTableAlgorithm implements PreciseShardingAlgorithm<Long> {
  9. @Override
  10. public String doSharding(final Collection<String> tableNames, final PreciseShardingValue<Long> shardingValue) {
  11. for (String each : tableNames) {
  12. if (each.endsWith(shardingValue.getValue() % 2 + "")) {
  13. return each;
  14. }
  15. }
  16. throw new UnsupportedOperationException();
  17. }
  18. }
  1. package com.aliyun.config;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import javax.sql.DataSource;
  4. /**
  5. * @Description: 数据源配置
  6. *
  7. * @author xub
  8. * @date 2019/10/16 下午7:47
  9. */
  10. public final class DataSourceUtil {
  11. private static final String HOST = "localhost";
  12. private static final int PORT = 3306;
  13. private static final String USER_NAME = "root";
  14. private static final String PASSWORD = "123456";
  15. public static DataSource createDataSource(final String dataSourceName) {
  16. DruidDataSource result = new DruidDataSource();
  17. result.setDriverClassName(com.mysql.jdbc.Driver.class.getName());
  18. result.setUrl(String.format("jdbc:mysql://%s:%s/%s?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8", HOST, PORT, dataSourceName));
  19. result.setUsername(USER_NAME);
  20. result.setPassword(PASSWORD);
  21. return result;
  22. }
  23. }

3.2 代码生成的测试

  1. package com.aliyun.shard.controller;
  2. import com.aliyun.shard.entity.TabUser;
  3. import com.aliyun.shard.service.ITabUserService;
  4. import com.aliyun.util.Result;
  5. import com.aliyun.util.StatusCode;
  6. import com.google.common.collect.Lists;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.web.bind.annotation.*;
  10. import org.springframework.web.bind.annotation.RestController;
  11. import javax.annotation.PostConstruct;
  12. import java.util.List;
  13. /**
  14. * <p>
  15. * 前端控制器
  16. * </p>
  17. *
  18. * @author haige
  19. * @since 2021-11-26
  20. */
  21. @Slf4j
  22. @RestController
  23. @RequestMapping("/tabUser")
  24. public class TabUserController {
  25. @Autowired
  26. public ITabUserService tabUserService;
  27. /**
  28. * 模拟插入数据
  29. */
  30. List<TabUser> userList = Lists.newArrayList();
  31. /**
  32. * 初始化插入数据
  33. */
  34. @PostConstruct
  35. private void getData() {
  36. userList.add(new TabUser(1L,"小小", "女", 3));
  37. userList.add(new TabUser(2L,"爸爸", "男", 30));
  38. userList.add(new TabUser(3L,"妈妈", "女", 28));
  39. userList.add(new TabUser(4L,"爷爷", "男", 64));
  40. userList.add(new TabUser(5L,"奶奶", "女", 62));
  41. }
  42. @PostMapping("batchSaveUser")
  43. public Result batchSaveUser() {
  44. return new Result(StatusCode.SUCCESS,tabUserService.insertForEach(userList));
  45. }
  46. @GetMapping("/findAll")
  47. public Result findAll(){
  48. List<TabUser> tabUserList = tabUserService.findAll();
  49. return new Result(StatusCode.SUCCESS,"查询成功",tabUserList);
  50. }
  51. }

实现了5条数据分别添加到了tab_user0,tab_user1,tab_user2三张表,在查询findAll数据时又能返回三张表的所有数据。

四.工程源码

感兴趣的猿友可以了解--> 下载源码

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/757160
推荐阅读
相关标签
  

闽ICP备14008679号