日期:2014-05-16  浏览次数:20713 次

通过缓存中的复制延迟标记实现对PHP/MySQL的读/写的分离式控制

我一直在想,在我们的中国及海外客户不断快速成长的情况下,如何能够更好地扩展他们的网站,却保持其原有网站内容及结构仍旧简单可用。

一个扩展方法便是,采用数据库副机来实现读操作,读操作在很多网站上表现为80%以上的SQL查询,但是对于游戏类网站而言,读操作的SQL查询占比不尽相同。标准的方法就是,实行读/写分离,即数据库主机实现写操作,而副机实现读操作。

这样一切工作就会很顺利,但是,当许多因素,尤其是有大量的MySQL查询出现的时候,副机会产生延迟现象,而且尤其是在游戏类、数据采集类及统计类网站中,当有大量的写操作时,情况会变的更糟糕,这样读操作会延迟数秒,甚至更长,导致用户无法正常操作、站点甚至游戏无法正常运行。

但是,若仅允许读操作在主机上实现的话,又会影响到系统扩展,所以,一些站点对读操作进行区分,重要的读操作在主机上实现,次要的在副机上实现,但问题是,很难区分出哪些是“不重要的”读操作,在游戏中区分出不重要的读操作更加困难。

若某些副机出问题的话,情况会变得更复杂,当只有几台服务器承担大量的查询负荷、复杂工作、或数据分析工作时,会使副机延迟现象加重。副机1工作正常,但是突然副机2连续一个小时滞后1分钟,然后,副机3出现代码问题,因为有人在该机执行了写操作导致复制中止,需即刻修复。

那么,如何才能够最好地处理该问题呢?

一个好的主意,就是进行动态的读/写分离,运用某个系统来监控系统的复制延迟现象,理想的情况是,在缓存中设置一些标记(旗帜),用以显示副机的真实状态并控制查询去向。基本的处理方式就是,设置一些桶(斗),用于显示延迟在1秒内、10秒内、1分钟内甚至更多的时间内的副机。

然后,带有重要读操作的代码可以检查缓存页面开始处,作出明智决定,发出读操作,先是发到延迟较短的副机,继而是延迟稍长的副机,最后是发到主机。

同其它动态控制系统一样,当负荷很重,事务/请求/答复很频繁时,系统便会失控,(更不必说有振动及其它问题产生)。最好的方式就是,从简单开始,实行有限控制,可运用卸载(甩负荷)技术,如时间延迟很长或主机读数量很大时,禁止占时较长的大型的读查询。

尽管系统不尽完善,但是能自动处理许多问题,尤其是自从配备了合适的系统监控及管理以后。在负荷高峰期,能够处理单个副机乃至整个系统的延迟问题,确保在特定条件下,能够提供最好的用户体验,并且在系统出问题时,不会带来严重的影响。

 

                                 (Authored by Steve Mushero / ChinaNetCloud CEO & CTO  本博客英文原文请点此查看