当前位置: 首页 > 科技观察

数据库分表,读写分离后,数据库中间件起到什么作用?

时间:2023-03-18 02:05:51 科技观察

分库分表,读写分离会带来什么问题?上一篇文章阐述了分布式系统架构(见推荐阅读),简单讲了分库分表,以及读写分离的场景。分库分表就是为了解决高并发和海量数据的问题。分库后会出现新的问题。1.跨库join问题。如果有2个数据库,订单数据库和用户数据库,需要查询所有购买了某种产品的用户信息。库存,如果订单数据和商品数据在同一个数据库中,我们可以使用事务来保证扣除商品库存和生成订单的操作要么成功要么失败,但是分库后就不能使用数据库事务了。使用分布式事务分表后也会出现新的问题。1、join操作横向分表后,数据分散在多个表中。如果需要和其他表进行join查询,需要在业务代码或者数据库中间件中进行多次join查询,然后合并结果2、count()操作业务代码或者数据库中间件进行count(*)操作在每个表上,然后添加结果。或者新建一个表,如果表名是“记录号表”,它包含两个字段table_name和row_count,每次插入或删除子表数据成功后,“记录号表”会更新3,orderbyoperationlevelsub-table最后将数据分散到多个子表中,无法在数据库中完成排序操作。每个分表中的数据只能通过业务代码或数据库中间件进行查询,然后聚合排序。在高并发这个阶段,肯定是需要做读写分离的,什么意思?因为其实大部分的互联网公司,一些网站,或者APP其实读的多,写的少。那么对于这种情况,就是写一个主库,但是主库挂了多个从库,然后从多个从库读取,能不能支持更高的读取并发压力呢?那么如何实现MySQL的读写分离呢?其实很简单。它基于主从复制架构。简单来说,我们需要建一个主库,挂多个从库。然后我们只写主库,然后从库中读取bin日志进行重放,这样主库和从库数据是一样的,只是并发比较高的时候,会有一个主从同步延迟问题。放一张图理解MySQL主从复制的原理。这个采访经常被问到。总的来说,MySQL的复制有三个Step1.在主库上的二进制日志(BinaryLog)中记录数据变化(这些记录被称为二进制日志事件)2.备库将主库上的日志复制到它的自己的中继日志(RelayLog)Log)3.备库读取中继日志中的事件,并在备库数据之上重放。既然有了理论知识,那如何实现呢?本来是为了实现一个功能,现在,单写读写分离,跨库join,分布式事务,排序操作等等,够你忙的了。这时候你就应该想到数据库中间件,它可以帮你完成上述操作,让你从复杂的数据处理中解脱出来,专注于业务代码的开发。数据库中间件能为您做什么?目前国内使用最多的中间件是sharding-jdbc和mycat。其他的很少用到,就不再介绍了。目前对于数据源管理的数据库中间件主要有两种思路。1、客户端模式,在每个应用程序模块中配置管理你需要的一个(或多个)数据源,直接访问各个数据库,完成模块中的数据集成。sharding-jdbc的实现方式2.通过中间代理层统一管理所有数据源,后端数据库集群对前端应用程序透明。放两张图就可以理解mycat的实现。一般建议小公司用sharding-jdbc,大公司用mycat,因为维护一个mycat集群也是需要人力物力的。.鉴于篇幅所限,本文介绍了mycat的基本使用,并用最形象的例子让你了解mycat为你做了什么。先介绍一下什么是分片?简单来说,就是将我们存储在同一个数据库中的数据,通过一定的特定条件,分散存储在多个数据库中,以达到分散单个设备负载的效果。如上图所示,数据被分到多个数据库中。数据库分片后,如果应用需要读取数据,需要处理多个数据源的数据。如果没有数据库中间件,应用将直接面对分片集群。数据源切换、事务处理、数据聚合都需要应用程序直接处理。本应以业务为主的应用会在处理sharding上花费大量的工作问题后,归根结底,每一个应用进程都将是一个彻底的推倒重来的轮子。因此,有了数据库中间件,应用程序只需要专注于业务处理,大量的通用数据聚合、事务、数据源切换都由中间件处理。那么数据库中间件是怎么做到的呢?绿色部分是mycat的逻辑节点,蓝色部分是物理节点(即数据库的部署地址)。数据库中间件的概念,所以数据库中间件可以看作是一个或多个数据库集群组成的逻辑库表:既然逻辑表有逻辑库,就会有逻辑表。在分布式数据库中,对于应用程序来说,读写一张数据表就是一张逻辑表。数据分片后逻辑表可以分布在一个或多个分片库中,也可以没有数据分片或分片,只有一张表构成一个datanode:分片节点数据分片后,一个大表被分割进入不同的分片数据库。每个表shard所在的数据库为shard节点datahost:节点host(上图中蓝色节点)数据分片后,每个shard节点(dataNode)不一定独享一台机器可以有多个shard数据库在同一台机器上。这样一个或多个分片节点(dataNodes)所在的机器就是节点主机(dataHost)。高分片节点(dataNode)均匀分布在不同的节点主机(dataHost)上。rule:分片规则我们前面讲过数据分片。当一个大表被分成若干个分表时,需要一定的规则。这样,按照一定的业务规则将数据划分成一定的分片的规则就是分片规则。选择合适的分片规则对数据切分非常重要,这将大大避免后续数据处理的困难。为了在实战中快速熟悉各种配置,Mycat一般都是直接从git下载代码,用idea在本地启动,方便练习。小编在本文中演示了这个方法。mycat的配置其实很简单,最重要的是熟悉各个配置文件的规则。例如用户名、密码、分片规则等都在配置文件中定义。关于配置文件,conf目录下主要有以下三个是大家需要熟悉的。如果你用idea打开本地测试,我会在resources目录下演示最简单的映射。配置,找一个数据库服务器,建3个数据库,db1,db2,db3,把id为0-5000000的数据放在db1中,把id为5000001到10000000的数据放在db2中,以此类推server.xml是Mycat服务器参数调整和用户授权的配置文件(部分配置省略,以下两个配置文件相同)123456TESTDBschema.xml是逻辑库,逻辑表定义和Slice定义配置文件selectuser()rule.xml是分片规则的配置文件idrang-longclass="io.mycat.route.function.AutoPartitionByLong">autopartition-long.txtautopartition-long.txt详细shardingstrategy#rangestart-end,datanodeindex#K=1000,M=10000.00-500M=0500M-1000M=11000M-1500M=2这个配置的意思是id从0到500w放在第一个分支的tablets,等等在。小编这里使用Navicat(数据库连接工具)连接本地mycat主机:localhost端口:8066用户名:root(在server.xml中配置的用户名和密码)密码:123456看到有TestDB库,执行表创建语句CREATETABLE`tb_test`(`id`int(11)NOTNULL,`name`varchar(255)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;然后去对应的查看物理数据库db1、db2、db3,三个数据库都有这张表向逻辑数据库插入如下三条数据insertintotb_test(id,name)values(1,"1");insertintotb_test(id,name)values(5000001,"5000001");insertintotb_test(id,name)values(10000001","10000001");可以看到id为1的数据插入到物理数据库的db1中,id为5000001的数据插入到db2中,id为10000001的数据插入到db3中。在逻辑数据库中执行以下语句获取这3条记录selectid,namefromtb_test执行以下语句,可以看到mycat分别从三个数据库中取了记录,LIMIT100是因为schema.xml中配置了sqlMaxLimit="100"explainselectid,namefromtb_test和mycat,我们的数据库地址配置成mycat就够了,帮我们做了很多,其他各种分片规则的配置,读写分离等就不再演示了,了解一下大概就可以了整个框架的运行过程***再分享一个知识点,从mycat1.5开始会支持本地xml启动和从zookeeper加载配置到本地xml的两种方式,即原来共享的zookeeper可以作为配置中心