符合 XX 公司的数据库中间件 MyCat 的使用

目录

ー:准备工作

二:MyCat 出现的坑

三:结论


 

ー:准备工作


数据库集群:一主两从

数据库高可用:不推荐,主从数据同步不一致问题。咨询了一线公司的兄弟。千万级数据量经过分表和主从读写分离后,完全扛得住。比如 1000万 的表,切分 4表 之后也就单表 200多万 。查询速度并不慢

  1. 咨询到的情况,是单表 1000万 刚刚达到分表的界限。单表其实也可以支持。20 个字段左右。(数据量刚好达到分表分库的情况

  2. 主要是读时延时。 千万级数据主键查询也就 1s ,其实也并不慢。如果没命中索引。10s 左右。切分后单表大概 200 多万数据。

    1. 要引入主键生成模块。防止分表后,各表的主键冲突。(如果不符合,则分表方案作罢,既要保证主键的唯一性,数据要是从其他库中导入不会有该问题)

    2. 主键查询会增快,但是也就在 1s 内。看切分规则!

      1. 如果是 hash 切分,那全表查询需要排序需要查询所有的库再排序,增加了复杂度。(只能尽量避免)既可能会更慢。且堆排序需要内存支持。不适合太大数据

      2. 如果按照范围进行切分,则按索引查询会很快。全查只需要每个表有序再进行合并即可。但是会产生的问题是查询的范围不均。可能会集中在一个区间。但是公司业务属于导购这边的业务,每个导购应该都是活跃的。应该查询的都比较热吧。建议采用这种分表的方式。切分规则较简单易于配置和理解。排序的话只需要取某个库的进行排序。推荐

  3. 需要引入保证数据库的高可用的能力以及故障恢复的能力。建议引入 binlog 备份能力。需要 DBA 开发。引入一天一备,一周一备,一月一备的能力,以及每天的增量备份。(我只会全量备份 binlog), DBA 那边搞这个。倒是基本没出过事只是出问题时候的保障

 

二:MyCat 出现的坑


  • 以下的问题都是按数据库已经按区间分表。切分规则如下,以自增的 id 主键进行 hash 分片。

  • mycat 目前只支持分库 join !不支持单库分表 join 。坑。不知道怎么搞。可能只能使用程序来控制。转战 sharding-jdbc

  • mycat 作为数据源使用的表都需要在配置文件中配置

  • mycat 不支持配置文件的热加载。需要重启中间件。这期间可能打断应用中执行的某些任务

 

问题一:非分片建查询


正常查询:根据分片主建查询,映射中存在映射关系,正常路由到正确表进行查询。

SELECT * FROM submeter WHERE id = 999;

除了 id 路由键之外的数据就需要三个库都进行查询了。因为中间件不确定在哪个库,之后还要进行合并的过程。所以基本杜绝了大量数据的非路由键的查询

SELECT * FROM submeter WHERE qwe = 'qwe999';

explain SELECT * FROM submeter WHERE qwe = 'qwe999';     // MyCat 会返回重写后的路由信息
dn1    SELECT * FROM submeter1 WHERE qwe = 'qwe999' LIMIT 100
dn1    SELECT * FROM submeter2 WHERE qwe = 'qwe999' LIMIT 100
dn1    SELECT * FROM submeter3 WHERE qwe = 'qwe999' LIMIT 100

前端一个查询,落到库中变为三个查询(只分了三个表)。占用三个数据库连接。如果分的多了,数据库响应其他客户端的能力变弱。

 

问题二:分页问题


语句:默认是是按主键进行排序的

select * from submeter limit 2;

explain select * from submeter limit 2;    // MyCat 会返回重写后的路由信息
dn1    SELECT * FROM submeter1 LIMIT 2
dn1    SELECT * FROM submeter2 LIMIT 2
dn1    SELECT * FROM submeter3 LIMIT 2

引入问题:

  1. 还是一个查询变多个查询的问题。
  2. 分页是按第一个 dataNode 返回的结果集为准的。(现象就是多执行几次。每次得到的结果集不同)  

解决问题:

  1. 问题一无法解决
  2. 需要加入排序字段解决,比如 order by id 语句。三个结果集都查完之后使用堆排序进行结果集的整合。(带入的问题是需要额外的引入排序机制,基本上排序都涉及到极高的时间复杂度),如果是使用 区间 进行拆分,则可以只拿其中一个查询结果集交差

 

问题三:分页问题再加入偏移量


语句:默认是是按主键进行排序的

select * from submeter order by id limit 5,2;

explain  select * from submeter order by id limit 5,2;
dn1    SELECT * FROM submeter1 ORDER BY id LIMIT 0, 7
dn1    SELECT * FROM submeter2 ORDER BY id LIMIT 0, 7
dn1    SELECT * FROM submeter3 ORDER BY id LIMIT 0, 7

问题:

对于有 tDB 节点的全分片 limit m, n 操作,Mycat 需要处理的数据量为  (m+n)*t 个。比如实际应用中有 50DB 节点,要执行 limit 1000,10 操作,则 Mycat 处理的数据量为 50500 条,返回结果集为 10,当偏移量更大时,内存和 CPU 资源的消耗则是数十倍增加。

 

解决问题:

看业务,这边使用区间进行拆分,一般只需要一个结果集即可。每个数据都较活跃不会造成某个范围分片区域过热。

或者用 ES 的排序来解决大数据量的分页问题。数据库只提供详情查询。

 

三:结论


公司业务要求有多个列表,且列表需要多维度进行查询,相同类型的数据还需要别的维度排序,根据上文可知。MyCat 中间件不适合做这些事情,所以转用了 ES 作为搜索引擎,屏蔽了对数据库的复杂查询,但是还是需要提供相应的产出数据的接口作为兜底,以防 ES 丢失数据时对服务的保证。且根据其他服务来源的数据,该数据是以主键递增的形式生成,并且每个 id 都很活跃,所以决定使用范围切分的方法,屏蔽 hash 分片带来的不易扩展等问题。因为每条数据都很活跃,所以也不会产生范围切分时某个分片请求过热的问题。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章