Cobar的十一个秘密:
1.Cobar会假死:原因->不可能吧,据说Cobar是NIO的非阻塞,其实,Cobar前端是NIO的,而后端跟mysql的交互是阻塞模式,其NIO只给出了框架,还未实现.
2.Cobar高可用的陷阱:原因->分片节点配置了两个数据源,每个节点会对数据源进行心跳检测,默认是第一个,频率是10秒钟一次,当心跳失败后,会自动切换到第二个数据源进行读写,假如Cobar发生了假死,则在发生假死的1分钟内,Cobar会自动切换到第二个数据源,因为假死的缘故,第二个数据源的心跳也超时.导致1分钟内Cobar来回切换.可能在两个数据源都发生写操作,破坏数据一致性,无法知道那个数据源是最新的数据.
其次,当后端数据库达到最大连接时,会对新建连接全部拒绝,此时,Cobar的心跳检测所建立的新连接也会拒绝.
3.看上去很美的自动切换:可能出现主备两个库都在同时写数据,主备同步失败的情况
-Cobar启动的时候,会用默认第一个Datasource进行数据读写操作
-当第一个Datasource心跳检测失败,会切换到第二个Datasource
-若有两个以上的Cobar实例做集群,当发生节点切换,你若重启其中任何一台Cobar,就完美调入陷阱
目前只有一个解决办法,节点切换以后,尽快找个合适的时间,全部集群都同时重启,避免隐患
Mycat如何解决该问题?很简单,节点切换以后,记录一个properties文件(conf目录下),重启的时候,读取里面的节点index,真正实现了无故障无隐患的高可用
4.只实现了一半的NIO:
简单的SQL执行过程
FrontConnection 实现了 NIO 通讯,但 MySQLChanel 则是同步的 IO 通讯.
MyCAT 在 Cobar 的基础上,完成了彻底的 NIO 通讯,并且合并了两个线程池,这是很大一个提升。从 1.1 版本开始,MyCAT 则彻底用了 JDK7 的 AIO,有一个重要提升。
5.阻塞:
Cobar 本质上类似一个交换机,将后端 Mysql 的返回结果数据经过加工后再写入前端连接并返回,于是前 后端连接都存在一个“写队列”用作缓冲,后端返回的数据发到前端连接 FrontConnection 的写队列中排队等待 被发送,而通常情况下,后端写入的的速度要大于前端消费的速度,在跨分片查询的情况下,这个现象更为明显,于是写线程就在这里又一次被阻塞。
MyCAT 解决此问题的方式则更加人性化,首先将原先数组模式的固定长度的队列改为链表模式,无限制, 并且并发性更好,此外,为了让用户知道是否队列过长了(一般是因为 SQL 结果集返回太多,比如 1 万条记 录),当超过指定阀值(可配)后,会产生一个告警日志。
<system><property name="frontWriteQueueSize">1024</property></system>
6.又爱又恨的SQL批处理模式
提交到 cobar 的批处理中的每一条 SQL 都是单独的数据库连接来执行的
批处理中的 SQL 并发执行
7.死锁:
一个线程需要锁定 N 个资源并执行操作以后,才结束事务。当这 N 个资源的锁定顺 序是随机的情况下,那么就很容易产生死锁现象,而恰好 Cobar 并没有保证 N 个资源的锁定顺序,于是我们再次 荣幸“中奖”。
8.连接池被分割:
因为 Cobar 对后端 MySQL 的连接池管理是基于分片——Database 来实现的,而不 是整个 MySQL 的连接池共享,以一个分片数为 100 的表为例,假如 50 个分片在 Server1 上,就意味着 Server1 上的数据库连接被切分为 50 个连接池,每个池是 20 个左右的连接,这些连接池并不能互通,于是,在分片表的 情况下,我们的并发能力被严重削弱
9.配置文件热装载:每次重载都把后端数据库重新断连一次,导致业务中断,而很多时候,大家改配置仅仅是 为了修改分片表的定义,规则,增加分片表或者分片定义,而不会改变数据库的配置信息
10.不支持读写分离
11.不可控的主从切换