分布式事务-03-单体应用分库多数据源改造
2022/1/15 23:07:11
本文主要是介绍分布式事务-03-单体应用分库多数据源改造,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
需要多库的原因
什么情况下需要多库呢?数据库不够用的时候。
如果应用的用户不断增长,数据量也不断增长,单一数据库的数据量较大(问题来了,多少算较大?),数据库查询成了瓶颈的时候,那么就需要分库分表。
数据量推测
假设是流量充值应用场景。
假设100万注册用户
访问量:一天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亿订单数据。
当用户量更大的时候,数据量更大,数据库访问不是瓶颈,但是数据库的空间大小成为瓶颈。
数据拆分
一般而言,是按照数据量分库分表,把数据量均匀分布到多个数据库中。
但刚开始就以最简单的按业务来拆分库。
资金、流量券、促销、积分、流量套餐、抽奖、充值订单,分别使用独立的数据库服务器,各个表的数据放在自己的服务器上,使用自己的磁盘空间,这样可以初步的先延长一下我们数据库的使用的周期。
单体应用多数据源改造
- 根据业务先建立多个库,再把每个业务对应的表移过去
- 设置多个数据源
- 把mapper分到各个package里
- 在application.yml中,配置相应的参数,便于
@Value("${activity.datasource.url}")
获取到参数 - 配置mapperscan
- @Bean(name = "activityTransactionManager")
- @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-单体应用分库多数据源改造的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)