akka集群是高容错、去中心化、不存在单点故障以及不存在单点瓶颈的集群。它使用gossip协议通信以及具备故障自动检测功能。

Gossip收敛

  集群中每一个节点被其他节点监督(默认的最大数量为5)。集群中的节点互相监督着,某节点所监督的状态也正在被其他监督着。通过gossip协议,节点向其他节点传递自己所见节点的最新状态(Up、Joining等等),同时节点也在接收来自其他节点的信息,这些信息包括哪些节点以及这些节点对应的状态,并这些节点加入到自己的seen表里去,表示自己已经看见了这些节点的最新状态了,当所有的节点都把其他节点“看见”了后,我们可以说"Gossip收敛"完成了。

  根据以上陈述,当集群中某节点不可达(unreachable)时,gossip收敛不能完成。那些不可达的节点需要变成可达状态(reachable)或者down状态,收敛才能进行。

  akka集群不存在leader选举,但是存在leader节点,但是leader节点可以转移,leader负责执行leader action,当每次收敛完成后,leader需要做三件事:

  • 将处于joining状态节点变更为Up状态, 即joining->up
  • leaving->exiting
  • exiting->removed

failure Detector

  集群中,一个节点被其他节点监督(默认最大数量为5),任何一个节点被探测到不可达时,那么这个消息将被通过gossip协议传播到其他节点去,其他节点也将此节点标为不可达。同时故障检测机制也会将节点从不可达标记为可达,同时扩散给其他节点。

关于评判一个节点是否可达的方式是利用历史数据中每次心跳时间间隔的平均值与心跳次数为均方差去构建一个正太分布,F是这个分布的密度分布函数,利用以下公式:

`phi = -log10(1 - F(timeSinceLastHeartbeat))`
  phi反应了当前网络的好坏情况,当`akka.cluster.failure-detector.threshold`阈值配置不当时,并不是等待某个心跳检测超时时,才会把节点标记为不可达。其值默认为18,想要得到更高的灵敏度,需要把阈值设置降低。

## 实践
  编程方式构建集群
  `akka.tcp://myCluster@127.0.0.1:2551`节点:

application.conf:

akka {
actor {
provider = cluster
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 2551
}
}
cluster {
seed-nodes = []
}
}
package nathan

import akka.actor.{Actor, ActorSystem, Address}
import akka.cluster.Cluster
import com.typesafe.config.ConfigFactory object Main extends App {
val actorSystem = ActorSystem("myCluster", ConfigFactory.load())
Cluster(actorSystem).join(Address(protocol = "akka.tcp",system = "myCluster",host = "127.0.0.1",port = 2551))
}

  上述代码Cluster(actorSystem).join(address)是以address为基础创建集群,集群的名称为"myCluster",其中包含"akka.tcp://myCluster@127.0.0.1:2551"的节点。集群的名称为其第一个加入的节点的名字决定,其他后加入的节点的名称应当与其保持一致。当这个单节点集群创建完毕后,这个单节点就成为seedNode,也就是说,其他节点通过向种子节点发出Join指令,就可以加入集群。

  akka.tcp://myCluster@127.0.0.1:2552节点

application.conf

akka {
actor {
provider = cluster
}
remote {
enabled-transports = ["akka.remote.netty.tcp"]
netty.tcp {
hostname = "127.0.0.1"
port = 2552
}
}
}
package nathan

import akka.actor.{ActorSystem, Address}
import akka.cluster.Cluster
import com.typesafe.config.ConfigFactory object Main extends App {
val actorSystem = ActorSystem("myCluster", ConfigFactory.load())
Cluster(actorSystem).joinSeedNodes(List(Address(protocol = "akka.tcp",system = "myCluster1",host = "127.0.0.1",port = 2551)))
}

  Cluster(actorSystem).joinSeedNodes(List(address))代码作用向某个种子节点发出Join命令以加入集群。这里填写的种子节点越多越好,这样消息在集群中扩散可以更快。

监听集群节点状态

  集群时间有如下几种有如下几种:MemberJoinedMemberWeaklyUpMemberUpMemberLeftMemberExitedMemberRemovedLeaderChangedRoleLeaderChangedUnreachableMemberReachableMember等等。

class ListenClusterActor extends Actor {
val cluster = Cluster(context.system)
override def preStart(): Unit = {
cluster.subscribe(self, InitialStateAsEvents, classOf[MemberEvent], classOf[UnreachableMember])
}
override def postStop(): Unit = cluster.unsubscribe(self)
override def receive: Receive = {
case MemberJoined(member) =>
println("join:" + member)
case MemberUp(member) =>
println("up:" + member)
case MemberExited(member) =>
println("exited:" + member)
case MemberRemoved(member,previousStatus) =>
println("removed:" + member+" before status:"+previousStatus)
case UnreachableMember(member) =>
println("unreachable:" + member)
}
}

当其他节点加入集群时和离开时,打印如下:

