cluster处理,实战体验几种MySQLCluster方案_MySQL
cluster处理,实战体验几种MySQLCluster方案_MySQL详细介绍
本文目录一览: 怎么用stata同时做时间和行业的cluster处理
SE/Robust
vce(vcetype) vcetype may be conventional, robust, cluster clustvar, bootstrap, or jackknife
一般是用来产生稳健标准误的
常见是这样使用,vce(cluster,id),id是截面识别符
Cluster的功能是什么
cluster的功能就是当一台电脑当机了,cluster另外一个节点就会自动启用,一般用在服务器上,即实现热切换功能,保证服务不中断
Cluster群集一般来讲有四个功能
1. 冗余功能,就是说在这个群集中的任何一台机器出现本机或网络故障时,整个网络仍不中断,对外的服务也不中断,网络有多个路线可以走,服务器也可以相互代替。
2.负载均衡,就是当网络流量很大时。少量的服务器可能响应不过来,这时需要多台服务器为其分担处理。打个比方:一台IA服务器的处理能力是每秒几万个,显然无法在一秒钟内处理几十万个请求,但如果我们能够有10台这样的服务器组成一个系统,如果有办法将所有的请求平均分配到所有的服务器,那么这个系统就拥有了每秒处理几十万个请求的能力。
3. 协商处理,这种方案的原理是客户请求会同时被所有的节点所接收,然后所有节点按照一定的规则协商决定由哪个节点处理这个请求。此种方案中比较显著的特点就是整个集群中没有显著的管理节点,所有决定由全体工作节点共同协商作出。
4。流量分发,原理是所有的用户请求首先到达集群的管理节点,管理节点可以根据所有服务节点的处理能力和现状来决定将这个请求分发给某个服务节点。当某个服务节点由于硬件或软件原因故障时,管理节点能够自动检测到并停止向这个服务节点分发流量。这样,既通过将流量分担而增加了整个系统的性能和处理能力,又可以很好的提高系统的可用性。
nodejs实现多进程(cluster 模式)
Nodejs的主进程是单线程的,但它有多线程处理方案(更准备来说是多进程方案),即主进程开启不同的子进程,主进程接收所有请求,然后将分发给其它不同的nodejs子进程处理。
它一般有两种实现:
Nodejs 的 cluster模式 用的就是第一种实现,它使用一个主线程 master 和多个子线程 worker ,形成一个集群,通过主线程来向子线程分发请求。cluster 实现了对 child_process 的封装,通过 fork 方法创建子进程的方式实现了多进程模型。
http 和 cluster 、 process 都是 nodejs 的内置模块,不需要额外安装
实现过程大概是这样的: cluster 模块应用 child_process 来创建子进程,子进程通过复写掉 cluster._getServer 方法,从而在 server.listen 来保证只有主进程监听端口,主子进程通过 IPC 进行通信,其次主进程根据平台或者协议不同,应用两种不同模块( round_robin_handle.js 和 shared_handle.js )进行请求分发给子进程处理。
PM2是后台进程管理器,是多进程方案的一个成熟应用,可以帮助管理和保持应用程序在线。
全局安装: npm install pm2@latest -g
它的使用也非常简单:
PM2对nodejs应用,可以根据系统自动实现负载均衡: pm2 start http-server.js -i max
我们肯定不想每次启动时,都要手动输入一堆指令,所以我们可以将这些配置统一使用配置文件来管理,注意js文件名必须是 xxx.config.js ,我这里用 ecosystem.config.js :
apps 数组中,可以放置多个对象,对应多个文件执行不同的配置
执行配置: pm2 start ecosystem.config.js --env dev
可以看到在启动后,桌面上生成了流水和错误日志:
在express中使用集群cluster
我们知道node是单进程的,但实际上目前cpu都是多核的,单进程只能跑一个核,这样cpu资源就没有得到充分利用。 cluster是一个node内置的集群模块,可以用于多进程管理。cluster非常好用,它大大减轻了我们多进程开发的难度,让我们可以轻松构建一个负载均衡集群。
express框架比较常用,我们可以在它下面集成cluster,使其拥有多进程的功能:
我的电脑是4核的,因此会fork出4个子进程,这个www文件会被执行5次,因为要构建5个进程: 1个主进程,4个子进程 。 这样做的好处是——主进程master只负责管理worker子进程,不直接参与业务处理。 给大家做个形象的比喻: 多进程模式下,master是主人,worker是工人。主人拿着皮鞭专门管理一群工人干活,看到哪个不干活(worker挂掉)就一鞭子抽过去(重启worker),主人会活的很好(master不会挂);而单进程模式就是主人亲自干活,一不小心自己也挂了(未捕获异常搞死进程),那就真起不来了。 当然,这只是一个比喻。实际上,哪个worker挂掉后,master并不会自动重启它,但master会接收到一个通知exit,我们可以新fork一个进程即可。 下面我们就来测试一下: 当我们访问网页,究竟是哪个worker给我们处理呢? 我们在express的首页index加上worker的监听信息:
用命令行模拟测试:
有mac电脑的同学可以打开命令行工具,输入命令top:
这是个linux命令,可以实时监控主机的进程。 寻找一下node进程,然后找到其中一个进程id,强制杀死它,看看进程是否自动重建了?
我们在写js时,用到最多的还是回调函数,而回调函数因其延迟执行的特性,有时确实会有些隐蔽的、会导致进程挂掉的高风险bug没被发现,这时,即使我们开了worker子进程,这些危险的bug仍会轮番攻击worker,导致exit事件频繁发生。 为保护进程的安全,我们需要捕获这些未知的危险bug,通过打印错误堆栈分析出错误原因,并及时修正。
多进程必然带来数据共享问题,比如session。 假如你在登录时是worker1帮你处理的,session也会记录在worker1下面,而当你去购物车下单时,可能就分配到worker2去了,worker2下面没有session,因此判断你没登录,提醒你去登录。 这样就出问题了,怎么办呢? 我们可以用mysql或redis来搞定,因为这二者都是独立于node进程之外的。 mysql是用表来记录session,而redis是共享内存,实战中redis使用的更普遍一些。 如果只是普通的数据,也可以用file做数据共享,这就看你的具体需求了。
什么是cluster技术
什么是集群(Cluster)技术
Cluster集群技术可如下定义:一组相互独立的服务器在网络中表现为单一的系统,并以单一系统的模式加以管理。此单一系统为客户工作站提供高可*性的服务。大多数模式下,集群中所有的计算机拥有一个共同的名称,集群内任一系统上运行的服务可被所有的网络客户所使用。Cluster必须可以协调管理各分离的组件的错误和失败,并可透明地向Cluster中加入组件。一个Cluster包含多台(至少二台)拥有共享数据存储空间的服务器。任何一台服务器运行一个应用时,应用数据被存储在共享的数据空间内。每台服务器的操作系统和应用
程序文件存储在其各自的本地储存空间上。Cluster内各节点服务器通过一内部局域网相互通讯。当一台节点服务器发生故障时,这台服务器上所运行的应用程序将在另一节点服务器上被自动接管。当一个应用服务发生故障时,应用服务将被重新启动或被另一台服务器接管。当以上的任一故障发生时,客户都将能很快连接到新的应用服务上.
中文叫集群。就是将多台计算机或是虚拟主机组织在一起,如同一台机器,共同完成一个应用。用软件或是硬件都能实现,其目的主要有三:负载均衡、高可用性以及科学计算
负载均衡是说将大量请求按预先设定好的权值分发到各个计算机上,适用于大访问量的应用
高可用性是说多台计算机为一台或多台计算机做备份工作,一旦死机马上有另外一台或多台继续工作。比如银行、电信的系统就要求每年99.99%无死机率,就要使用这个技术
科学计算是指将复杂的计算拆成很多步,分散到不同的计算机进行计算达到省时的目的。比如梦工厂在制作电脑动画时,或是进行大规模科学计算时
最后,我要说的是这三种集群的配置方法不同,而且可以结合使用。
Cluster技术发展多年了,但其实并没有一个非常准确的定义和分类,不同的人有不同的理解。
其实,叫什么无所谓,只要能够对用户有益就可以了. 🙂
就个人理解而言,cluster有以下几种,当然前面说过,不同的人有不同的理解,大家可以充分讨论。我的这些分类更偏重于工程而不是技术性。
1. HA集群
实现高可用性,但对单个应用性能没有提高,市场上大部分产品都是属于这类,技术上也较简单。
2. IP负载均衡集群
利用IP技术实现对通用IP应用的支持。这种技术并不是很新,最早是在硬件上面采用的,Linux出现后才有了很多纯软件的模式,这也是open source带来的好处吧
3.并行计算集群
包括了一些象PVM,beowulf这样的信息传递机制和API库,也有任务调度产品,当然技术上最难的是并行编译/并行系统等更智能化的产品
4.应用负载均衡集群
虽然cluster的最高目的是实现真正的与应用程序无关的动态负载均衡,但由于技术上的限制,现在都只能在特殊的应用中实现,需要修改应用程序,所以并没有通用产品,大多是厂商有自己的并行版本。例如oracle paraller server.
以上基本是按照工程或者说产品的角度划分的,和技术上划分应该有一定区别。
下面是一篇很早以前写的东西,当时是为了媒体宣传写的,有一些商业味道在里面,有些地方技术上也不完全正确。现在给大家附上是想交换一下观点。并不是宣传Turbolinux公司的产品(本人是Turbolinux员工),确实是实在懒得改了,虽然这种商业性文章在公共社区里发表犯了大忌。只是供大家参考,关于Turbolinux产品优劣不参与讨论。请大家理解。
一直是不参与linux社区讨论的,这次是因为对cluster接触了比较长的时间,已经有了很大的兴趣,所以注册了来灌水。
随着Internet/Intranet应用的日益广泛,计算机系统的重要性也日益上升。低故障率和高性能向来是人们追求的主要目标,但对于单台服务器来讲,这两个问题是无法解决的。
l 可用性——很多服务器都宣称已经达到了99%的可用性。这个数字意味着什么呢?也就是说每年会有1%的非预计停机时间,让我们来具体算一下。 365(天 / 年)× 24(小时 / 天) × 1% = 87.6 (小时 / 年)。这每年87.6小时的停机时间对于要求24×7连续服务的企业来说简直就是灾难。
l 高性能——假设一般的桌面机每秒能够处理几千个请求,而IA服务器每秒能够处理几万个请求。那么对于需要每秒处理几十万个请求的企业来说,如果不采用集群技术,唯一的选择就是购买更加高档的中、小型计算机。如果这样做,虽然系统性能只提高了十倍,但其购买价格和维护费用就将会上升几十倍甚至更多。
集群技术的出现和发展则很好的解决了这两个问题。
一.集群
集群就是由一些互相连接在一起的计算机构成的一个并行或分布式系统,从外部来看,它们仅仅是一个系统,对外提供统一的服务。
集群技术本身有很多种分类,市场上的产品也很多,都没有很标准的定义。一般可以分为以下几种:
1. 基于冗余的集群
严格来讲,这种冗余系统并不能叫做真正的集群,因为它只能够提高系统的可用性,却无法提高系统的整体性能。
有以下几种类型。
A. 容错机
特点是在一台机器内部对其所有的硬件部件都进行冗余(包括硬盘、控制卡、总线、电源等等)。
能够基本做到与软件系统无关,而且可实现无缝切换,但价格极其昂贵。
典型市场产品:Compaq NonStop(Tandem),Micron(NetFrame),Straus
B. 基于系统镜像的双机系统
特点是利用双机,将系统的数据和运行状态(包括内存中的数据)进行镜像,从而实现热备份的目的。
能够做到无缝切换,但因为采用软件控制,占用系统资源较大,而且由于两台机器需要完全一样的配置,所以性能价格比太低。
典型市场产品:Novell SFT III,Marathon Endurance 4000 for NT
C. 基于系统切换的双机系统
特点是利用双机,将系统的数据(仅指硬盘数据)进行镜像,在主机失效的情况下从机将进行系统一级的切换。
性能价格比适中,但无法实现无缝切换。
典型市场产品:Legato(Vinca) StandbyServer for NetWare,Savoir(WesternMicro)SavWareHA(Sentinel),Compaq StandbyServer
2. 基于应用程序切换的集群
特点是当集群中的某个节点故障时,其它节点可以进行应用程序一级的切换,所以所有节点在正常状态下都可以对外提供自己的服务,也被成为静态的负载均衡方式。
性能价格比高,但也无法实现无缝切换,而且对单个应用程序本身无法做到负载均衡。
典型市场产品:Legato(Vinca) Co-StandbyServer for NT,Novell HA Server,Microsoft Cluster Server,DEC Cluster for NT,Legato Octopus,Legato FullTime,NeoHigh Rose HA,SUN Clusters, Veritas Cluster Server (FirstWatch),CA SurvivIT,1776
3. 基于并行计算的集群
主要应用于科学计算、大任务量的计算等环境。有并行编译、进程通讯、任务分发等多种实现方法。
典型市场产品:TurboLinux enFuzion,Beowulf,Supercomputer Architectures,Platform
4. 基于动态负载均衡的集群
所有节点对外提供相同的服务,这样可以实现对单个应用程序的负载均衡,而且同时提供了高可用性。
性能价格比极高,但目前无法支持数据库。
典型市场产品:TurboCluster Server,Linux Virtual Server,F5 BigIP,Microsoft Windows NT Load Balance Service
二.负载均衡
负载均衡是提高系统性能的一种前沿技术。还是沿用前面的例子,一台IA服务器的处理能力是每秒几万个,显然无法在一秒钟内处理几十万个请求,但如果我们能够有10台这样的服务器组成一个系统,如果有办法将所有的请求平均分配到所有的服务器,那么这个系统就拥有了每秒处理几十万个请求的能力。这就是负载均衡的基本思想。
实际上,目前市场上有多家厂商的负载均衡产品。由于其应用的主要技术的不同,也就有着不同的特点和不同的性能。
1.轮询DNS
轮询DNS方案可以说是技术上最简单也最直观的一种方案。当然,这种方案只能够实现负载均衡的功能,却无法实现对高可用性的保证。
它的原理是在DNS服务器中设定对同一个Internet主机名的多个IP地址的映射。这样,在DNS收到查询主机名的请求时,会循环的将所有对应的IP地址逐个返回。这样,就能够将不同的客户端连接定位到不同的IP主机上,也就能够实现比较简单的负载均衡功能。但是,这种方案有两个比较致命的缺点:
l 只能够实现对基于Internet主机名请求的负载均衡,如果是直接基于IP地址的请求则无能为力。
l 在集群内有节点发生故障的情况下,DNS服务器仍会将这个节点的IP地址返回给查询方,也就仍会不断的有客户请求试图与已故障的节电建立连接。这种情况下,即使你手工修改DNS服务器的对应设置,将故障的IP地址删除,由于Internet上所有的DNS服务器都有缓存机制,仍会有成千上万的客户端连接不到集群,除非等到所有的DNS缓存都超时。
2.硬件解决方案
有些厂商提供对负载均衡的硬件解决方案,制造出带有NAT(网络地址转换)功能的高档路由器或交换机来实现负载均衡功能。NAT本身的原理就是实现多个私有IP地址对单个公共IP地址的转换。代表产品是Cicso公司和Alteon公司的某些高档硬件交换机系列。这种方案有如下缺点:
l 由于采用了特殊的硬件,使得整个系统中存在非工业标准部件,极大的影响系统的扩充和维护、升级工作。
l 价格极其昂贵,和软件的解决方案根本是数量级上的差别。
l 一般只能实现对节点系统一级的状态检查,无法细化到服务一级的检查。
l 由于采用NAT机制,集群管理节点本身要完成的工作量很大,很容易成为整个系统的瓶颈。
l 此特殊硬件本身就是单一故障点。
l 实现异地节点的集群非常困难。
3.协商式处理(并行过滤)
这种方案的原理是客户请求会同时被所有的节点所接收,然后所有节点按照一定的规则协商决定由哪个节点处理这个请求。此种方案中比较显著的特点就是整个集群中没有显著的管理节点,所有决定由全体工作节点共同协商作出。代表产品是Microsoft公司的Microsoft Load Balancing Service这种方案的特点是:
l 由于各节点间要进行的通讯量太大,加重了网络的负担,一般需要增加节点通讯的专用网络,也就加大了安装和维护的难度和费用。
l 由于每个节点都要接收所有的客户请求并进行分析,极大的加大了网络驱动层的负担,也就减低了节点本身的工作效率,同时也时网络驱动层很容易成为节点系统的瓶颈。
l 由于要更改网络驱动层的程序,所以并不是一个通用的方案,只能够实现对特殊平台的支持。
l 在小量节点的情况下协商的效率还可以接受,一旦节点数量增加,通讯和协商将变得异常复杂和低效,整个系统的性能会有非线性的大幅度下降。所以此类方案,一般在理论上也只允许最多十几个的节点。
l 无法实现异地节点的集群。
l 由于集群内没有统一的管理者,所以可能出现混乱的异常现象。
4.流量分发
流量分发的原理是所有的用户请求首先到达集群的管理节点,管理节点可以根据所有服务节点的处理能力和现状来决定将这个请求分发给某个服务节点。当某个服务节点由于硬件或软件原因故障时,管理节点能够自动检测到并停止向这个服务节点分发流量。这样,既通过将流量分担而增加了整个系统的性能和处理能力,又可以很好的提高系统的可用性。
通过将管理节点本身做一个子集群可以消除由于管理节点自身的单一性带来的单一故障点。有些传统技术人员认为,因为所有的客户流量都将通过管理节点,所以管理节点很容易成为整个系统的瓶颈。但TurboCluster Server通过先进的直接路由或IP隧道转发机制巧妙的解决了问题。使得所有对客户响应的流量都由服务节点直接返回给客户端,而并不需要再次通过管理节点。众所周知,对于服务提供商而言,进入的流量要远远小于流出的流量,所以管理节点本身将不再是瓶颈。
流量分发的具体实现方法有直接路由、IP隧道和网络地址转换三种方法。TurboCluster Server目前支持效率最高的前两种。由于这种先进的结构和技术,使得TurboCluster Server集群内的服务节点数并没有上限,而且对大量节点的协同工作的效率也能够非常好的保证。
三.市场前景
集群技术已经发展了多年,其中的分支也非常多。目前集群技术正逐渐走向分层结构,以后也肯定会有专门用户前端、后端的集群产品出现。
随着计算机应用地位的逐渐提升,系统安全和重要性的日益增加,集群技术必将会有着极为广阔的应用前景。
实战体验几种MySQLCluster方案_MySQL
1.背景MySQL的cluster方案有很多官方和第三方的选择,选择多就是一种烦恼,因此,我们考虑MySQL数据库满足下三点需求,考察市面上可行的解决方案:高可用性:主服务器故障后可自动切换到后备服务器可伸缩性:可方便通过脚本增加DB服务器负载均衡:支持手动把某公司的数据请求切换到另外的服务器,可配置哪些公司的数据服务访问哪个服务器需要选用一种方案满足以上需求。在MySQL官方网站上参考了几种解决方案的优缺点:综合考虑,决定采用MySQL Fabric和MySQL Cluster方案,以及另外一种较成熟的集群方案Galera Cluster进行预研。2.MySQLCluster简介:MySQL Cluster 是MySQL 官方集群部署方案,它的历史较久。支持通过自动分片支持读写扩展,通过实时备份冗余数据,是可用性最高的方案,声称可做到99.999%的可用性。架构及实现原理:MySQL cluster主要由三种类型的服务组成:NDB Management Server:管理服务器主要用于管理cluster中的其他类型节点(Data Node和SQL Node),通过它可以配置Node信息,启动和停止Node。 SQL Node:在MySQL Cluster中,一个SQL Node就是一个使用NDB引擎的mysql server进程,用于供外部应用提供集群数据的访问入口。Data Node:用于存储集群数据;系统会尽量将数据放在内存中。缺点及限制:对需要进行分片的表需要修改引擎Innodb为NDB,不需要分片的可以不修改。NDB的事务隔离级别只支持Read Committed,即一个事务在提交前,查询不到在事务内所做的修改;而Innodb支持所有的事务隔离级别,默认使用Repeatable Read,不存在这个问题。外键支持:虽然最新的Cluster版本已经支持外键,但性能有问题(因为外键所关联的记录可能在别的分片节点中),所以建议去掉所有外键。Data Node节点数据会被尽量放在内存中,对内存要求大。数据库系统提供了四种事务隔离级别:A.Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新(事务执行的时候不允许别的事务并发执行。事务串行化执行,事务只能一个接着一个地执行,而不能并发执行。)。B.Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。C.Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。D.Read Uncommitted(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。3.MySQL Fabric简介:为了实现和方便管理MySQL 分片以及实现高可用部署,Oracle在2014年5月推出了一套为各方寄予厚望的MySQL产品 -- MySQL Fabric, 用来管理MySQL 服务,提供扩展性和容易使用的系统,Fabric当前实现了两个特性:高可用和使用数据分片实现可扩展性和负载均衡,这两个特性能单独使用或结合使用。MySQL Fabric 使用了一系列的python脚本实现。应用案例:由于该方案在去年才推出,目前在网上暂时没搜索到有大公司的应用案例。架构及实现原理:Fabric支持实现高可用性的架构图如下:Fabric使用HA组实现高可用性,其中一台是主服务器,其他是备份服务器, 备份服务器通过同步复制实现数据冗余。应用程序使用特定的驱动,连接到Fabric 的Connector组件,当主服务器发生故障后,Connector自动升级其中一个备份服务器为主服务器,应用程序无需修改。Fabric支持可扩展性及负载均衡的架构如下:使用多个HA 组实现分片,每个组之间分担不同的分片数据(组内的数据是冗余的,这个在高可用性中已经提到)应用程序只需向connector发送query和insert等语句,Connector通过MasterGroup自动分配这些数据到各个组,或从各个组中组合符合条件的数据,返回给应用程序。缺点及限制:影响比较大的两个限制是:自增长键不能作为分片的键;事务及查询只支持在同一个分片内,事务中更新的数据不能跨分片,查询语句返回的数据也不能跨分片。测试高可用性服务器架构: 功能 IP Port Backing store(保存各服务器配置信息) 200.200.168.24 3306 Fabric 管理进程(Connector) 200.200.168.24 32274 HA Group 1 -- Master 200.200.168.23 3306 HA Group 1 -- Slave 200.200.168.25 3306 安装过程省略,下面讲述如何设置高可用组、添加备份服务器等过程首先,创建高可用组,例如组名group_id-1,命令:mysqlfabric group create group_id-1往组内group_id-1添加机器200.200.168.25和200.200.168.23:mysqlfabric group add group_id-1 200.200.168.25:3306mysqlfabric group add group_id-1 200.200.168.23:3306然后查看组内机器状态:由于未设置主服务器,两个服务的状态都是SECONDARY提升其中一个为主服务器:mysqlfabric group promote group_id-1 --slave_id 00f9831f-d602-11e3-b65e-0800271119cb然后再查看状态:设置成主服务器的服务已经变成Primary。另外,mode属性表示该服务器是可读写(READ_WRITE),或只读(READ_ONLY),只读表示可以分摊查询数据的压力;只有主服务器能设置成可读写(READ_WRITE)。这时检查25服务器的slave状态:可以看到它的主服务器已经指向23然后激活故障自动切换功能:mysqlfabric group activate group_id-1激活后即可测试服务的高可以性首先,进行状态测试:停止主服务器23然后查看状态:可以看到,这时将25自动提升为主服务器。但如果将23恢复起来后,需要手动重新设置23为主服务器。实时性测试:目的:测试在主服务更新数据后,备份服务器多久才显示这些数据测试案例:使用java代码建连接,往某张表插入100条记录,看备份服务器多久才能同步这100条数据测试结果:表中原来有101条数据,运行程序后,查看主服务器的数据条数:可见主服务器当然立即得到更新。查看备份服务器的数据条数:但备份服务器等待了1-2分钟才同步完成(可以看到fabric使用的是异步复制,这是默认方式,性能较好,主服务器不用等待备份服务器返回,但同步速度较慢)对于从服务器同步数据稳定性问题,有以下解决方案:使用半同步加强数据一致性:异步复制能提供较好的性能,但主库只是把binlog日志发送给从库,动作就结束了,不会验证从库是否接收完毕,风险较高。半同步复制会在发送给从库后,等待从库发送确认信息后才返回。可以设置从库中同步日志的更新方式,从而减少从库同步的延迟,加快同步速度。 安装半同步复制:在mysql中运行install plugin rpl_semi_sync_master soname 'semisync_master.so';install plugin rpl_semi_sync_slave soname 'semisync_slave.so';SET GLOBAL rpl_semi_sync_master_enabled=ON;SET GLOBAL rpl_semi_sync_slave_enabled=ON;修改my.cnf :rpl_semi_sync_master_enabled=1rpl_semi_sync_slave_enabled=1sync_relay_log=1sync_relay_log_info=1sync_master_info=1稳定性测试:测试案例:使用java代码建连接,往某张表插入1w条记录,插入过程中将其中的master服务器停了,看备份服务器是否有这1w笔记录测试结果,停止主服务器后,java程序抛出异常:但这时再次发送sql命令,可以成功返回。证明只是当时的事务失败了。连接切换到了备份服务器,仍然可用。翻阅了mysql文档,有章节说明了这个问题:里面提到:当主服务器当机时,我们的应用程序虽然是不需做任何修改的,但在主服务器被备份服务器替换前,某些事务会丢失,这些可以作为正常的mysql错误来处理。数据完整性校验:测试主服务器停止后,备份服务器是否能够同步所有数据。重启了刚才停止主服务器后,查看记录数可以看到在插入1059条记录后被停止了。现在看看备份服务器的记录数是多少,看看在主服务器当机后是否所有数据都能同步过来大约经过了几十秒,才同步完,数据虽然不是立即同步过来,但没有丢失。1.2、分片:如何支持可扩展性和负载均衡fabric分片简介:当一台机器或一个组承受不了服务压力后,可以添加服务器分摊读写压力,通过Fabirc的分片功能可以将某些表中数据分散存储到不同服务器。我们可以设定分配数据存储的规则,通过在表中设置分片key设置分配的规则。另外,有些表的数据可能并不需要分片存储,需要将整张表存储在同一个服务器中,可以将设置一个全局组(Global Group)用于存储这些数据,存储到全局组的数据会自动拷贝到其他所有的分片组中。4.Galera Cluster简介:Galera Cluster号称是世界上最先进的开源数据库集群方案主要优点及特性:真正的多主服务模式:多个服务能同时被读写,不像Fabric那样某些服务只能作备份用同步复制:无延迟复制,不会产生数据丢失热备用:当某台服务器当机后,备用服务器会自动接管,不会产生任何当机时间自动扩展节点:新增服务器时,不需手工复制数据库到新的节点支持InnoDB引擎对应用程序透明:应用程序不需作修改架构及实现原理:首先,我们看看传统的基于mysql Replication(复制)的架构图:Replication方式是通过启动复制线程从主服务器上拷贝更新日志,让后传送到备份服务器上执行,这种方式存在事务丢失及同步不及时的风险。Fabric以及传统的主从复制都是使用这种实现方式。而Galera则采用以下架构保证事务在所有机器的一致性:客户端通过Galera Load Balancer访问数据库,提交的每个事务都会通过wsrep API 在所有服务器中执行,要不所有服务器都执行成功,要不就所有都回滚,保证所有服务的数据一致性,而且所有服务器同步实时更新。缺点及限制:由于同一个事务需要在集群的多台机器上执行,因此网络传输及并发执行会导致性能上有一定的消耗。所有机器上都存储着相同的数据,全冗余。若一台机器既作为主服务器,又作为备份服务器,出现乐观锁导致rollback的概率会增大,编写程序时要小心。不支持的SQL:LOCK / UNLOCK TABLES / GET_LOCK(), RELEASE_LOCK()…不支持XA Transaction目前基于Galera Cluster的实现方案有三种:Galera Cluster for MySQL、Percona XtraDB Cluster、MariaDB Galera Cluster。我们采用较成熟、应用案例较多的Percona XtraDB Cluster。应用案例:超过2000多家外国企业使用:包括:集群部署架构: 功能 IP Port Backing store(保存各服务器配置信息) 200.200.168.24 3306 Fabric 管理进程(Connector) 200.200.168.24 32274 HA Master 1 200.200.168.24 3306 HA Master 2 200.200.168.25 3306 HA Master 3 200.200.168.23 3306 4.1、测试数据同步在机器24上创建一个表:立即在25 中查看,可见已被同步创建使用Java代码在24服务器上插入100条记录立即在25服务器上查看记录数可见数据同步是立即生效的。4.2、测试添加集群节点添加一个集群节点的步骤很简单,只要在新加入的机器上部署好Percona XtraDB Cluster,然后启动,系统将自动将现存集群中的数据同步到新的机器上。现在为了测试,先将其中一个节点服务停止:然后使用java代码在集群上插入100W数据查看100w数据的数据库大小:这时启动另外一个节点,启动时即会自动同步集群的数据:启动只需20秒左右,查看数据大小一致,查看表记录数,也已经同步过来5.对比总结 MySQL Fabric Galera Cluster 使用案例 2014年5月才推出,目前在网上暂时没搜索到有大公司的应用案例 方案较成熟,外国多家互联网公司使用 数据备份的实时性 由于使用异步复制,一般延时几十秒,但数据不会丢失。 实时同步,数据不会丢失 数据冗余 使用分片,通过设置分片key规则可以将同一张表的不同数据分散在多台机器中 每个节点全冗余,没有分片 高可用性 通过Fabric Connector实现主服务器当机后的自动切换,但由于备份延迟,切换后可能不能立即查询数据 使用HAProxy实现。由于实时同步,切换的可用性更高。 可伸缩性 添加节点后,需要先手工复制集群数据 扩展节点十分方便,启动节点时自动同步集群数据,100w数据(100M)只需20秒左右 负载均衡 通过HASharding实现 使用HAProxy实现负载均衡 程序修改 需要切换成jdbc:mysql:fabric的jdbc类和url 程序无需修改 性能对比 使用java直接用jdbc插入100条记录,大概2000+ms 跟直接操作mysql一样,直接用jdbc插入100条记录,大概600ms 6.实践应用综合考虑上面方案的优缺点,我们比较偏向选择Galera 如果只有两台数据库服务器,考虑采用以下数据库架构实现高可用性、负载均衡和动态扩展:如果三台机器可以考虑:
回归用不用聚类稳健误,结果看得出来吗
看得出来。对于面板数据,reg与xtreg都可以使用,并且可以使用聚类稳健标准误,但是结果会不一样,所以回归用不用聚类稳健误,结果是看得出来的。聚类稳健标准误:认为在某一个group内部,个人的观测值取值是相关的,比如一个区县,一个家庭内部等等。可以用cluster来处理。
dubbo之Cluster(容错)
在介绍dubbo的cluster之前,先来看一下cluster在dubbo整体设计中的位置。按照官网的说法,Cluster作为路由层, 封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,核心扩展接口为 Cluster , Directory , Router , LoadBalance ,接口间的依赖关系如下:
虚拟Invoker暴露流程程: Cluster => (Directory => Router) => LoadBalance => Invoker ,依照这个顺序,我们先来看Cluster。Cluster不属于核心层,目的是将多个 Invoker 伪装成一个 Invoker,这样其它人只要关注 Protocol 层 Invoker 即可,加上 Cluster 或者去掉 Cluster 对其它层都不会造成影响,因为只有一个提供者时,是不需要 Cluster 的。本文主要关注Cluster层的容错及其核心接口(LoadBalance在之前的文章已经做过介绍)。
先来看Cluster层中的Cluster接口,支持SPI扩展、自适应扩展,默认SPI实现是FailOverCluster,核心只有一个join接口
比较好理解,把Directory中的所有原始Invoker合并成一个虚拟Invoker,虚拟Invoker是一系列通过合并原始Invoker,并在此基础上扩展带有容错机制的Invoker。以FailOverCluster为例,join返回FailoverClusterInvoker,具体的invoke逻辑由虚拟Invoker( FailoverClusterInboker )实现,构造方法( 这里以FailoverClsterInvoker为例,其他虚拟Invoker的构造方法大同小异 )通过继承父类AbstractClusterInvoker实现,只有一个Directory参数:
当前dubbo版本提供的虚拟Invoker主要有下面几种,下面来分别介绍:
所有8种cluster中,除去AvailableCluster、MergeableCluster、BroadcastCluster,其他都需要根据LoadBalance选取可用Invoker,具体逻辑在AbstractClusterInvoker.select。先来看AbstractClusterInvoker的构造方法:
两个核心参数,Directory和URL,Directory本节先不做介绍,这里的URL是被调用服务的URL;availableCheck为了与服务的availableCheck做区分,这里的参数名是 cluster.availablecheck ;核心关注上面提到的select方法,先来看逻辑:
整体select方法都是为了尽可能保证每次选出的Invoker不重复,也就是说最大限度的保证负载均衡;doSelect方法在处理的时候,通过loadBalance选出的Invoker,还会对其进一步判断是否已被选中过,步骤如下:
doSelect方法中的loadbalance.select已经在LoadBalance部分做了分析,这里不再冗述,重点关注reSelect方法;先把备选Invoker中,未被选中过的Invoker过滤出来,优先从中选取可用Invoker,步骤如下:
Cluster层的容错主要通过几种常用的容错机制配合负载均衡,保证最终通过Cluster暴露可用的Invoker;而且,dubbo在保证Invoker可用性前提下,要求尽可能均衡负载,过程会多次执行负载均衡策略。
注:dubbo源码版本2.7.1,欢迎指正。
Redis cluster 原理
Redis cluster 实现了所有的single key 操作,对于multi key操作的话,这些key必须在一个节点上面,redis cluster 通过 hash tags决定key存贮在哪个slot上面。
节点首要功能是存贮数据,集群状态,映射key到相应的节点。自动发现其他节点,发现失败节点,让从变为主。
为了完成以上功能,cluster使用tcp和二进制协议(Redis Cluster Bus),节点间互联.node 同时使用gossip协议传播信息,包括节点的发现,发送ping包,Pub/Sub信息。 因为节点并不代理请求转发,会返回MOVED和ASk错误,clients就可以直连到其他节点。client理论上面可以给任意节点发送请求,如果需要就重定向。但实际应用中client存贮一个从key到node的map来提高性能。
Redis cluster 使用异步复制的模式,故障转移的时候,被选为主的节点,会用自己的数据去覆盖其他副本节点的数据。所以总有一个时间口会丢失数据。 下面一个例子会丢失数据:
master partition 变得不可用
它的一个从变为主
一定时间之后,这个主又可用了
客户端这时候还使用旧的的路由,在这个主变为从之前,写请求到达这个主。
3、可用性
假设n个主节点,每个主下面挂载一个从,挂掉一个,集群仍然可用。挂点两个,可用性是1 -(1/(n 2 -1))(第一个节点挂掉后,还剩下n 2-1个节点),只有一个节点的主挂掉的可能性是 1/n*2 -1)
replicas migration 使可用性更高
4、性能
reids cluster 不代理请求到正确的节点,而是告诉客户端正确的节点
client 会保存一份最新的key与node映射,一般情况,会直接访问到正确的节点。
异步写副本
一般的操作和单台redis有相同的性能,一个有n个主节点的集群性能接近n*单个redis
综上 高性能 线性扩展 合理的写安全 高可用 是rediscluser 的主要目标
因为首先redis 存贮的数据量会特别大,如果合并需要更大的空间
key空间分布被划分为16384个slot,所以一个集群,主节点的个数最大为16384(一般建议master最大节点数为1000)
HASH_SLOT = CRC16(key) mod 16384
hash tag 是为了保证不同的key,可以分布到同一个slot上面,来执行multi-key的操作
hash tag的规则是以第一个{开始,到第一个}结尾,中间的内容,来做hash。
例子
{user1000}.following 与 {user1000}.followers user1000作为key
foo{}{bar} 整个key
{{bar}} {bar 为key
{bar}{zap} bar 为key
Ruby Example
从左到右依次为:node id, address:port, flags, last ping sent, last pong received, configuration epoch, link state, slots
其中node id是第一次启动获得的一个160字节的随机字符串,并把id保存在配置文件中,一直不会再变
每个节点有一个额外的TCP端口,这个端口用来和其他节点交换信息。这个端口一般是在与客户端链接端口上面加10000,比如客户端端口为6379,那么cluster bus的端口为16379.
node-to-node 交流是通过cluster bus与 cluster bus protocol进行。其中cluster bus protocol 是一个二进制协议,因为官方不建议其他应用与redis 节点进行通信,所以没有公开的文档,要查看的话只能去看源码。
Redis cluster 是一个网状的,每一个节点通过tcp与其他每个节点连接。假如n个节点的集群,每个节点有n-1个出的链接,n-1个进的链接。这些链接会一直存活。假如一个节点发送了一个ping,很就没收到pong,但还没到时间把这个节点设为 unreachable,就会通过重连刷新链接。
node 会在cluster bus端口一直接受连接,回复ping,即使这个ping 的node是不可信的。但是其他的包会被丢掉,如果发送者不是cluster 一员。
一个node有两种方式接受其他其他node作为集群一员
这样只要我们把节点加入到一个节点,就会自动被其他节点自动发现。
客户端可以自由的连接任何一个node,如果这个node 不能处理会返回一个MOVED的错误,类似下面这样
描述了key 的hash slot,属于哪个node
client 会维护一个hash slots到IP:port的映射
当收到moved错误的时候,可以通过CLUSTER NODES或者CLUSTER SLOTS去刷新一遍整个client
cluster 支持运行状态下添加和删除节点。添加删除节点抽象:把一部分hash slot从一个节点移动到另一个节点。
所以,动态扩容的核心就是在节点之间移动hash slot,hash slot 又是key的集合。所以reshare 就是把key从一个节点移动到其他节点。
redis 提供如下命令:
前两个指令:ADDSLOTS和DELSLOTS,用于向当前node分配或者移除slots,指令可以接受多个slot值。分配slots的意思是告知指定的master(即此指令需要在某个master节点执行)此后由它接管相应slots的服务;slots分配后,这些信息将会通过gossip发给集群的其他nodes。
ADDSLOTS指令通常在创建一个新的Cluster时使用,一个新的Cluster有多个空的Masters构成,此后管理员需要手动为每个master分配slots,并将16384个slots分配完毕,集群才能正常服务。简而言之,ADDSLOTS只能操作那些尚未分配的(即不被任何nodes持有)slots,我们通常在创建新的集群或者修复一个broken的集群(集群中某些slots因为nodes的永久失效而丢失)时使用。为了避免出错,Redis Cluster提供了一个redis-trib辅助工具,方便我们做这些事情。
DELSLOTS就是将指定的slots删除,前提是这些slots必须在当前node上,被删除的slots处于“未分配”状态(当然其对应的keys数据也被clear),即尚未被任何nodes覆盖,这种情况可能导致集群处于不可用状态,此指令通常用于debug,在实际环境中很少使用。那些被删除的slots,可以通过ADDSLOTS重新分配。
SETSLOT是个很重要的指令,对集群slots进行reshard的最重要手段;它用来将单个slot在两个nodes间迁移。根据slot的操作方式,它有两种状态“MIGRATING”、“IMPORTING”
1)MIGRATING:将slot的状态设置为“MIGRATING”,并迁移到destination-node上,需要注意当前node必须是slot的持有者。在迁移期间,Client的查询操作仍在当前node上执行,如果key不存在,则会向Client反馈“-ASK”重定向信息,此后Client将会把请求重新提交给迁移的目标node。
2)IMPORTING:将slot的状态设置为“IMPORTING”,并将其从source-node迁移到当前node上,前提是source-node必须是slot的持有者。Client交互机制同上。
假如我们有两个节点A、B,其中slot 8在A上,我们希望将8从A迁移到B,可以使用如下方式:
1)在B上:CLUSTER SETSLOT 8 IMPORTING A
2)在A上:CLUSTER SETSLOT 8 MIGRATING B
在迁移期间,集群中其他的nodes的集群信息不会改变,即slot 8仍对应A,即此期间,Client查询仍在A上:
1)如果key在A上存在,则有A执行。
2)否则,将向客户端返回ASK,客户端将请求重定向到B。
这种方式下,新key的创建就不会在A上执行,而是在B上执行,这也就是ASK重定向的原因(迁移之前的keys在A,迁移期间created的keys在B上);当上述SET SLOT执行完毕后,slot的状态也会被自动清除,同时将slot迁移信息传播给其他nodes,至此集群中slot的映射关系将会变更,此后slot 8的数据请求将会直接提交到B上。
动态分片的步骤:
在上文中,我们已经介绍了MOVED重定向,ASK与其非常相似。在resharding期间,为什么不能用MOVED?MOVED意思为hash slots已经永久被另一个node接管、接下来的相应的查询应该与它交互,ASK的意思是当前query暂时与指定的node交互;在迁移期间,slot 8的keys有可能仍在A上,所以Client的请求仍然需要首先经由A,对于A上不存在的,我们才需要到B上进行尝试。迁移期间,Redis Cluster并没有粗暴的将slot 8的请求全部阻塞、直到迁移结束,这种方式尽管不再需要ASK,但是会影响集群的可用性。
1)当Client接收到ASK重定向,它仅仅将当前query重定向到指定的node;此后的请求仍然交付给旧的节点。
2)客户端并不会更新本地的slots映射,仍然保持slot 8与A的映射;直到集群迁移完毕,且遇到MOVED重定向。
一旦slot 8迁移完毕之后(集群的映射信息也已更新),如果Client再次在A上访问slot 8时,将会得到MOVED重定向信息,此后客户端也更新本地的集群映射信息。
可能有些Cluster客户端的实现,不会在内存中保存slots映射关系(即nodes与slots的关系),每次请求都从声明的、已知的nodes中,随机访问一个node,并根据重定向(MOVED)信息来寻找合适的node,这种访问模式,通常是非常低效的。
当然,Client应该尽可能的将slots配置信息缓存在本地,不过配置信息也不需要绝对的实时更新,因为在请求时偶尔出现“重定向”,Client也能兼容此次请求的正确转发,此时再更新slots配置。(所以Client通常不需要间歇性的检测Cluster中配置信息是否已经更新)客户端通常是全量更新slots配置:
遇到MOVED时,客户端仅仅更新特定的slot是不够的,因为集群中的reshard通常会影响到多个slots。客户端通过向任意一个nodes发送“CLUSTER NODES”或者“CLUSTER SLOTS”指令均可以获得当前集群最新的slots映射信息;“CLUSTER SLOTS”指令返回的信息更易于Client解析。
通常情况下,read、write请求都将有持有slots的master节点处理;因为redis的slaves可以支持read操作(前提是application能够容忍stale数据),所以客户端可以使用“READONLY”指令来扩展read请求。
“READONLY”表明其可以访问集群的slaves节点,能够容忍stale数据,而且此次链接不会执行writes操作。当链接设定为readonly模式后,Cluster只有当keys不被slave的master节点持有时才会发送重定向消息(即Client的read请求总是发给slave,只有当此slave的master不持有slots时才会重定向,很好理解): 1)此slave的master节点不持有相应的slots 2)集群重新配置,比如reshard或者slave迁移到了其他master上,此slave本身也不再支持此slot。
集群中的nodes持续的交换ping、pong数据,这两种数据包的结构一样,同样都携带集群的配置信息,唯一不同的就是message中的type字段。
通常,一个node发送ping消息,那么接收者将会反馈pong消息;不过有时候并非如此,比如当集群中添加新的node时,接收者会将pong信息发给其他的nodes,而不是直接反馈给发送者。这样的好处是会将配置尽快的在cluster传播。
通常一个node每秒都会随机向几个nodes发送ping,所以无论集群规模多大,每个nodes发送的ping数据包的总量是恒定的。每个node都确保尽可能半个NODE_TIMEOUT时间内,向那些尚未发送过ping或者未接收到它们的pong消息的nodes发送ping。在NODE_TIMEOUT逾期之前,nodes也会尝试与那些通讯异常的nodes重新建立TCP链接,确保不能仅仅因为当前链接异常而认为它们就是不可达的。
当NODE_TIMEOUT值较小、集群中nodes规模较大时,那么全局交换的信息量也会非常庞大,因为每个node都尽力在半个NODE_TIMEOUT时间内,向其他nodes发送ping。比如有100个nodes,NODE_TIMEOUT为60秒,那么每个node在30秒内向其他99各nodes发送ping,平均每秒3.3个消息,那么整个集群全局就是每秒330个消息。这些消息量,并不会对集群的带宽带来不良问题。
心跳数据包的内容
ping和pong数据包中也包含gossip部分,这部分信息告诉接受者,当前节点持有其他节点的状态,不过它只包含sender已知的随机几个nodes,nodes的数量根据集群规模的大小按比例计算。
gossip部分包含了
集群失效检测就是,当某个master或者slave不能被大多数nodes可达时,用于故障迁移并将合适的slave提升为master。当slave提升未能有效实施时,集群将处于error状态且停止接收Client端查询。
每个node持有其已知nodes的列表包括flags,有2个flag状态:PFAIL和FAIL;PFAIL表示“可能失效”,是一种尚未完全确认的失效状态(即某个节点或者少数masters认为其不可达)。FAIL表示此node已经被集群大多数masters判定为失效(大多数master已认定为不可达,且不可达时间已达到设定值,需要failover)。
nodes的ID、ip+port、flags,那么接收者将根据sender的视图,来判定节点的状态,这对故障检测、节点自动发现非常有用。
当node不可达的时间超过NODE_TIMEOUT,这个节点就被标记为PFAIL(Possible failure),master和slave都可以标记其他节点为PFAIL。所谓不可达,就是当“active ping”(发送ping且能受到pong)尚未成功的时间超过NODE_TIMEOUT,因此我们设定的NODE_TIMEOUT的值应该比网络交互往返的时间延迟要大一些(通常要大的多,以至于交互往返时间可以忽略)。为了避免误判,当一个node在半个NODE_TIMEOUT时间内仍未能pong,那么当前node将会尽力尝试重新建立连接进行重试,以排除pong未能接收