巧用RDS全家桶搭建亿级新闻源仓库

我们的业务,有一个实时新闻源库,初始大概有3000万数据,现在大概有上亿条数据了,我们在起初的处理方式比较简单粗暴,直接购买了3台8核16G的SSD版本的ECS,组成了一主双从的机组,从库只读。

业务是单库,但是具体的内容是分表的,比如:

article_content_01一直到article_content_200或更多,业务系统会在满足要求后实时创建新的表,每张表的数据量大概在100万左右。

我们在2013/2014年开始遇到各种各样的问题,也算是一些经验教训吧:

1.使用ECS组建的数据库集群,可用性不是特别特别的高,主要受限于IO、网络同步速率。甚至遇到过从库意外关机,然后影响业务了。

2.我们把所有的读取SQL放到了从库进行,但是问题来了,我们的开发语言是php,所以它没有办法像JAVA那样做一个连接池来处理请求,一开始我们使用一个随机算法来分配每次读请求所使用的从库,导致当我们的并发很大的时候,从库的连接分配策略会出现不平均的问题,从而导致某个从库满载。虽然最后通Haproxy完成了从库的负载均衡,但是也带来了额外的运维负担。这个谈不上是坑,算是一个经验教训,想当然的以为随机算法可以替代负载均衡了。

3.风控的问题 ,有的时候一些不应该发生的低级错误就是这么堂而皇之的出现了,比如,测试库只有3000万数据,而正式库有3亿数据,有些逻辑代码在测试库的响应正常并不代表在正式库也是正常的。如果你不能敏感并及时的去处理慢查询,那业务基本也就凉了。

4.监控的问题不提了,直到最后都没找到一个称心如意的MYSQL监控解决方案。

5.审计的问题,我们永远处于有日志,而没办法审计的状态,有事没事假装看看罢了。

6.备份就讨厌了,需要手动这先不说。备份时机、锁表、备份后的归档处理、定时清理老备份、备份文件的校验,这些都是事儿啊,对运维人员来说,都是很低级但是不得不做的工作。

7.有的时候,你的Web服务器抗住了流量,但是不幸的是你的数据库没能坚持下去,这种突发的流量往往没办法预测,或者出现后需要最短时间内修复,我们出现过大概3次,每次大概2小时时间去扩容,会影响一部分我们用户的体验,表现为卡顿、页面报错等。

8.硬成本和运维成本问题,3台高配ECS+1个全职运维人员的成本,一年下来少说也要几十万。

问题应该有很多,但是只能想到这些,先记下来吧。其实有很多问题不是MYSQL的问题,属于架构层面或者开发层面的问题,但是我们谈一个具体技术细节的时候不能只谈它本身,没有场景和实践,那是耍流氓啊。


然后我们从15年开始,实在是不行了,这种方式已经让所有人都接近崩溃,所以我们考虑切换到RDS上去,当时只是先切换了几个不重要的业务库,试试看效果。然后一发不可收拾,总结一句话,这产品除了价格,简直完美。

首先RDS for Mysql解决了我之前提到的几个问题:

1.托管式的服务,动态弹性的升级,不需要关心运维的问题。

2.可以动态的添加只读库,方便。

3.控制台对慢查询很敏感(虽然这个是近2年才有的功能),而且可以做报警。

4.阿里云现在这一版的控制台看监控还算是比较舒服,也能看的全。

5.日志审计这一块,通过最新版本的阿里云DMS已经可以比较简单的完成了,它还有个收费版,没用过,没有发言权,但是现在这个免费的版本也挺不错的。

6.备份不提,阿里云RDS的备份已经做得很好了。

以上的问题,除了突发流量暴库的问题不能通过RDS直接解决,其他都能很好的解决了。而且相对于3个ECS的成本,单独购买RDS的费用也还在可以接受的范围内。

下面说一下,我们如何解决突发流量的问题,阿里云有个比较好的产品叫DRDS,但是这个产品属于好用,但知名度不高的一个状态,可能是小客户用到的概率不高吧。

DRDS扮演了一个类似负载均衡器的角色,当然了,比普通的负载均衡更高级一些。它不仅仅是Haproxy这种基于网络点的负载均衡,还可以针对SQL进行负载均衡,这一点在处理超大表检索的时候特别好用。而且它的后端是一个个的RDS,对于低成本突破连接数限制有非常大的帮助,同时弹性增减扩容,只需要购买按量RDS就可以了。

在高并发的场景下,数据库遇到的问题主要在于连接数限制、IO限制、锁、并发读写等问题,这些问题通过RDS/DRDS几乎都可以很好地去进行处理,有些高级应用需要做一点点开发上的让步。


阿里云的RDS实例其实也经过变迁的,起初是只限制内存和连接数,后来才出现“CPU核数”这个概念,所以也导致了我这种老用户一度很难适应,毕竟老版本2400M内存的RDS就默认8核了,而现在购买一个8核的RDS价格还是比较高的。我有个骨灰级的实例,可以截图给大家看下,现在买不到啦:

有一段时间,时不时也会收到短信提示,RDS发生主备切换云云,起初是比较紧张的,担心阿里云的技术不硬从而影响我的业务,后来切换过多次之后,发现真的没出过问题,从此也就安心了,小顾虑罢了。


最后一部分说一下,我们如何解决全文检索的问题,因为有分表的原因,所以很难通过程序去完成全文检索,而且因为量大Like语句基本不可能使用。在这种情况下,我们开始尝试使用第三方的工具去完成,比如Sphinx 。但是我们很快又遇到了问题:

1.成本问题,因为Sphinx 不写磁盘,一切读取到后都存在内存,所以几亿数据对内存的要求就高了,买ECS的时候就要买高内存的配置。

2.Sphinx一次性读取数据到内存这个过程,可能对业务产生一定性能影响,但是不严重。

3.Sphinx 的运维问题及配置问题。

然后我们偶然的发掘了阿里云的OpenSearch产品,支持RDS一键同步并且可视化的创建表、索引很舒心,还提供了SDK和各种好用的函数。唯一的问题在于,价格感人,特别是数据量大且每天并发检索高的用户来说,这个成本很可观。但是优点也很明显:

1.除了一开始的创建,几乎不需要你运维。

2.所有数据都打平到一层,检索速度极快。

3.支持分表结构,支持多个实体表,支持主外键关联,万物皆可查询。

4.对数据源几乎没有任何影响,即便你源库挂了,检索服务依旧可用。


就先写到这里了,都是些经验教训,谈不上太高深的技巧,主要还是要结合场景去做一个适合自己业务的架构。现在我们关系型数据库用RDS for Mysql,NoSQL数据库使用RDS for MongoDB,一路走来也都挺好的,虽然某个阶段它有这样那样的问题,但是一个持续迭代的产品必然会有更高的生命力和稳定性。