join:Member(address = akka.tcp://myCluster@127.0.0.1:2552, status = Joining)
up:Member(address = akka.tcp://myCluster@127.0.0.1:2552, status = Up)
exited:Member(address = akka.tcp://myCluster@127.0.0.1:2552, status = Exiting)
removed:Member(address = akka.tcp://myCluster@127.0.0.1:2552, status = Removed) before status:Exiting

Akka Cluster简介与基本环境搭建的更多相关文章

  1. 工作流--JBPM简介及开发环境搭建

    一. 工作流简介 项目中不断的接触工作流,点点滴滴积累了一些,下面把一些学习到的东西整理记录下来. 工作流一般的适用场景:公文流转.行政审批.订单处理.产品研发.制造过程等.用专业一点的语言来描述工作 ...

  2. Django之Django简介,开发环境搭建,项目应用创建

    软件及Django框架简介 软件框架 一个软件框架是由其中各个软件模块组成的: 每一个模块都有特定的功能: 模块与模块之间通过相互配合来完成软件的开发. 软件框架是针对某一类软件设计问题而产生的. M ...

  3. Python简介及开发环境搭建

    Python简介 Python是一门动态解释性的强类型定义的计算机程序设计语言,是一种完全面向对象的语言,由荷兰人"龟叔"-Guido van Rossum于1989年开发,于19 ...

  4. Appium 简介与自动化测试环境搭建

    1. Appium 简介 2. Appium 自动化测试环境搭建 1. Appium 简介 Appium 是一个开源测试自动化框架,可用于原生,混合和移动 Web 应用程序测试. 它使用 WebDri ...

  5. Web笔记(一) Web 简介与开发环境搭建

    Web应用程序的工作原理 大多数的Web应用程序结构都是采用最为流行的B/S软件开发体系结构,将Web应用程序部署在Web服务器上,只要Web服务器启动,用户就可以通过客户端浏览器发送HTTP请求到W ...

  6. 【系列】Python编程思想(1):Python简介与开发环境搭建

    李宁老师的 开始学习.   本系列文章深入介绍了Python的各种技术,堪称是目前最全的Python教程.主要目的是让读者可以了解Python的各种核心技术,包括各种Python函数库.本教程使用Py ...

  7. 小朋友学Python(1):Python简介与编程环境搭建

    一.Python简介 不死Java,不朽C/C++,新贵Python. Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰 ...

  8. Scala语言简介和开发环境配置

    Scala语言的简介和开发环境搭建 Scala是一门结合了面向对象特征和函数式编程特征的语言,它是一个创新的编程语言产品.Scala可以做脚本(就像shell脚本一样),可以做服务端编程语言,可以写数 ...

  9. angularJS开发环境搭建和启动

    本文目录:1.angularJS框架简介 2.angularJS环境搭建 3.启动一个项目 1.angularJS框架简介 AngularJS是一个开发动态Web应用的框架.它让你可以使用HTML作为 ...

随机推荐

  1. 乐呵乐呵得了 golang入坑系列

    开场就有料,今天返回去看了看以前的文章,轻松指数有点下降趋势.一琢磨,这不是我的风格呀.一反思,合着是这段时间,脑子里杂七杂八的杂事有点多,事情一多,就忘了快乐.古话说得好:愁也一天,乐也一天,只要还 ...

  2. 01---Spring框架

    Spring框架简介及官方压缩包目录介绍 工厂模式 Spring环境搭建 IoC详解 Spring创建Bean的三种方式(包含两种工厂方式) scope属性讲解 DI详解 Spring中几种注入方式 ...

  3. ES6模块化

    关于ES6模块化 历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来.其他语言都有这项功能,比如 Ruby 的require ...

  4. Python爬虫(十)_正则表达式

    本篇将介绍python正则表达式,更多内容请参考:[python正则表达式] 什么是正则表达式 正则表达式,又称规则表达式,通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式是对字符串操 ...

  5. Android数据存储之内部存储、外部存储

    首先来介绍下什么是内部存储? 在Android平台下,有着自己独立的数据存储规则,在windows平台下,应用程序能够自由的或者在特定的訪问权限基础上訪问或改动其它应用程序下的文件资源. 可是在And ...

  6. openstack-glance API 镜像管理的部分实现和样例

    感谢朋友支持本博客,欢迎共同探讨交流,因为能力和时间有限.错误之处在所难免.欢迎指正. 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  7. UVA - 11396 Claw Decomposition(二分图染色)

    题目大意:给你一张无向图,每一个点的度数都是3. 你的任务是推断是否能把它分解成若干个爪(每条边仅仅能属于一个爪) 解题思路:二分图染色裸题.能够得出:爪的中心点和旁边的三个点的颜色是不一样的 #in ...

  8. FFmpeg源码简单分析:libswscale的sws_scale()

    ===================================================== FFmpeg的库函数源码分析文章列表: [架构图] FFmpeg源码结构图 - 解码 FFm ...

  9. hibernate学习笔记之中的一个(JDBC回想-ORM规范)

    JDBC回想-ORM规范 JDBC操作步骤 注冊数据库驱动 Class.forName("JDBCDriverClass") 数据库 驱动程序类 来源 Access sun.jdb ...

  10. 大数据学习(5)MapReduce切片(Split)和分区(Partitioner)

    MapReduce中,分片.分区.排序和分组(Group)的关系图: 分片大小 对于HDFS中存储的一个文件,要进行Map处理前,需要将它切分成多个块,才能分配给不同的MapTask去执行. 分片的数 ...