数据是如何存储的
发布时间:2025-05-19 17:55:51 发布人:远客网络
一、数据是如何存储的
转自网友文章:大型网站数据库优化
千万人同时访问的网站,一般是有很多个数据库同时工作,说明白一点就是数据库集群和并发控制,这样的网站实时性也是相对的。这些网站都有一些共同的特点:数据量大,在线人数多,并发请求多,pageview高,响应速度快。总结了一下各个大网站的架构,主要提高效率及稳定性的几个地方包括:1、程序
程序开发是一方面,系统架构设计(硬件+网络+软件)是另一方面。软件架构方面,做网站首先需要很多web服务器存储静态资源,比如图片、视频、静态页等,千万不要把静态资源和应用服务器放在一起。一个好的程序员写出来的程序会非常简洁、性能很好,一个初级程序员可能会犯很多低级错误,这也是影响网站性能的原因之一。
网站要做到效率高,不光是程序员的事情,数据库优化、程序优化这是必须的,在性能优化上要数据库和程序齐头并进!缓存也是两方面同时入手。第一,数据库缓存和数据库优化,这个由dba完成(而且这个有非常大的潜力可挖,只是由于我们都是程序员而忽略了他而已)。第二,程序上的优化,这个非常的有讲究,比如说重要一点就是要规范SQL语句,少用in多用or,多用preparestatement,另外避免程序冗余如查找数据少用双重循环等。另外选用优秀的开源框架加以支持,我个人认为中后台的支持是最最重要的,可以选取spring+ibatis。因为ibatis直接操作SQL并有缓存机制。spring的好处就不用我多说了,IOC的机制可以避免new对象,这样也节省开销。据我分析,绝大部分的开销就是在NEW的时候和连接数据库时候产生的,请尽量避免。另外可以用一些内存测试工具来做一个demo说明hibernate和ibatis谁更快!前台你想用什么就用什么,struts,webwork都成,如果觉得自己挺牛X可以试试用tapestry。用数据库也未必不能解决访问量巨大所带来的问题,作成静态文件硬盘的寻址时间也未必少于数据库的搜索时间,当然对资料的索引要下一翻工夫。我自己觉得门户往往也就是当天、热门的资料点击率较高,将其做缓存最多也不过1~2G的数据量吧,举个例子:◎拿网易新闻来说
格式化一下,方便理解:http://域名/年/月日/新闻所属分类/新闻ID.html
可以把当天发布的、热门的、流揽量大的作个缓寸,用hashtable(key:年-月-日-分类-ID,value:新闻对象),静态将其放到内存(速度绝对快过硬盘寻址静态页面)。通常是采用oracle存储过程+2个weblogic,更新机制也几乎一样每签发一条新闻,就会生成静态页面,然后发往前端的web服务器,前端的web都是做负载均衡的。另外还有定时的程序,每5-15分钟自动生成一次。在发布新闻的同时将数据缓存。当然缓存也不会越来越大,在个特定的时间段(如凌晨)剔除过期的数据。做一个大的网站远没有想象中那么简单,服务器基本就要百十个的。这样可以大大增加一台计算机的处理速度,如果一台机器处理不了,可以用httpserver集群来解决问题了。2、网络
中国的网络分南北电信和网通,访问的ip就要区分南北进入不同的网络。3、集群通常会使用CDN与GSBL与DNS负载均衡技术,每个地区一组前台服务器群,例如:网易,百度使用了DNS负载均衡技术,每个频道一组前台服务器,一搜使用了DNS负载技术,所有频道共用一组前台服务器集群。网站使用基于Linux集群的负载均衡,失败恢复,包括应用服务器和数据库服务器,基于linux-ha的服务状态检测及高可用化。
应用服务器集群可以采用apache+tomcat集群和weblogic集群等;web服务器集群可以用反向代理,也可以用NAT的方式,或者多域名解析都可以;Squid也可以,方法很多,可以根据情况选择。4、数据库因为是千万人同时访问的网站,所以一般是有很多个数据库同时工作的,说明白一点就是数据库集群和并发控制,数据分布到地理位置不同的数据中心,以免发生断电事故。另外还有一点的是,那些网站的静态化网页并不是真的,而是通过动态网页与静态网页网址交换做出现的假象,这可以用urlrewrite这样的开源网址映射器实现。这样的网站实时性也是相对的,因为在数据库复制数据的时候有一个过程,一般在技术上可以用到hibernate和ecache,但是如果要使网站工作地更好,可以使用EJB和websphere,weblogic这样大型的服务器来支持,并且要用oracle这样的大型数据库。
大型门户网站不建议使用Mysql数据库,除非你对Mysql数据的优化非常熟悉。Mysql数据库服务器的master-slave模式,利用数据库服务器在主从服务器间进行同步,应用只把数据写到主服务器,而读数据时则根据负载选择一台从服务器或者主服务器来读取,将数据按不同策略划分到不同的服务器(组)上,分散数据库压力。
大型网站要用oracle,数据方面操作尽量多用存储过程,绝对提升性能;同时要让DBA对数据库进行优化,优化后的数据库与没优化的有天壤之别;同时还可以扩展分布式数据库,以后这方面的研究会越来越多;如果我来设计一个海量数据库,可能首先考虑的就是平行扩容性,原因很简单,我没有办法预估将来的数据规模,那我也就没有边界可言,因此,基本上首选dbm类哈希型数据库,甚至,对于实时性要求很高的数据库,可能会自行设计库。当我们使用业务描述脚本、事务批处理机、目录服务、底层存取来划分一个数据库系统之后,其实,所谓的海量数据需求,也就不是那么难办到了。嗯,这样还有一个额外的好处,就是由于平行扩容性很好,因此,前期可以以较低成本搭建一个简单的架子,后期根据业务量逐出扩容。这对很多企业来说,就是入门门槛很低,便于操作,且商业风险也小。MySQL比起动辄几十万美金,搭建豪华的Oracle平台,成本低多了。
二、nginx负载均衡怎么访问数据库
nginx是一个轻量级的、高性能的 web server主要可以干两件事情:
1、直接作为http server(代替apache,对PHP需要FastCGI处理器支持);
2、作为反向代理服务器实现负载均衡
以下我们就来举例说明如何使用 nginx实现负载均衡。因为nginx在处理并发方面的优势,现在这个应用非常常见。当然了Apache的 mod_proxy和mod_cache结合使用也可以实现对多台app server的反向代理和负载均衡,但是在并发处理方面apache还是没有 nginx擅长。
a.我们本地是Windows系统,然后使用VirutalBox安装一个虚拟的Linux系统。
在本地的Windows系统上分别安装nginx(侦听8080端口)和apache(侦听80端口)。在虚拟的Linux系统上安装apache(侦听80端口)。
这样我们相当于拥有了1台nginx在前端作为反向代理服务器;后面有2台apache作为应用程序服务器(可以看作是小型的server cluster。;-));
b. nginx用来作为反向代理服务器,放置到两台apache之前,作为用户访问的入口;
nginx仅仅处理静态页面,动态的页面(php请求)统统都交付给后台的两台apache来处理。
也就是说,可以把我们网站的静态页面或者文件放置到nginx的目录下;动态的页面和数据库访问都保留到后台的apache服务器上。
c.如下介绍两种方法实现server cluster的负载均衡。
我们假设前端nginx(为127.0.0.1:80)仅仅包含一个静态页面index.html;
后台的两个apache服务器(分别为localhost:80和158.37.70.143:80),一台根目录放置phpMyAdmin文件夹和test.php(里面测试代码为print“server1“;),另一台根目录仅仅放置一个test.php(里面测试代码为 print“server2“;)。
a.在最简单地构建反向代理的时候(nginx仅仅处理静态不处理动态内容,动态内容交给后台的apache server来处理),我们具体的设置为:在nginx.conf中修改:
这样当客户端访问localhost:8080/index.html的时候,前端的nginx会自动进行响应;
当用户访问localhost:8080/test.php的时候(这个时候nginx目录下根本就没有该文件),但是通过上面的设置 location~\.php$(表示正则表达式匹配以.php结尾的文件,详情参看location是如何定义和匹配的),nginx服务器会自动pass给 158.37.70.143的apache服务器了。该服务器下的test.php就会被自动解析,然后将html的结果页面返回给nginx,然后 nginx进行显示(如果nginx使用memcached模块或者squid还可以支持缓存),输出结果为打印server2。
如上是最为简单的使用nginx做为反向代理服务器的例子;
b.我们现在对如上例子进行扩展,使其支持如上的两台服务器。
我们设置nginx.conf的server模块部分,将对应部分修改为:
上面第一个部分location ^~/phpMyAdmin/,表示不使用正则表达式匹配(^~),而是直接匹配,也就是如果客户端访问的 URL是以开头的话(本地的nginx目录下根本没有phpMyAdmin目录),nginx会自动pass到127.0.0.1:80的Apache服务器,该服务器对phpMyAdmin目录下的页面进行解析,然后将结果发送给nginx,后者显示;
如果客户端访问URL是的话,则会被pass到158.37.70.143:80的apache进行处理。
因此综上,我们实现了针对不同请求的负载均衡。
如果用户访问静态页面index.html,最前端的nginx直接进行响应;
如果用户访问test.php页面的话,158.37.70.143:80的Apache进行响应;
如果用户访问目录phpMyAdmin下的页面的话,127.0.0.1:80的Apache进行响应;
即用户访问这个同一页面的时候,我们实现两台服务器的负载均衡(实际情况中,这两个服务器上的数据要求同步一致,这里我们分别定义了打印server1和server2是为了进行辨认区别)。
a.现在我们的情况是在windows下nginx是localhost侦听8080端口;
两台apache,一台是127.0.0.1:80(包含test.php页面但是打印server1),另一台是虚拟机的158.37.70.143:80(包含test.php页面但是打印server2)。
首先在nginx的配置文件nginx.conf的http模块中添加,服务器集群server cluster(我们这里是两台)的定义:
表示这个server cluster包含2台服务器
〉然后在server模块中定义,负载均衡:
proxy_pass 这里的名字和上面的cluster的名字相同
proxy_ www.gzlij.comredirect off;
proxy_set_header X-Real-IP$remote_addr;
proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;
这样的话,如果访问页面的话,nginx目录下根本没有该文件,但是它会自动将其pass到myCluster定义的服务区机群中,分别由127.0.0.1:80;或者158.37.70.143:80;来做处理。
上面在定义upstream的时候每个server之后没有定义权重,表示两者均衡;如果希望某个更多响应的话例如:
综上,我们使用nginx的反向代理服务器reverse proxy server的功能,将其布置到多台apache server的前端。
nginx仅仅用来处理静态页面响应和动态请求的代理pass,后台的apache server作为app server来对前台pass过来的动态页面进行处理并返回给nginx。
通过以上的架构,我们可以实现nginx和多台apache构成的机群cluster的负载均衡。
1)可以在nginx中定义访问不同的内容,代理到不同的后台server;如上例子中的访问phpMyAdmin目录代理到第一台server上;访问test.php代理到第二台server上;
2)可以在nginx中定义访问同一页面,均衡(当然如果服务器性能不同可以定义权重来均衡)地代理到不同的后台server上。如上的例子访问test.php页面,会均衡地代理到server1或者server2上。
实际应用中,server1和server2上分别保留相同的app程序和数据,需要考虑两者的数据同步。