我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么做数据库读写分离

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么做数据库读写分离

这篇文章主要讲解了“怎么做数据库读写分离”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么做数据库读写分离”吧!

实现方式

对于读写分离的使用,主要分为两种方式,客户端方式和代理方式。

客户端方式可以自己用 Spring 自带的 AbstractRoutingDataSource 来实现,也可以用开源的框架来实现,比如  Sharding-JDBC。

怎么做数据库读写分离

代理方式需要编写代理服务来对所有节点进行管理,应用不需要关注多个数据库节点信息。可以自己实现,也可以用开源的框架,也可以用商业的云服务。

怎么做数据库读写分离

数据延迟

谈到数据延迟,你先得理解主从架构的原理。对数据的增删改操作在主库上执行,查询在从库上执行,当数据刚插入到主库,然后马上去查询的时候,很有可能数据还没同步到从库上,就会出现查询不到的情况。

像我之前在某些网站发表文章,发表之后跳转到列表页面,发现没有新发表的文章,重新刷新下页面又有了,这一看这就是读写分离后的数据延迟导致的现象。

强制路由数据延迟要不要解决,一般取决于业务场景。对于实时性要求没有那么高的业务场景,允许一定的延迟,对于实时性要求高的场景,唯一的方式就是直接从主库进行查询,这样才能及时读到刚插入或者修改后最新的数据。

强制路由

就是一种解决方案,也就是将读请求强制分发到主库进行查询。大部分中间件都支持 Hint  语法/FORCE_MASTER/和/FORCE_SLAVE/。

以 Sharding-JDBC 举例,框架提供了 HintManager 来强制路由,使用方式如下:

HintManager hintManager = HintManager.getInstance(); hintManager.setMasterRouteOnly();

为了方便使用,建议封装一个注解,在需要实时查询的业务方法上加上注解,通过切面进行强制路由的设置。

注解使用:

@MasterRoute @Override public UserBO getUser(Long id) {     log.info("查询用户 [{}]", id);     if (id == null) {         throw new BizException(ResponseCode.PARAM_ERROR_CODE, "id不能为空");     }     UserDO userDO = userDao.getById(id);     if (userDO == null) {         throw new BizException(ResponseCode.NOT_FOUND_CODE);     }     return userBoConvert.convert(userDO); }

切面设置:

@Aspect public class MasterRouteAspect {     @Around("@annotation(masterRoute)")     public Object aroundGetConnection(final ProceedingJoinPoint pjp, MasterRoute masterRoute) throws Throwable {         HintManager hintManager = HintManager.getInstance();         hintManager.setMasterRouteOnly();         try {             return pjp.proceed();         } finally {             hintManager.close();         }     } }

事务操作

在事务中的读请求,走主库还是从库呢?对于这个问题,最简单的方式就是所有事务中的操作都走主库,在事务中经常会存在插入,然后再重新查询的场景,此时事务没提交,就算同步很快,从库也是没有数据的,所以只能走主库。

但还有一些请求,只需要查询从库就行了,如果针对所有事务中的操作都强制路由,也不是很好。在 Sharding-JDBC  中的做法挺好的,对于同一线程且同一数据库连接内,如有写入操作,以后的读操作均从主库读取,用于保证数据一致性。如果我们在数据写入之前有查询请求,还是走的从库,减轻主库压力。

怎么做数据库读写分离

动态强制路由

在功能开发的时候就决定了哪些接口要强制走主库,这个时候我们会在代码上进行路由的控制,也就是前面讲的自定义注解。如果有些是没有加的,但是在线上运行的时候发现还是要走主库才可以,这个时候就需要改代码重新发布了。

动态强制路由可以结合配置中心来实现,通过配置的方式来决定哪些接口要强制路由,然后在 Filter 中通过 HintManager  来设置,避免改代码重启。

也可以通过切面精确到业务方法级别的动态路由配置。

