最近一直在学习大型网站的架构和性能优化,疯狂地从网上寻找各种可能的架构资料,终于在InfoQ上找到2009 QCon举办的QCon全球企业开发大会北京站演讲资料。
挑了我最喜欢的几个大型网站(豆瓣、淘宝、优酷),先看了豆瓣的主讲人洪强宁分享的《豆瓣网技术架构变迁》。看完后有几个感觉:
※ 罗马不是一天建成的
豆瓣在5年内经历了6次架构的调整,和淘宝有得一拼啊。任何优秀的架构都是在不断的问题和瓶颈中发展起来的
※ 总是考虑使用Memcached
应该在系统架构的第一时间就考虑使用Memcached,按照洪大师的说法。豆瓣现在的内存缓存有38G。Memcached的好处地球人都知道了
※提防Memcached的并发访问
Memcached虽然是剂猛药,但也有可
能成为毒药。特别是在高并发的情况下同时获取一批缓存数据的时候(不知道新版本的Memcached解决这个问题没有,当时我第一次看到这个功能时那是激
动得内牛满面啊~~~)。要知道Memcached毕竟只是个缓存工具,不是内存数据库。不要指望他提供什么锁、并发控制的机制(不过它倒是提供了一个原
子操作increment,用于递增数据,对于刷新页面访问量之类的比较有用)
※ 根据数据访问特性合理规划表类型
使用MySQL的数据库,可以方便地使用不
同的存储引擎对应不同操作类型的表(貌似对于其它数据库,还没有这种功能。也可能是我孤陋寡闻了)。对于读写不平衡但并发低的情况,采用MyISAM可以
获得较高的效率。网上google了一把,ISAM的意思是Indexed Sequential Access Method
(有索引的顺序访问方法),它的优势是速度快,支持全文搜索;但对事务支持差(PS:个人意见这个用来做数据分析或者数据挖掘最好了
^_^)。如果是用于高并发的读写访问,那么只能采用InnoDB类型的表了。
※ 动静分离
使用lighttpd具有比Apache更好的静态文件处理功能(PS:个人见到从豆瓣的第一个版本开始到目前为止的版本,只有两点是不变的:1.使用lighttpd对精通文件进行分离,直接从FS读取。动态的走SCGI接口。2.使用Memcached)。
※ 对缓存、数据库进行负载均衡,例如MySQL Proxy
使用类似于Load
Balance来平衡Memcached的负载。不同于Round-robin方式,采用的是hash分配。自己实现Hash算法(PS:这个倒是和网上
的多数观点一样,但缓存的东西多了,命中率总是会下降,要么扩大内存要么改算法,避免多次的重新分配)
※ 不要忽视小文件的读写
在豆瓣的某个发展阶段,就出现了因为大量的小图片读写而造成大量的磁盘IO和碎片的问题。原来豆瓣一开始也是把所有图片都放在一个目录下啊(),后来出现问题后才改成1000个图片一个目录。要不按照洪大师的说法:一个ls就可以让服务器挂掉。
※ 屏蔽表名和物理表的关系
通过中间映射实现底层物理数据表的无缝迁移。(PS:这个只要是做过Java的都知道了,IoC,代理其实也就是这个作用),具体的做法就是只传一个逻辑表名进去,后台函数映射后解析成一个真正的物理表所在的位置,方便日后的数据迁移,只要维护这个映射表就好了
※ 数据复制(主从模式)是必经阶段
当主数据库出现瓶颈时,要考虑采用数据库
复制的方式(Master /
Slave模式),主库负责事务性读写,从库负责非事务性读(不能有写)。数据库复制的形式在豆瓣的发展上发生了很多次变化,我看到的就有从单点的复制到
最终的跨机房复制。这一点可以从后面的PPT看到
※ 数据库复制是存在时间延迟的
数据库复制的延迟时间要考虑在内,否则会出现当主库写完后,未来得及复制到从库就出现Application从从库读数据的情况,严重的话用户每次更新数据后再刷新看到的永远都是旧的数据(缓存还没有更新,同步的数据还在路上呢....)。
※ 人肉刷新缓存有时候是必要的
接上面的问题,洪大师的团队最终采用了“人肉刷新”---- 即在可预见的情况下,内存中的数据更新后,主动调用Memcached的flush()方法刷新一下缓存,先同步了缓存再说,后面的数据你就慢慢复制吧。这个只能靠程序员自己控制了....ORZ
※ 统一的Data mining入口
豆瓣的数据库复制机制中有一个特别的“Data mining”模块,由它负责把数据写到主DB,再从主DB
replicate到从DB,然后Data mining模块从从DB read。这个有点搞不懂?这个“Data
mining”到底是什么来头?怎么所有数据都从这里写,甚至连主DB的数据都是从这里写进去的?
※ 分离服务器
把服务器分成控制服务器、应用服务器、代理服务器。分别对应入口转发,应用请求,负载均衡。把数据挖掘、日志分析、爬虫应用之类占用带宽,耗内存的东西全都移到后端,放在月黑风高,夜深人静的时候去进行吧。
※ 硬件的故障不可忽视
SCSI比SATA的稳定性要高,花在内存上的钱是值得的
※ 永远不要高估机房托管方、空间提供商的智商和责任心
比如洪大师说的:搬机器的时候不小心把你们服务器的电源线拔了之类的问题...
※ 如果你够牛B,那么考虑实现自己的内存数据库和文件系统
例如DoubanFS、DoubanDB(貌似这是一个基于key-value的内存数据库,看来内存数据库在未来大有可为啊,该死的hibernate,该死的iBatis,该死的OR-Mapping)。
以上是豆瓣洪大师的观点,加上最近看到的其它,也一并总结一下吧:
※ 尽可能在长事务的情况下使用异步通信,例如发送SMS、MMS到网关然后等待回应
※ 对数据库采用水平分区而非垂直分区以加强后期的扩展性
※ 合理恰当地使用索引
※ 在高层次的地方使用缓存,而不要在低层次的地方使用缓存
※ 建立科学合理的性能、压力测试环境。性能瓶颈总是出现在你意想不到的地方
posted on 2010-03-19 22:21
Paul Lin 阅读(1514)
评论(0) 编辑 收藏 所属分类:
架构与性能