集群、负载均衡、分布式

2018-07-04 鲁鲁槟 收藏

一、高并发集群设计思路

01.png

①、负载均衡

  • 转发用户的请求到后端的服务器【平均分配:轮询】

  • 硬件:性能好、稳定、价格昂贵

  • 软件:性能还行、稳定也还行,免费

    lvs:【已经集成到linux2.6及内核】工作网络七层协议的第四层-网络层

    haproxy:工作网络七层协议的第四层-网络层

    nginx:工作网络七层协议的第七层-应用层,只能做 http 协议的负载均衡

②、SESSION 丢失

  • 在负载均衡中程序上的 SESSION 会出现丢失的问题?怎么解决?效果:登录成功之后,刷新一下显示登录,再刷新一下又未登录,再刷新又登录。一会登录一会未登录!

  • 解决办法:SESSION共享:【SESSION入库或SESSION存memcache】

③、mysql 主从数据库

  • 当向主服务器操作数据【insert,update,delete】,同样的数据会被自动复制到从服务器,也就是说从服务器是主服务器的一个镜像永远和主服务器上的数据一致

  • 程序上要实现读、写分离:程序当要写数据时写到主服务器,当读数据时从从服务器读。

④、反向代理

  • 用户请求数据时,反向代理先在本地找有没有缓存页面,如果有就直接返回,如果没有就到后端服务器请求数据,请求完之后缓存到本地,下次直接用这个缓存即可。【缓存时间和要缓存的页面都可配置】

  • 穿透:网站中有些页面不能缓存【购物车、搜索页等】,那么可以配置成穿透的行为直接访问后端不缓存这些页面。

  • 软件: squid:缓存到硬盘上、varnish【*】:缓存到内存中

  • 对于大流量的网站,您采用什么样的方法来解决访问量问题:squid 反向代理

⑤、高可用集群

  • 高可用【HA:high availiablity】:没有单点故障:集群中任何一台服务器出现故障整个系统依然能正常对外服务。(两台负载均衡AB,A备份B工作,当B坏了,A顶替)

  • 软件: heartbeat、keepalived

⑦、CDN(反向代理)

  • 内容分发网络:全世界各地搭建数据节点,用户访问网站时从离他最近的节点取数据,这样速度最快!只适合静态内容。

  • 建议:不要自己搭建,因为服务器节点太多维护成本较高。可以使用第三方的。

一、概念

1.1、集群(Cluster)

所谓集群是指一组独立的计算机系统构成的一个松耦合的多处理器系统,它们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送,实现分布式计算机。

通俗一点来说,就是让若干台计算机联合起来工作(服务),可以是并行的,也可以是做备份。

【集群指的是将几台服务器集中在一起,实现同一业务。】

1.2、负载均衡(Load Balance)

网络的负载均衡是一种动态均衡技术,常见的实现方式是通过一些工具实时地分析数据包,掌握网络中的数据流量状况,把任务合理均衡地分配出去。

这种技术基于现有网络结构,提供了一种扩展服务器带宽和增加服务器吞吐量的廉价有效的方法,加强了网络数据处理能力,提高了网络的灵活性和可用性。

日常生活中到处都能看到“负载均衡”,一个超市的收营员高峰期只能服务10位顾客,当做活动时有20位顾客需要服务的话可能就会排长队,这样购物体验将会很差(就像客户抱怨系统/网站访问太慢)。最简单的办法就是再招个营业员,重新开通一个出口。负载均衡的核心就是“分摊压力”。

【在现有网络结构之上,负载均衡提供了一种廉价有效的方法扩展服务器带宽和增加吞吐量,加强网络数据处理能力,提高网络的灵活性和可用性。】

1.3、分布式

【一个复杂业务分拆多个子业务,部署在不同的服务器上】

二、集群

2.1、大规模集群的特点

①、高可靠性(HA)

利用集群管理软件,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。

②、高性能计算(HP)

即充分利用集群中的每一台计算机的资源,实现复杂运算的并行处理,通常用于科学计算领域,比如基因分析、化学分析等。

③、负载平衡(LB)

即把负载压力根据某种算法合理分配到集群中的每一台计算机上,以减轻主服务器的压力,降低对主服务器的硬件和软件要求。

2.2、常用的集群

①、load balance cluster(负载均衡集群)

