Twitter的水平扩展的一些关键点,虽然它是个RoR应用,但是这些建议绝对是放之四海而皆准的,非常好的总结。
因为年初Twitter曾经遇到了性能瓶颈,而且几乎束手无策。当初很多人开始怀疑Ruby的性能问题,而后Twitter站起来了 ^__^
有时间的朋友看看这个slide:http://www.slideshare.net/Blaine/scaling-twitter,没有时间的看看我的摘要。
开发:
1、一定要测试!一定要早点测试!一定要早点测试!否则你就死定了。不要存任何侥幸心理,从项目的开始就写好测试。
2、对任何部分都要测试。还是测试!
3、性能测试要交给用户来做。那样才有意义。所以要做好log。用好分析工具:Munin(服务器内存占用监控)、Nagios(服务器服务网络状态监控)、AWStats & Google Analytics、错误日志、发现了错误马上进入问题跟踪系统(Trac、Jira……太多了,但是最好有一个)。
架构:
1、使用可以分区的架构。按照架构上的功能清晰的分区。这意味着你可以通过替换一个实现来改进性能,因为性能和复杂度往往是不可兼得的。
对于数据库:
1、尽量不要分布式数据库,包括数据库分区。最好通过提高单台服务器的性能提升这个节点的性能。更重要的是查询优化。通过备份服务器解决单点故障。
2、对where子句中的字段增加index。(这个当然了)
3、扁平化查询,比如一个user有很多朋友,查一个人的朋友如果通过外键会浪费很多性能。可以把ids序列化为1,2,3这样,然后用like查询速度更快。
4、一定要优化你的SQL,不要寄希望于ORM给你解决(不管是DataMapper、ActiveRecord或者UnitOfWork)。
Cache:
1、一定要考虑Cache,最重要的是领域对象的Cache,一定要考虑Memcache,如Memcached。
2、应该有90%的查询可以Cache。
3、但是要注意Cache实效问题(要及时标注实效),这个是个难点也是个重点。
4、可以考虑用Message来标记实效(这样可以保证异步,无阻塞的按照顺序的让数据失效),据称也不是很难。
Messaging:
1、混合应用。不用去看Java的OpenFire了,即使它很好,完全可以考虑erlang的ejabberd了,俄罗斯的产物。
2、排队问题有很多解决方案:ActiveMQ、RabbitMQ、MySQL + Lightweight Locking、Drb(for ruby)