SQL的读写分离与负载均衡问题设想。
首先,我们可以了解一下,SQL的读写分离的工作方式,如下图所示:
总得来说,三种方案,现阶段来说,都是单节点写,多节点读。SQL 2012 的Always On还实现了读负载均衡,但方案投入相对来说较大。
所以用得最多的应还是第二种方案,表级同步,数据差异几秒。但有个问题,当只读的节点多了时,要如何实现负载均衡?
真正的负载均衡,需要计算的东西太多,要计算连接线程数,要计算CPU使用率等,而这一切都需要你在程序中体现。实现难度相对来说会好大!
除非你用第三方服务软件来实现,SQL现阶段来说,这样的软件不多,公司也未必会进行投资。
所以我自己分析了一下代码级的负载均均衡。
读写分离后的读均衡的数据层有几个条件需分析:1、需提前判断SQL语句是写语句(insert 、update、Create、 Alter)还是读语句(Select);
存储过程是写还是读的也需区分清楚。2、刚新增的数据的即时读需怎么解决。3、读的时侯怎么实现负载均衡?
对于第三点,负载均衡,首先不会做得太复杂,太复杂的话,没有第三方软件,实现起来难度大,性能也难以保证。所以只想了简单的方案:
1、多节点平均线程,忽略了SQL查询的查询性能及时间,单纯计算连接线程数。
2、采用随机算法选出节点,嘎嘎,网上找到的。感觉不太好把握。
3、采用循环算法,就是节点转成列表,每次读库,记录上次读库用到的节点。这个也忽略了查询的性能及时间等因素,实现起来简单。其实同时
实现了多节点平均线程。
4、还有一种是采用循环及计数算法,需记录还在活动的查询线程,读库的类在open connection时需计数加1,释放Connection时,需要把计数减1。
以上4种方法,我觉得第3、4种较为好,看项目的需要可以进行改造。
但还有一个问题,就是写数据库的刚写进却说的数据同步到读数据库中需要间隔时间,如果不做处理,会出现新增后数据找不到的情况。
这个问题的解决比较考验技艺了,普通的单个新增、更新可以在读库类中的新增方法及更新方法中用Thread.Sleep(1000);让系统等一下。
但批量新增、更新的就不能用单个新增、更新的方法了!!不然,你就等死吧,呵。