从LiveJournal后台发展看大规模网站性能优化方法
一、LiveJournal发展历程
LiveJournal是99年始于校园中的项目,几个人出于爱好做了这样一个应用,以实现以下功能:- 博客,论坛
- 社会性网络,找到朋友
- 聚合,把朋友的文章聚合在一起
- 2004年4月份:280万注册用户。
- 2005年4月份:680万注册用户。
- 2005年8月份:790万注册用户。
- 达到了每秒钟上千次的页面请求及处理。
- 使用了大量MySQL服务器。
- 使用了大量通用组件。
二、LiveJournal架构现状概况

三、从LiveJournal发展中学习
1、一台服务器
毫无疑问,当时LJ存在巨大的单点问题,所有的东西都在那台服务器的铁皮盒子里装着。

2、两台服务器

暂时解决了负载的问题,新的问题又出现了:
- 原来的一个单点变成了两个单点。
- 没有冷备份或热备份。
- 网站速度慢的问题又开始出现了,没办法,增长太快了。
- Web服务器上CPU达到上限,需要更多的Web服务器。
3、四台服务器

- 单点故障。数据库和用于做网关的Web服务器都是单点,一旦任何一台机器出现问题将导致所有服务不可用。虽然用于做网关的Web服务器可以通过保持心跳同步迅速切换,但还是无法解决数据库的单点,LJ当时也没做这个。
- 网站又变慢了,这次是因为IO和数据库的问题,问题是怎么往应用里面添加数据库呢?
4、五台服务器

- 读操作数据库选择算法处理,要选一个当前负载轻一点的数据库。
- 在从数据库服务器上只能进行读操作
- 准备好应对同步过程中的延迟,处理不好可能会导致数据库同步的中断。只需要对写操作进行判断即可,读操作不存在同步问题。
5、更多服务器

6、现在我们在哪里:




- 在数据库组内不要使用自增ID,以便于以后在数据库组之间迁移用户,以实现更合理的I/O,磁盘空间及负载分布。
- 将userid,postid存储在全局服务器上,可以使用自增,数据库组中的相应值必须以全局服务器上的值为准。全局服务器上使用事务型数据库InnoDB。
- 在数据库组之间迁移用户时要万分小心,当迁移时用户不能有写操作。
7、现在我们在哪里

- 一个全局主服务器,挂掉的话所有用户注册及写操作就挂掉。
- 每个数据库组一个主服务器,挂掉的话这组用户的写操作就挂掉。
- 数据库组从服务器挂掉的话会导致其它服务器负载过大。
- 一个Master出错后恢复同步,最好由服务器自动完成。
- 数字分配,由于同时在两台机器上写,有些ID可能会冲突。
- 奇偶数分配ID,一台机器上写奇数,一台机器上写偶数
- 通过全局服务器进行分配(LJ采用的做法)。
8、现在我们在哪里

- 支持事务
- 需要做更多的配置,不过值得,可以更安全的存储数据,以及得到更快的速度。
- 记录日志(LJ用它来记网络访问日志)
- 存储只读静态数据,足够快。
- 并发性很差,无法同时读写数据(添加数据可以)
- MySQL非正常关闭或死机时会导致索引错误,需要使用myisamchk修复,而且当访问量大时出现非常频繁。
9、缓存
- 12台独立服务器(不是捐赠的)
- 28个实例
- 30GB总容量
- 90-93%的命中率(用过squid的人可能知道,squid内存加磁盘的命中率大概在70-80%)
- 没有完美的事物,缓存也有缺点:
- 增大开发量,需要针对缓存处理编写特殊的代码。
- 管理难度增加,需要更多人参与系统维护。
- 当然大内存也需要钱。
10、Web访问负载均衡
- 快,小,可管理的http web 服务器/代理
- 可以在内部进行转发
- 使用Perl开发
- 单线程,异步,基于事件,使用epoll , kqueue
- 支持Console管理与http远程管理,支持动态配置加载
- 多种模式:web服务器,反向代理,插件
- 支持插件:GIF/PNG互换?
11、MogileFS
- 文件属于类(类是最小的复制单位)
- 跟踪文件存储位置
- 在不同主机上存储
- 使用MySQL集群统一存储分布信息
- 大容易廉价磁盘