流量分发

场景一:

假设你有一个主节点,两个从节点,读请求较多,两个从节点压力有点大。这个时候只能增加第三个从节点来分担压力。现象是主库的压力并不大,写入较少,从成本来考虑,是否可以不增加第三个从节点呢?

场景二:

假设你有一个 8 核 64G 的主库,8 核 64G 的从库,4 核 32G 的从库,从配置上来看,4 核 32G  的从库处理能力肯定是要低于其他两个的,这个时候如果我们没有定制流量分发的比例,就会出现低配数据库压力过高而导致的问题。当然这个也能避免使用不同规则的从库。

上面的场景需要能够对请求进行管理,在 Sharding-JDBC 中提供了读写分离的路由算法,我们可以自定义算法来进行流量的分发管理。

实现算法类:

public class KittyMasterSlaveLoadBalanceAlgorithm implements MasterSlaveLoadBalanceAlgorithm {     private RoundRobinMasterSlaveLoadBalanceAlgorithm roundRobin = new RoundRobinMasterSlaveLoadBalanceAlgorithm();     @Override     public String getDataSource(String name, String masterDataSourceName, List<String> slaveDataSourceNames) {         String dataSource = roundRobin.getDataSource(name, masterDataSourceName, slaveDataSourceNames);         // 控制逻辑,比如不同的从节点(配置不同)可以有不同的比例         return dataSource;     }     @Override     public String getType() {         return "KITTY_ROUND_ROBIN";     }     @Override     public Properties getProperties() {         return roundRobin.getProperties();     }     @Override     public void setProperties(Properties properties) {         roundRobin.setProperties(properties);     } }

基于 SPI 机制的配置:

org.apache.shardingsphere.core.strategy.masterslave.RoundRobinMasterSlaveLoadBalanceAlgorithm org.apache.shardingsphere.core.strategy.masterslave.RandomMasterSlaveLoadBalanceAlgorithm com.cxytiandi.kitty.db.shardingjdbc.algorithm.KittyMasterSlaveLoadBalanceAlgorithm

读写分离的配置:

spring.shardingsphere.masterslave.load-balance-algorithm-class-name=com.cxytiandi.kitty.db.shardingjdbc.algorithm.KittyMasterSlaveLoadBalanceAlgorithm spring.shardingsphere.masterslave.load-balance-algorithm-type=KITTY_ROUND_ROBIN

感谢各位的阅读,以上就是“怎么做数据库读写分离”的内容了,经过本文的学习后,相信大家对怎么做数据库读写分离这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么做数据库读写分离

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

mongodb怎么做读写分离

在MongoDB中实现读写分离可以通过复制集来实现。复制集是一组运行在不同服务器上的MongoDB进程,其中有一个主节点(Primary)和多个从节点(Secondary)。主节点负责处理所有的写操作,从节点负责处理读操作。以下是一种在Mo
2023-09-04

MySQL做读写分离提高性能缓解数据库压力

这篇文章主要为大家介绍了MySQL做读写分离提高性能缓解数据库压力的技巧详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-05-19

SQL级别数据库读写分离策略

数据库读写分离是一种常见的数据库优化策略,通过将数据库的读和写操作分别分配到不同的数据库实例上,以提高系统的性能和稳定性。在SQL级别的数据库读写分离策略中,可以通过以下几种方式实现:主从复制:将数据库实例分为主数据库和从数据库,主数据库负
SQL级别数据库读写分离策略
2024-08-05

MySQL插入锁与数据库读写分离

MySQL插入锁是指在数据库中进行插入操作时会对相关数据行进行锁定,防止其他用户同时插入或修改该数据行。这可以确保数据的完整性和一致性,但也会影响数据库的并发性能。数据库读写分离是指将数据库的读操作和写操作分开到不同的数据库实例或服务器中
MySQL插入锁与数据库读写分离
2024-08-19

编程热搜

目录