设计分布式系统—简明粗暴的名字发现服务

2018-09-20 15:21:14 +08:00
 ChristopherWu

转发旧文: https://yonghaowu.github.io/2018/09/19/erlang_distibute_node/ 抛砖引玉,希望得到大佬指教。

在设计实现分布式系统时,必定离不开名字发现服务: 一个新节点加进来系统里了,怎么样被其他节点感知到,并且能与此节点通信呢?

在此, 我向大家简明扼要的介绍一下 erlang 这个设计了十多年稳定性达到 99.99999999%的电话系统的语言是怎么样做的。

erlang 的这个名字发现服务叫epmd(Erlang Port Mapper Daemon),中文是Erlang 端口映射守护进程,默认是开启在 4369 端口。

一个 node 上(可以暂时理解为一台物理机上),所有其他 erlang 的程序启动启动时,必须指定自己的名称(例如:my_name@ubuntu,,这个是 erlang 节点名称,@的前面是名字,后面是本机 hostname ),并把 ip 到 4369 端口上(当然这些 erlang 都帮你处理好了)。值得注意的是,每个程序启动时,都会试图去创建 empd 进程,失败就算了。(这很粗暴, 但可以保证 empd 必定会启动

注册完成后,empd 会广播此节点的信息到各个节点上,让各个节点保存起来。这样子就算 empd 挂掉了,其他节点依然有着其他节点的信息,能够通信。

而 empd 服务正常时,节点则会向 empd 查询其他节点的信息。

empd 挂掉了,由于节点存有其他全部节点的信息,所以旧节点依然能够通信。empd 重新启动了,新节点依然通过 empd 注册信息,但因为旧节点不会重连 empd (不清楚 erlang 为何这样设计,照理重连应该挺方便的),所以新节点无法与旧的节点通信了。要想恢复,除了重启,唯一的办法就是通过erl_epmd:register_node重新注册该节点。

分布式服务,自然是把服务器都放在同一个内网中,相互通信。不暴露在外面,不做成内网简直是愚蠢。

而当本地节点尝试通过 empd 与远程节点联系时,empd 会发请求其他内网机器的 empd 服务,这两个 empd 服务就作为桥梁,把本地节点与远程节点联系起来。

你也许会有一个疑问, 本地节点怎么样得知远程节点的内网 ip ?

还记得my_name@ubuntu,这个 节点名称吗?

@的前面是名字,后面是本机 hostname。

与其他节点通信时,便是靠 @后面的这个 hostname 来通信,这意味着,你需要在 /etc/hosts里配置好所有 hostname 对应的内网 ip。自然这个可以通过很多办法便捷的完成。

至此,empd 的名字发现服务便介绍完成。你也可以依据此来自己实现一个简单的服务。

2613 次点击
所在节点    程序员
16 条回复
YouXia
2018-09-20 15:43:37 +08:00
一个服务发现程序大约需要考虑下以下几点:
1、服务发现程序为解决单点问题,而引入了单点问题,那 master 怎么做多活或者说怎么做 leader 选举
2、订阅机制怎么实现?
3、通信协议是啥?原因?
4、心跳使用 TCP or UDP,或者 HTTP,原因?
5、meta 信息如何持久化?
6、负载均衡机制?
7、如何解决多机房问题?
等等。。。

文章不是为了写而写,你这文章明显是普通大众不假思索就能考虑到的,且文笔还需要多加锻炼,语气各种不通顺。

阿里内网,搜索系有 cm2,集团有 vipserver、diamond 等,随便内网看几篇文章吧。
yidinghe
2018-09-20 15:49:58 +08:00
@YouXia 回帖不看帖。文章从头到尾都没有 master 的概念,你这 1234567 就是闭着眼睛写的,跟文章没一点关系。
YouXia
2018-09-20 15:53:48 +08:00
@yidinghe 你一个服务发现程序没有 master,那搞啥!
yidinghe
2018-09-20 15:54:41 +08:00
@YouXia 问得好,你先看完文章,然后再向楼主提具体的问题。
neoblackcap
2018-09-20 16:02:36 +08:00
@YouXia 文章里面的确是没有 master 的意思,因为每个节点都是 master。
@yidinghe 如果我没有理解错的话。也可以说这个分布式没有水平拓展性。因为单机解决不了的数据,上这个分布式方案也解决不了。
YouXia
2018-09-20 16:04:10 +08:00
@yidinghe 楼主说涉及和实现一个分布式服务发现程序,然后介绍了 epmd 的节点通信方法,我回复说这个通信方式并不是重点,普通大众都能考虑到,重点是需要考虑到以上几点。不知道你啥理解力。
ChristopherWu
2018-09-20 16:04:37 +08:00
@YouXia 你说的对,文章写得不够好。。但是抛砖引玉嘛,本来 v2 也只是讨论的论坛,非专业文章集合的地方。

erlang 的这个服务发现,跟常见的 master/slave 等分布式服务的服务发现不一样,所以说 粗暴简明。
ChristopherWu
2018-09-20 16:14:12 +08:00
@neoblackcap
》也可以说这个分布式没有水平拓展性。因为单机解决不了的数据,上这个分布式方案也解决不了。
不太清楚你说的这句话是什么意思额。

水平拓展性是有的,但是需要自己来做 load balance,如 A 组件调用 B 时,A 将处理转发到 B 的其他 node 上。比如我们现在一个常用系统就简单的用了 random 或者 cpu 压力来做。稳定性很高,也可以水平拓展。
yidinghe
2018-09-20 16:17:13 +08:00
@neoblackcap 通过广播来水平扩展啊。
misaka19000
2018-09-20 16:31:55 +08:00
前几天用 golang 写了个类似的系统,瞎写写的,但是感觉有些理念和楼主的差不多

https://github.com/RitterHou/totoro
neoblackcap
2018-09-20 16:44:39 +08:00
@ChristopherWu 你每个节点保存的信息是多少?全部节点的路由信息嘛?如果不是,那么不就出现相当抛弃了 CAP 理论里面的 P。
如果你全部保存,那么就是一个星状网络,你能处理的信息取决于你单机能处理的数据量。
不知道我理解的对不对。有错请指出
ChristopherWu
2018-09-20 16:49:48 +08:00
@neoblackcap

是的, 会保存所有节点的路由信息。
>empd 会广播此节点的信息到各个节点上,让各个节点保存起来

是的,能处理的信息取决于单机能处理的数据量。但是呢,我们可以通过在程序前加一个 LBS 层,来分开这种压力。
neoblackcap
2018-09-20 16:57:48 +08:00
@ChristopherWu 然后你的 LBS 层又是一个单点是吗?如果你的 LBS 不是单点的话,那么直接将服务注册到 LBS 层上面不是更好了?
ChristopherWu
2018-09-20 16:59:45 +08:00
@neoblackcap 偷了个懒,LBS 用了阿里云的了。。
tenca
2018-09-21 06:18:43 +08:00
你说你粗暴可以。但是,问题是,这不叫分布式啊。不是说把程序跑到几个机器上然后能相互通信就叫分布式系统的。
ChristopherWu
2018-09-21 10:24:53 +08:00
@tenca
我认为算分布式。

》 A distributed system is a network that consists of autonomous computers that are connected using a distribution middleware. They help in sharing different resources and capabilities to provide users with a single and integrated coherent network.

不然你说说你的定义?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/491211

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX