这篇博文分享的是我们使用阿里云RDS(关系型数据库服务)遇到的2个烦恼——让人无奈的资源争抢与缺少弹性的限制策略。
昨天用2台临时磁盘的云服务器成功顶住了访问高峰,而且表现不错!相关背景见之前的博文:云计算之路-阿里云上:3月5日下午出现的异常情况。
云服务器的问题解决之后,却遭遇了RDS的2个问题。
第1个问题——资源争抢造成的RDS响应慢
问题表现于通过SQL Server Management Studio操作RDS实例频繁出现响应速度很慢的情况,有时鼠标点下去要等很长时间才有反应,甚至Management Studio标题栏会出现Not Responding的提示。
开始还以为是我们的RDS实例负载过高,但是当时这个实例的IOPS并不高(见下图),我们购买的RDS实例的最大IOPS是4000。
后来在访问低峰操作,也是同样的问题。于是,我们不得不怀疑是同1台物理机上的其他RDS实例惹的祸——抢占了更多计算资源。
提交工单之后,客服的说法也验证了我们的怀疑——我们的RDS实例所在的物理机压力比较大,今天经过RDS DBA的确认,的确存在资源争抢的问题。
针对这个问题,阿里云目前的解决方法是先将抢占资源的RDS实例移至其他负载低的物理机临时解决问题,然后考虑更有效的资源隔离方案。
虽然有效地解决资源隔离问题是云服务商面临的一个很大的挑战,但是从一个用户角度,如果不解决这个问题,真的很痛苦与无奈——自己再怎么努力优化性能也无济于事,只能每天祈祷同一艘服务器上的其他RDS实例安分守己。
第2个问题——阿里云RDS对数据库最大连接数的硬性限制
先看下面一张RDS实例数据库连接数的监控图:
我们购买的RDS实例的最大连接数是800。现在工作日访问高峰会出现几次达到最大连接数的情况,我们面临这样一个选择——要不要升级RDS?而升级规格也只有1个选择——最大连接数:1200。也就是说为了1周不超过10次的数据库连接数超过800的情况,我们却要将RDS扩容40%,弹性扩展能力都去哪儿了?
如果我们的应用程序的负载真的偶尔需要超过800的数据库连接,我们进行升级也就罢了。但是,这些数据库连接实际上是ADO.NET连接池保持着的连接,是为了更好的性能——新建数据库连接是不容忽视的开销,实际的活跃连接数没这么高。
所以,阿里云RDS把连接数作为衡量用户使用数据库服务器资源的一个硬性指标,我们觉得不合理。除了数据库连接数不代表活跃连接数外,同样是一次数据库连接,有的快如闪电,有的慢如蜗牛,资源消耗不是一个级别的。即使使用的是最低规格的RDS,只用了很少的数据库连接,但是如果SQL操作性能低下,也会占用很多资源。
在RDS规格中还有另外一个硬性指标——IOPS,这个指标倒是比连接数靠谱得多,至少反映了用户实际消耗的IO。当然,仅靠它判断资源消耗量也是不够的,还有内存、CPU,所以RDS规格中也有内存大小,但目前没有CPU的限制(也许这里恰恰就是资源争抢的主战场)。
所以,要判断一个用户实际消耗的数据库服务器的计算资源,需要结合多个因素综合考虑,而现在RDS最大的问题是——会完全依据最大连接数这个单一指标进行强制限制,只要超过了最大连接数,就会拒绝后续的所有数据库连接——逼着用户赶紧升级。即使假设这样的限制有1万个不得已的理由,那也得从用户角度考虑,留一定的峰值余度,比如1天内可以超过最大连接数多少次,就是CDN计算流量时也会去除一部分峰值。
更多从用户角度考虑,很多问题就会迎刃而解,即使不能迎刃而解,折衷的方案也会减少用户的痛处。云计算做的不是高上大的技术,而是实实在在的服务。