ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

分布式事务-03-单体应用分库多数据源改造

2022-01-15 22:34:22  阅读:160  来源: 互联网

标签:03 分库 String 数据源 数据库 Value private datasource activity


需要多库的原因

什么情况下需要多库呢?数据库不够用的时候。

如果应用的用户不断增长,数据量也不断增长,单一数据库的数据量较大(问题来了,多少算较大?),数据库查询成了瓶颈的时候,那么就需要分库分表。

数据量推测

假设是流量充值应用场景。

假设100万注册用户

访问量:一天3万次流量充值

调用接口最少数量:

  1. 进入流量充值界面
  2. 显示流量充值的金额
  3. 完成支付

可以假设,每天调用的次数最少为:3万次 * 3 = 9万次接口的调用,认为一天大约10万次接口调用。

高峰时期调用数量

高峰时间段:中午2小时,晚上2小时,假设一天高峰是4小时。

高峰承载量:假设承载80%的请求数量,即10万 * 80% = 8万次。

高峰每秒请求次数:每小时2万次调用,2万 / 3600 = 5.5,大约5/s。

高峰数据库写入量:以订单数计算,一天3万条,一个月150万数据,一年就是2000万订单数据

假设1000万注册用户

假设就是100万用户放大十倍,那么每年至少2亿订单数据。

当用户量更大的时候,数据量更大,数据库访问不是瓶颈,但是数据库的空间大小成为瓶颈。

数据拆分

一般而言,是按照数据量分库分表,把数据量均匀分布到多个数据库中。
但刚开始就以最简单的按业务来拆分库。

资金、流量券、促销、积分、流量套餐、抽奖、充值订单,分别使用独立的数据库服务器,各个表的数据放在自己的服务器上,使用自己的磁盘空间,这样可以初步的先延长一下我们数据库的使用的周期。

单体应用多数据源改造

  1. 根据业务先建立多个库,再把每个业务对应的表移过去
  2. 设置多个数据源
  3. 把mapper分到各个package里
  4. 在application.yml中,配置相应的参数,便于@Value("${activity.datasource.url}") 获取到参数
  5. 配置mapperscan
  6. @Bean(name = "activityTransactionManager")
  7. @Primary 这个注解只要一个bean写,不写或者在多个配置bean里写都不行

改完测试功能是否完整

@Configuration  
@MapperScan(basePackages = "com.zhss.data.refill.center.mapper.activity", 
			sqlSessionFactoryRef = "activitySqlSessionFactory")
public class ActivityDataSourceConfig {  
   
    @Value("${activity.datasource.url}")  
    private String dbUrl;  
    @Value("${activity.datasource.username}")  
    private String username;  
    @Value("${activity.datasource.password}")  
    private String password;  
    @Value("${activity.datasource.driverClassName}")  
    private String driverClassName;  
    @Value("${activity.datasource.initialSize}")  
    private int initialSize;  
    @Value("${activity.datasource.minIdle}")  
    private int minIdle;  
    @Value("${activity.datasource.maxActive}")  
    private int maxActive;  
    @Value("${activity.datasource.maxWait}")  
    private int maxWait;  
    @Value("${activity.datasource.timeBetweenEvictionRunsMillis}")  
    private int timeBetweenEvictionRunsMillis;  
    @Value("${activity.datasource.minEvictableIdleTimeMillis}")  
    private int minEvictableIdleTimeMillis;  
    @Value("${activity.datasource.validationQuery}")  
    private String validationQuery;  
    @Value("${activity.datasource.testWhileIdle}")  
    private boolean testWhileIdle;  
    @Value("${activity.datasource.testOnBorrow}")  
    private boolean testOnBorrow;  
    @Value("${activity.datasource.testOnReturn}")  
    private boolean testOnReturn;  
    @Value("${activity.datasource.poolPreparedStatements}")  
    private boolean poolPreparedStatements;  
    @Value("${activity.datasource.maxPoolPreparedStatementPerConnectionSize}")  
    private int maxPoolPreparedStatementPerConnectionSize;  
    @Value("${activity.datasource.filters}")  
    private String filters;  
    @Value("${activity.datasource.connectionProperties}")  
    private String connectionProperties;  
    
    /**
     * 创建druid数据库连接池bean
     * @return
     */
    @Bean(name = "activityDataSource")     
    @Primary  
    public DataSource activityDataSource(){  
        DruidDataSource datasource = new DruidDataSource();  
        datasource.setUrl(this.dbUrl);  
        datasource.setUsername(username);  
        datasource.setPassword(password);  
        datasource.setDriverClassName(driverClassName);  
        datasource.setInitialSize(initialSize);  
        datasource.setMinIdle(minIdle);  
        datasource.setMaxActive(maxActive);  
        datasource.setMaxWait(maxWait);          
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);  
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);  
        datasource.setValidationQuery(validationQuery);  
        datasource.setTestWhileIdle(testWhileIdle);  
        datasource.setTestOnBorrow(testOnBorrow);  
        datasource.setTestOnReturn(testOnReturn);  
        datasource.setPoolPreparedStatements(poolPreparedStatements);  
        datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);  
        
        try {  
            datasource.setFilters(filters);  
        } catch (SQLException e) {  
            e.printStackTrace();
        }  
        
        datasource.setConnectionProperties(connectionProperties);  
          
        return datasource;  
    }
    
    @Bean(name = "activityTransactionManager")
    @Primary
    public DataSourceTransactionManager activityTransactionManager() {
    	return new DataSourceTransactionManager(activityDataSource());
    }

    @Bean(name = "activitySqlSessionFactory")
    @Primary
    public SqlSessionFactory activitySqlSessionFactory(
    		@Qualifier("activityDataSource") DataSource activityDataSource) throws Exception {
    	final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
    	sessionFactory.setDataSource(activityDataSource);
    	return sessionFactory.getObject();
    }   
    
}

标签:03,分库,String,数据源,数据库,Value,private,datasource,activity
来源: https://www.cnblogs.com/richardhaha/p/15807294.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有