对于一个需要处理高并发的系统而言,可以从多个层面去解决这个问题。
1、数据库系统:数据库系统可以采取集群策略以保证某台数据库服务器的宕机不会影响整个系统,并且通过负载均衡策略来降低每一台数据库服务器的压力(当然用一台服务器应付一般而言没啥问题,找一台当备机放着应付宕机就行,如果一台应付不了,那么再加一台,但是备机还是要的,至少一台),另外采取读/写分离的方法降低数据库负载,再加上分库和分表进一步降低数据库负载,从而可以从容地应对高并发问题。当然成本会比较高,毕竟要这么多服务器。
2、分布式缓存系统:建立分布式缓存系统是至关重要的,所有的读写都先进入缓存系统,然后由缓存系统来安排从数据库系统/源服务器的读写。比如读的话,要是找不到,则把数据从数据库中读出放入缓存系统里(同样的,把页面从源服务器中获取并保存在缓存服务器中),再读取给客户端;写的话,则先写入缓存,由缓存系统把数据异步提交到消息队列中,然后写入数据库里。缓存分为硬盘缓存和内存缓存,硬盘缓存更多地用来缓存页面和页面资源例如多媒体资源,而内存缓存更多地用来缓存数据库的数据和应用中的一些状态。硬盘缓存有Squid,内存缓存有Memcached,微软在.Net Framework 4.0推了个Velocity也是内存缓存。
3、监控系统:这么多服务器和系统,总归是需要监控的,不然出了问题排查起来会非常麻烦,所以上述系统在开发时也要考虑到监控这一块,做好日志记录,然后配合监控系统可以一下子查到问题根源。
4、前端系统:和数据库系统一样可以采用服务器集群和负载均衡,可以把各个服务细分然后注册到服务中心再分别部署到不同的服务器上即采用分布式服务的方式,还可以使用多线程,另外为了更好地用户体验,可以多用异步方式和客户端操作来显示数据或者执行操作,ajax,js等等可以派不少用处,此外,还可以使用网页静态化(这样不但降低了开销还会提高网页被搜索到的概率,.Net有URLRewrite可以做到,只需要引入dll并注册然后设置Rewrite的规则即可),还有图片等多媒体资源单独设置服务器与页面分离,使用镜像网站或者CDN技术(Content Delivery Network,智能镜像网站+缓存技术,让用户可以访问自己最近的镜像网站的缓存服务器中的缓存页面)
5、服务器CPU和IO的平衡:对于所有的服务器,都需要保证它们的CPU和IO保持平衡,如果失衡,需要查找原因,更改部署和配置以达到平衡。
对于一般的小型服务器,最佳线程数=CPU核的个数*2 + 2,当然这个只是经验之谈,实际公式比较复杂,为最佳线程数=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu核的数量。
memcached的存储结构是把内存划分成不同尺寸的内存块,并建立多个相同尺寸的内存块作为一个内存块群,存储的时候根据数据的实际大小选用最合适尺寸的内存块进行存储,这样子的缺点就是如果数据大小不是和内存块大小一致就会浪费一些内存,所以再设置内存块大小的时候要确保不同的尺寸之间的大小差距不要太大。
memcached不会删除保存的数据,它是在接收到获取命令时先检查下数据是否过期,如果过期就返回没有数据,然后标志下这个内存块可以被重新保存数据,当内存都被使用需要释放数据时,它会根据LRU(Least Recently Used)机制来释放内存块。
memcached不支持分布式,也就是说不同服务器上的memcached不会互相通信,所以对于使用多台memcached服务器,需要客户程序来把需要保存的数据分发到不同的memcached服务器上,分发的方法就是用key通过一个分发策略来确定需要发送的服务器,然后进行发送保存,获取时也用key通过相同的分发策略确定服务器并获取。如果某台memcached服务器发生故障,可以通过重新分配服务器的方法把数据保存到新的服务器上。