大型网站面临的问题:
- 海量数据处理
大型网站每天的数据量可能上百万,甚至上千万或更多。如果存在设计不好的多对多关系,在前期可能没有任何问题,但是随着用户增长,数据量会以几何级数增加。此时,对于一个表的select和update(还不用说多表联合查询)的成本是非常高的。
- 数据并发处理
死锁在高并发情况下存在的概率非常高,这时使用缓存仍是一个大问题。因为在整个应用范围下,缓存是全局共享的。当两个或者多个请求同时对缓存有更新要求时,尽管我们有lock机制,但并不是很灵验,应用程序还是会直接死掉。
- 文件存贮问题
当文件量是海量数据的情况下,那么维护和使用时,磁盘I/O就是一个巨大的问题,哪怕你的带宽足够,但是你的磁盘也未必响应得过来。如果这个时候还涉及上传,磁盘很容易就over了。
- 数据关系处理
在Web2.0时代,数据关系大多是多对多关系,涉及的大多是多表联合查询。如果避免是一个问题。
- 数据索引问题
索引和更新是一对矛盾。廉价的索引可能带来高代价的update。
- 分布式处理
为了保证各地的访问速度,如何有效实现数据同步和更新,实现各地服务器的实时通信是一个很大的问题。
- Ajax利弊
Ajax利用简单的post和get进行数据传递,采用HTTP debuger抓取数据,但存在攻击危险。
- 数据安全性
大型网站面临的危险主要有外挂、群发等,如采用验证码,对用户体验又是一个很意外的影响。
- 数据同步和集群处理
当数据库服务器不堪重负时,就需要做基于数据库的负载和集群了。这时可能会遇到最让人困扰的问题:根据数据库的设计不同,数据基于网络传输时会发生数据延迟。这是很可怕的问题,也不可避免。由此,我们就需要通过另外的手段来保证在这延迟的几秒或者更长时间内,实现有效的交互。比如数据散列、分割、内容、异步处理等问题。
- Open API以及数据共享
Open API已经成为不可避免的趋势,从google,facebook,myspace到海内、校内,都在考虑这个问题,它可以更有效地留住用户,并激发用户更多参与,让更多人帮助你做最有效的开发。
- 大量like,or,in以及多表查询带来的性能屏障
- 大量上传文件攻击
解决方案
把Web2.0网站用户量级别定为三种,百万级别(M)、千万级别(S)以及亿万级别(Q)。如果全表查询,可以采用分区视图、分表索引处理。
对于M级别来说,主要应对的是I/O问题:对数据库的file文件分磁盘存贮(不是分区,是不同的硬盘),根据负载量大小,我们可以适当控制硬盘的数量和文件分区的数量。对于S级别,需要对注册和入库的流程进行简单修改。解决方案是数据散列和分区视图。
常用的方案有三种。第一种是等容扩充法:在用户注册控制的基础上,保证每个库的用户容量不超过500万,超过之后入第二个库,以此类推。这个方案可以保证有效的扩充性,但不能保证数据被有效索引。第二种就是共区索引方案,其实和第一种方案有异曲同工之处。但是对第一种方案进行了合理的优化,按照用户名进行了分库存贮。如建立26个数据库,按照用户名的索引来控制用户数据入哪个库。假如用户名是crazycode,那该用户名的数据存放在用户表C中。方案三是一个更具模型化的方案,进行用户ID的编码。我们用一种序列化的方案将用户名以编码的形式存贮,如crazycode按照C,R,A,......存贮为数字索引,然后进行分区存贮。数字类型的数据在数据库中可以更有效地被查询、更新和共享,这就是结合方案一和方案二的方案三。
对于Q级别,可以根据用户活跃度的权值结合数据量进行临时数据表的存放。如果是在非意外的数据情况下,每天登录的用户量不会上千万。利用一个简单的数据代理程序,一个临时的用户验证数据库,每天执行一次批处理,将活跃度高的用户帐户撮到临时数据库中。查询的时候先查询临时库,如果没有,再进行全库查询。
一个更高级的查询方案——数据缓存服务,就是将最常用最直接的数据直接存放在缓存服务器中,而这个缓存服务器定时从主服务器获取并更新信息。更深入地,可以将缓存服务器做二次缓存,也就是一次性处理输入并存放到list数据中,作为全局变量放到内存中进行查询,同时用散列表或者数组进行数据索引,根据查询分布到各个变量中,直接从内在中读取数据。