一共有四兄弟开裁缝铺,生意特别多,一个人做不下来,老是延误工期,于是四个兄弟商量:老大接订单, 三个兄弟来干活。 客户多起来之后,老大根据一定的原则(policy) 根据三兄弟手上的工作量来分派新任务。

②、High availability cluster(高可用集群)

两兄弟开早餐铺,生意不大,但是每天早上7点到9点之间客户很多并且不能中断。为了保证2个小时内这个早餐铺能够保证持续提供服务,两兄弟商量几个方法:

  • 方法一:平时老大做生意,老二这个时间段在家等候,一旦老大无法做生意了,老二就出来顶上,这个叫做 Active/Standby.(双机热备)

  • 方法二:平时老大做生意,老二这个时候就在旁边帮工,一旦老大无法做生意,老二就马上顶上,这个叫做Active/Passive.(双机双工)

  • 方法三:平时老大卖包子,老二也在旁边卖豆浆,老大有问题,老二就又卖包子,又卖豆浆,老二不行了,老大就又卖包子,又卖豆浆.这个叫做Active/Active (dual Active)(双机互备)

(包子= application package, 互相照应叫做heartbeat, 顶替对方工作叫做 failover/takeover. 如果两个兄弟突然都瞎了聋了,不知道现在对方到底是否正在干活,都认为自己要顶对方的工作,这个叫做brain-split, 然后需要第三者,比如他们的老爹来解决问题,这个叫做tier-breaker, 或者让他们两个的媳妇过来拉走其中一个,这个叫做fency。)

③、high computing clustering(高性能计算集群)

10个兄弟一起做手工家具生意,一个客户来找他们的老爹要求做一套非常复杂的仿古家具,一个人做也可以做,不过要做很久很久,为了1个星期就交出这一套家具,10个兄弟决定一起做。

老爹把这套家具的不同部分分开交给儿子们作,然后每个儿子都在做木制家具的加工,最后拼在一起叫货。

老爹是scheduler任务调度器,儿子们是compute node. 他们做的工作叫做作业。

(其实,还有一种,分布式存储相关的集群,应用于超大规模网站,云计算平台等等。涉及点存储方面的,这里就不介绍了)

三、实践

3.1、负载均衡中session共享的4种解决方案

①、问题

负载均衡时访问页面会把请求分发到不同的服务器,session是存在服务器端,如果首次访问被分发到A服务器,那么session就会被存到A服务器,再次访问时负载均衡会分发到B服务器那么第一次访问的session信息就会获取不到之前的session信息。从而导致数据的不一致。

②、解决方案

A、nginx或者haproxy做的负载均衡

用Nginx 做的负载均衡可以添加ip_hash这个配置, 用haproxy做的负载均衡可以用 balance source这个配置。 从而使同一个ip的请求发到同一台服务器。

B、利用数据库同步session

这种方案不可取,这样会加大数据库的访问压力。

C、利用cookie同步session数据

A服务器:

session_start();
if(isset($_SESSION["username"])){
    echo "ok you can go next";
}else if(isset($_COOKIE["username"])){
    echo "session is not in this server but cookie is exist";
    $_SESSION["username"]=$_COOKIE["username"];
}else{
    echo "cookie and session does\"t in this server";
    $_SESSION["username"]="lampol";
    setCookie("username","lampol",time()+30*24*60*60);
}
echo "this is A server";
var_dump($_SESSION);

B服务器:

echo "this is B server";

然后开始访问: 第一次访问发到B服务器 没有session和cookie数据 然后会存到session和本地cookie 刷新第二次访问分发到A服务器 session不存在但是cookie再本地存在 此时会把本地的cookie同步到B服务器中 缺点 如果禁用cookie那就完蛋了。

D、memcache或者redis存session(以memcache为例)

安装memcache及客户端和服务端,然后

ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "192.168.1.142:11211");

以上配置可以再php.ini中配置 这样就把session信息存到了memache中 (redis同理) 然后在运行

$mem = new Memcache;
$mem->connect("192.168.1.142",11211);
$id=session_id();
echo $mem->get($id);

本人自认为这种方案还是比较可取的。当然了到底用哪种方案,大家可以结合实际进行选择。

暂时还没有评论,快来抢沙发吧~

发表评论

您需要登录后才可以评论。登录 | 立即注册
阅读 870