李子

读写分离下的强一致性场景-MYCAT中间件
什么情况下可能导致同步延迟?服务器配置差、磁盘IO性能低下,无法满足业务需求。大表或者sql导致的性能问题,数据库...
扫描右侧二维码阅读全文
24
2018/10

读写分离下的强一致性场景-MYCAT中间件

什么情况下可能导致同步延迟?
服务器配置差、磁盘IO性能低下,无法满足业务需求。
大表或者sql导致的性能问题,数据库负载上升。

如何缓解或者避免此类问题,当出现主从延迟时如何处理?
对于主从同步延迟我们没法很好的控制情况下,对于一致性比较高的即时存取场景,可能存在刚insert完就需要马上查询结果,此类问题开发在使用中多次出现。

大多数的业务场景需要保证数据的强一致性,当使用数据库层使用mycat中间件代理时会出现前一次的数据库"写"的操作mycat指向的是主库,而下一次"查"的操作mycat指向了从库,出现数据不一致,此时须特殊指定,将"查"的操作也要指向主库。

解决思路:

索引和sql语句的优化、更换性能更好的SSD硬盘。

增加缓存层,写数据之前先存入redis或者memcache,读取时先从缓存层获取数据,如果缓存过期或者丢失再从数据库中查询。

中间件注解强制走主库
/#mycat:db_type=master/ SELECT * FROM un_item ;

注解规范

  1. 注解SQL使用select语句,不允许使用delete/update/insert等语句;虽然delete/update/insert 等语句也能用在注解中,但这些语句在Sql处理中有额外的逻辑判断,从性能考虑,请使用select语句
  2. 注解SQL禁用表关联语句
  3. 注解SQL尽量用最简单的SQL语句,如select id from un_item where id='1'
  4. 无论是原始SQL还是注解SQL,禁止DDL语句
  5. 能不用注解的尽量不用

注解使用示例
注解支持的'!'不被 mysql 单库兼容,
注解支持的'#'不被 mybatis 兼容
新增加 mycat 字符前缀标志 Hintsql:"/* mycat: /"

从 1.6 开始支持三种注解方式:
/#mycat:db_type=master/ select * from travelrecord
/!mycat:db_type=slave/ select * from travelrecord
/*mycat:db_type=master/ select * from travelrecord

mycat默认在事务里读都走主库,用事务可以解决这个问题
事务内的SQL,默认走写节点,以注释/balance/开头,则会根据balance=“1” 或“2” 去获取
非事务内的SQL,开启读写分离默认根据balance=“1” 或“2” 去获取,以注释/balance/开头 则会走写 解决部分已经开启读写分离, 但是需要强一致性数据的场景。
/balance/ select a.* from customer a where a.company_id=1;

主从延时切换:
mycat1.4 开始支持mysql主从复制状态绑定的读写分离机制,让读更加安全可靠。

需要把mycat心跳检查语句配置为 show slave status ;
dataHost 上定义两个新属性:switchType="2" 和 slaveThreshold="100",此时意味着开启mycat主从复制状态绑定的读写分离与切换机制。

心跳机制通过检测 show slave status 中的 "Seconds_Behind_Master","Slave_IO_Running","Slave_SQL_Running" 三个字段来确定当前主从同步的状态以及 Seconds_Behind_Master 主从复制时延。当 Seconds_Behind_Master > slaveThreshold 时,读写分离筛选器会过滤掉此 Slave 机器,防止读到很久之前的旧数据。而当主节点宕机后,切换逻辑会检查 Slave 上的 Seconds_Behind_Master 是否为 0,为 0 时则表示主从同步,可以安全切换,否则不会切换。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="kirin" checkSQLschema="false" sqlMaxLimit="100">
                <table name="un_item" dataNode="dn1" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" 
                            dbType="mysql" dbDriver="native" switchType="2" slaveThreshold="100">
            <heartbeat>show slave status </heartbeat>
            <writeHost host="hostM1" url="172.16.6.1:3306" user="root" password="xxx"></writeHost>
            <writeHost host="hostS1" url="172.16.6.2:3306" user="root" password="xxx"></writeHost>
        </dataHost>

</mycat:schema>
最后修改:2018 年 11 月 18 日 09 : 12 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论