在计算机领域,当单机性能达到瓶颈时,通常有两种方式解决性能问题,html
分布式系统有不少种:分布式文件系统、分布式数据库、分布式WebService、分布式计算等等,java
面向的情景不一样,但分布式的思路大体相同,万法归一吧!nginx
如下内容主要来自:分布式系统架构思想web
假设咱们有一台服务器,它能够承担1百万/秒的请求,这个请求能够的是:经过http访问网页、经过tcp下载文件、jdbc执行sql、RPC调用接口等等方式,如今咱们有一条数据的请求是2百万/秒,很显然服务器很难hold住,会各类拒绝访问,甚至宕机,怎么办呢?算法
一台机器解决不了的问题,那就两台。因此咱们加一台机器,每台承担1百万。若是请求继续增长呢,两台解决不了的问题,那就三台呗。这种方式咱们称之为水平扩展,若是实现请求的平均分配即是负载均衡了。sql
另外一个例子,咱们如今有两个数据请求,数据190万,数据280万,上面那台机器也hold不住,咱们加一台机器来负载均衡一下,每台机器处理45万数据1和40万数据2,可是平分太麻烦,不如一台处理数据1,一台处理数据2,一样能解决问题,这种方式咱们称之为垂直拆分。数据库
水平扩展和垂直拆分是分布式架构的两种思路,但并非一个二选一的问题,更多的是兼并合用。下面介绍一个实际的场景。这也是许多互联网的公司架构思路。编程
某些公司的计算机系统非常庞大,天然是一个整的分布式系统,为了方便组织管理,公司将整个技术部按业务和平台拆分为部门:订单的、会员的、商家的等等,而每一个部门有本身的web服务器集群、数据库服务器集群,缓存
经过同一个网站访问的连接可能来自于不一样的服务器和数据库,对网站及底层对数据库的访问被分配到了不一样的服务器集群,这个即是典型的按业务作的垂直拆分,每一个部门的服务器在hold不住时,会有弹性的扩展,这即是水平扩展。服务器
在数据库层,有些表很是大,数据量在亿级,若是只是纯粹的水平的扩展并不必定最好,
若是对表进行拆分,好比能够按用户id进行水平拆表,经过对id取模的方式,将用户划分到多张表中,同时这些表也能够处在不一样的服务器。
按业务的垂直拆库 和 按用户水平拆表 是分布式数据库中通用的解决方案。
前面咱们谈到了分布式来解决性能问题,但其附带的问题是怎么分布,即如何负载均衡。这里要解决的问题是当客户端请求时,应该让它请求分布式系统中哪一台服务器,一般的作法是经过一台中间服务器来给客服端分配目标服务器。
这里一样拿两个不一样的分布式系统作说明,
下图左边 是分布式文件系统FastDFS,
下图右边 是一个用于分布式的RPC中间件。
其中tracker即是负载均衡服务器,storage是存储文件和处理上传下载请求的服务器。
zookeeper是分布式系统中一个负载均衡框架,google的chubby的一个开源实现,是Hadoop和Hbase的重要组件。
一样的在http中,常据说的nginx也是一个负载均衡服务器,它面向的是分布式web服务器。
分布式系统中,解决了负载均衡的问题后,另一个问题就是数据的一致性了,这个就须要经过同步来保障。根据不一样的场景和需求,同步的方式也是有选择的。
在分布式文件系统中,好比商品页面的图片,若是进行了修改,同步要求并不高,就算有数秒甚至数分钟的延迟都是能够接受的,由于通常不会产生损失性的影响,所以能够简单的经过文件修改的时间戳,隔必定时间扫描同步一次,能够牺牲一致性来提升效率。
但银行中的分布式数据库就不同了,一丁点不一样步就是没法接受的,甚至能够经过加锁等牺牲性能的方式来保障彻底的一致。
在一致性算法中paxos算法是公认的最好的算法,chubby、zookeeper中paxos是它保证一致性的核心。
高并发,简言之:短期,大量请求。
如下内容主要来源于:java系统高并发解决方案(转载)
----------------------------------------------------------------------------
并发反映的是同时有多少许,好比互联网上的在线直播,可能有几万人须要同时访问服务器,这就是并发。
而分布是将任务分发到不一样的点上去,通常分布式最多的就是分布式计算。经过某种分布式编程方式,在不一样的系统上利用各自的CPU,内存等进行计算,将结果聚集至控制中心,进行处理。
大型网站,好比门户网站。在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:
以上的几个方面在必定程度上意味着更大的投入,会常常遇到瓶颈,没有很好的扩展性,因此还无法根本解决大型网站面临的高负载和高并发问题。
下面我从低成本、高性能和高扩张性的角度的一些经验:
首先是数据库,这是大多数应用所面临的首个SPOF【single point of failure 单一故障点】。
经常使用的优化措施是M-S(主-从)方式进行同步复制,将查询和操做和分别在不一样的服务器上进行操做。
推荐的是M-M-Slaves方式,2个主Mysql,多个Slaves,须要注意的是,虽然有2个Master,可是同时只有1个是Active,咱们能够在必定时候切换。之因此用2个M,是保证M不会又成为系统的SPOF。
Slaves能够进一步负载均衡,能够结合LVS,从而将select操做适当的平衡到不一样的slaves上。
以上架构能够抗衡到必定量的负载,可是随着用户进一步增长,你的用户表数据超过1千万,这时那个M变成了SPOF。你不能任意扩充Slaves,不然复制同步的开销将直线上升,怎么办?个人方法是表分区,从业务层面上进行分区。最简单的,以用户数据为例。根据必定的切分方式,好比id,切分到不一样的数据库集群去。
全局数据库用于meta数据的查询。缺点是每次查询,会增长一次,好比你要查一个用户nightsailer,你首先要到全局数据库群找到nightsailer对应的cluster id,而后再到指定的cluster找到nightsailer的实际数据。每一个cluster能够用m-m方式,或者m-m-slaves方式。这是一个能够扩展的结构,随着负载的增长,你能够简单的增长新的cluster进去。
2.2.二、高并发高负载网站的系统架构之HTML静态化
其实你们都知道,效率最高、消耗最小的就是纯静态页面,因此咱们尽量使咱们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。可是对于大量内容而且频繁更新的网站,咱们没法所有手动去挨个实现,因而出现了咱们常见的信息发布系统CMS,像咱们常访问的各个门户站点 的新闻频道,甚至他们的其余频道,都是经过信息发布系统来管理和实现的,信息发布系统能够实现最简单的信息录入自动生成静态页面,还能具有频道管理、权限 管理、自动抓取等功能,对于一个大型网站来讲,拥有一套高效、可管理的CMS是必不可少的。
同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询可是内容更新很小的应用,能够考虑使用html静态化来实现,好比论坛 中论坛的公用设置信息,这些信息目前的主流论坛均可以进行后台管理而且存储再数据库中,这些信息其实大量被前台程序调用,可是更新频率很小,能够考虑将这 部份内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求高并发。
网站HTML静态化解决方案
当一个Servlet资源请求到达WEB服务器以后咱们会填充指定的JSP页面来响应请求:
HTTP请求---Web服务器---Servlet--业务逻辑处理--访问数据--填充JSP--响应请求
HTML静态化以后:
HTTP请求---Web服务器---Servlet--HTML--响应请求
2.2.三、高并发高负载类网站关注点之缓存、负载均衡、存储
2.2.四、高并发高负载网站的系统架构之图片服务器分离
你们知道,对于Web 服务器来讲,无论是Apache、IIS仍是其余容器,图片是最消耗资源的,因而咱们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至不少台图片服务器。这样的架构能够下降提供页面访问请求的服务器系统压力,而且能够保证系统不会由于图片问题而崩溃。
2.2.五、高并发高负载网站的系统架构之数据库集群和库表散列
大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快没法知足应用,因而咱们须要使用数据库集群或者库表散列。
在数据库集群方面,不少数据库都有本身的解决方案,Oracle、Sybase等都有很好的方案,经常使用的MySQL提供的Master/Slave也是相似的方案,您使用了什么样的DB,就参考相应的解决方案来实施便可。
上面提到的数据库集群因为在架构、成本、扩张性方面都会受到所采用DB类型的限制,因而咱们须要从应用程序的角度来考虑改善系统架构,库表散列是经常使用而且最有效的解决方案。咱们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不一样的模块对应不一样的数据库或者表,再按照必定的策略对某个页面或者 功能进行更小的数据库散列,好比用户表,按照用户ID进行表散列,这样就可以低成本的提高系统的性能而且有很好的扩展性。
------------------------------------------------------------------------------
多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。
具备多线程能力的计算机因有硬件支持而可以在同一时间执行多于一个线程,进而提高总体处理性能。
关于Java中线程的生命周期,首先看一下下面这张较为经典的图:
上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌握了。