透过12306五大焦点看高性能高并发系统
幽云十八 发表于:12年02月20日 09:46 [转载] IT168
焦点四:软件层需要做哪些工作?
软件层将直接决定整个系统应对高并发的能力,其将应用服务器与数据库、存储结合成为一个有机的整体,使数据在这些IT设备之间传输,可以说软件层做得好与不好可能性能差异能达几倍到一个量级。那么在以高并发为前提的情况下,软件层要做什么呢?
百度首席架构师林仕鼎认为在解决请求尖峰时可采用threadpool或event-driven两种做法。这两种做法都需要自己维护请求队列,也带来了提高稳定性的可能性。简单地说,就是增加flow control机制,上游根据下游的负载做throttling,反馈可以有ack/poll等多种做法,有时需要由最下游一路反馈到最前端。并采用延迟截断,对于太老的请求,直接给出拒绝响应,让它在应用层重试。
4399架构师曹政则提供了更多更具体的方式,他认为可将存储key- value化,因为基本上查询都是直线式的,所以key-value就是很好的工具;因为出票可能需要找一下车次,座位,只能一一对应的查询就不好用;弄 个redis带个列表结构进去就可以了。春节放票总共多少张?又不是一次放出来,每张票对应一个key,一个value,能吃多少内存?后面跟个数据库做 同步,这点数据量对于现在的服务器来说根本不是问题。并且在注册登陆也可以在 mysql基础上弄个redis挂在前头响应以提高查询速度。
实际上,在12306在线购票系统中,查询操作是很常见,因为你需要查询车次,还需要查询余票。基于这点,曹政认为可将查询结果缓存化、静态化,这可通过两个步骤实现,起始地,目标地查询 - 常见查询目标(如北京到成都)全部预制缓存。非常见查询目标,基于第一次查询的结果缓存,这样查询车次基本上无压力。
查询有票状态就更简单了,因为票数只有有票,无票两个状态,某日某车次作为一个key-value类型存储(仍用redis即可)。某类车票发生从 有到无或从无到有的变化,才通知缓存更新。更新是后台通知的,而非基于用户查询。比如某车次硬卧票售完,通知一次更新,硬座售完,通知一次更新,软座售 完,通知一次更新。以此类推,这样的缓存更新次数极少。而且可以给前端返回甚至静态结果(基于查询条件生成静态结果,是个Seoer都会的,后台在票数变 化时通知更新,这样结构上就与前端查询无关了,而且一样可以保持实时性)。
最后还可对前端缓存进行处理来提高响应速度。可能大多数人都被10亿PV给吓到了,但实际上这里面有很大的水分,因为有很多可能是利用代码或者脚本 进行的自动刷新,自然而然就会产生较大的泡沫,而实际上绝对不会有那么多。基于这点,则可通过缓存来避免“爆机”,并且有例子证明,这样做的效果是能够应 对一小时20亿的刷新,12306的10亿刷新根本就不成问题。
当然,网上的各种关于软件层的建议还有很多很多,包括之前提到的云风的排队系统也应该属于软件层的内容,因为篇幅的原因,在此我们仅选取了几个较为典型的建议。