百万用户规模的系统如何扩展

系统扩展一直是个让人头疼的事情,但系统扩展过程中你是不是也经常会产生一些新的想法?同样,别人扩展系统的经验也一定会给你带来很多帮助,MatinKleppmann通过本文分享了他自己的一些经验。

系统扩展一直是个让人头疼的事情,但系统扩展过程中你是不是也经常会产生一些新的想法?同样,别人扩展系统的经验也一定会给你带来很多帮助,MatinKleppmann通过本文分享了他自己的一些经验。

这些经验对于扩展Twitter这样规模的系统或许没有什么帮助,但是针对百万用户级别系统的扩展(很多项目面临这样的难题),MatinKleppmann的经验无疑会带来很多帮助:

构建可扩展系统没有什么乐趣可言,这是一个枯燥而又繁琐的任务。虽然大量的工具已经预先准备好了,可现有的那些开源解决方案有着各种各样缺点(当然你自己的方案也不一定有多好,但至少能够帮你解决特定的问题)。

在这里,MatinKleppmann分享了他的6个重要的系统扩展经验(外加网友的一条有用评论):

1. 实际工作中的负载测试非常困难

负载测试需要让系统承担不同的工作量,有些工作量甚至超出了你现有的数据量水平,通过负载测试,评估系统在不同工作量条件下的性能,以及持续常态运行的能力。具体还需要测试出系统的响应速率、事务处理速率等参数。然而测试一个大型分布式系统和做科学实验不同,科学实验可以在理想条件下进行,而负载测试则要难得多了,这对于搞计算机科学的人来说可能很难接受。你很难知道你实际访问的是怎样的模式,很难测试比你实际拥有数据更大的综合数据集,很难将旧系统与新系统进行比较,所以为防新代码出现错误,你要随时准备好回滚。

2. 数据演变(data evolution)很困难

想象一下,你的机房被数据“淹没”的情形,到处都是数据——数据库中、日志中,以及一系列二进制数据块中。这时候如果要更新数据格式,你就需要改变一个巨大的时槽,而大公司在这些处理的自动化和优化上有着丰富的经验,可以适当借鉴大公司的数据演变经验,节约数据演变的时间成本。

3. 数据库连接是一个瓶颈

当系统在服务和节点数增加时,数据库连接数以难以置信的速度增加。每个连接都会消耗资源,不仅仅是机器资源,还有人力资源,因为你的开发人员需要去弄明白怎样解决这些问题。通过使用连接池或者编写数据访问层,你可以通过API进行数据库访问。

4. 读取副本是一步痛苦的操作

但读取副本从主服务器中解除数据库访问也是一种常用的扩展策略。同样,这也需要花费大量的精力来建立和维护这些系统,毕竟故障处理是一个始终存在的问题。

5. 考虑内存效率

峰值延迟通常是由内存问题引起的,想要更有效地利用RAM可能很困难,因为你很难判断出RAM的实际使用情况。通过购买更多的RAM可以解决很多性能问题,如果可能的话,可以在RAM中加入索引,注意是对字符串的哈希表建立索引,而不是针对字符串本身。

6. 更改捕获(change capture)是一个有效的方法

比如更改系统中的数据,这样的更改必须通过许多服务,比如数据库、搜索索引、图、索引、副本读取、缓存无效化。你可能认为可以每次在应用更新时将其写到多个位置,但实际上很少这样做。你也许认为可以通过应用程序读取数据库日志,但这对于有些系统是不可行的。更改捕获系统是一个不错的解决方案,该系统捕获所有写操作并将它们存储到数据库中。应用程序可以实时接收这些更新,它们会形成更改的历史记录。该方法的好处是将数据生产者和消费者分开,这为你进行实验提供了很大的方便,而不用去担心对主要站点造成影响。

7. 针对高速缓存和缓存无效化(cache invalidation)

Mysteriousllama的一篇文章评论为我们提供了额外的经验:如果没有正确地缓存,又没有有效的缓存失效策略,那数据库就危险了。使用Redis和Memcache来缓存可能出现的一切,而且要切记:不到万不得已,不要连接数据库。确保你可以轻松使任何缓存无效化,保持事务原子性,避免系统在紊乱状态下运行。通过锁定,以确保当缓存无效时,数据库不会堆满同一查询的多个副本。你或许会认为选择数据库中的查询缓存可能同样有效,但相信我,这不太可能。当然,除了缓存简单的查询,你还可以缓存更高级别的对象。

根据你对可靠性的要求,你还可能会考虑将缓存用作回写和数据库后台的批处理写入。由于多种因素的影响,这一般都要比单个写入效率更高,许多大型网站都将这作为它们进行系统扩展的常用策略。

来源:CSDN

0赞

好文章,需要你的鼓励

2014

04/20

22:41

分享

点赞

邮件订阅
白皮书