Archive

Archive for the ‘Erlang探索’ Category

Erlang集群全联通问题及解决方案

May 2nd, 2013 10 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Erlang集群全联通问题及解决方案

Erlang的集群默认情况下是全联通的,也就是当一个节点加入集群的时候,介绍人会推荐集群里面所有的节点主动来和新加入的节点建立联系,
效果如下图:

erlang_connect

具体点讲那就是net_kernel模块负责节点间的通道的建立、检查、断开并提供monitor_node语义。
摘抄 http://www.erlang.org/doc/man/erlang.html 如下:

monitor_node(Node, Flag) -> true
Types:
Node = node()
Flag = boolean()
Monitors the status of the node Node. If Flag is true, monitoring is turned on; if Flag is false, monitoring is turned off.

Making several calls to monitor_node(Node, true) for the same Node is not an error; it results in as many, completely independent, monitorings.

If Node fails or does not exist, the message {nodedown, Node} is delivered to the process. If a process has made two calls to monitor_node(Node, true) and Node terminates, two nodedown messages are delivered to the process. If there is no connection to Node, there will be an attempt to create one. If this fails, a nodedown message is delivered.

Nodes connected through hidden connections can be monitored as any other node.

Failure: badargif the local node is not alive.

其他模块如global, pg2, mnesia都利用这个monitor_node提供的语义来实现更上层的逻辑。那么上面提到的引荐机制正是global模块实现的,它的目的是提供集群层面的名称和进程的映射关系,所以它需要全联通。

学过中学数学的同学都知道系统总的通道的数目是N*(N-1)/2, 随着N的增长,这个数目会急速上升,见下图。

hidden_visible

这个对集群的规模有致命的破坏作用。 这么多链接需要耗用很多资源,更坏的是,erlang为了检测节点的存活,需要定期发心跳包来检查,一分钟一个tick, 这会造成大量的网络风暴。

那么我们如何来避免这个事情呢?
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Erlang集群RPC通道拥塞问题及解决方案

May 2nd, 2013 1 comment

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Erlang集群RPC通道拥塞问题及解决方案

Erlang的集群默认情况下是全联通的,也就是当一个节点加入集群的时候,介绍人会推荐集群里面所有的节点主动来和新加入的节点建立联系,
效果如下图:

erlang_connect

我们这次不讲如何避免全联通而是来讲这个节点间通道的问题。

我们知道erlang的消息发送是透明的,只要调用Pid!Msg, 虚拟机和集群的基础设施会保证消息到达指定的进程的消息队列,这个是语义方面的保证。那么如果该Pid是在别的节点,这个消息就会通过节点间的rpc通道来传递。rpc模块就是基于erlang的这个语义在上面实现了远程函数调用。

目前社区推比较推荐erlang服务分层,所以层和层之间的交互基本上透过rpc来进行的。类似下图的分层结构越来越多,当大量的消息在节点间流动的话,势必会造成通道拥塞。

layer

阻塞会导致发送进程被挂起,而rpc是单进程(gen_server)的,被挂起,rpc调用就废了。当然除了RPC, Pid!Msg 这种方式还是可以并行的走的。
这种阻塞极大的影响力系统的rt, 对性能和体验有很大的影响。

那这个问题如何定位、解决呢?Erlang很贴心的提供了一揽子解决方案:

首先是发现问题:

erlang:system_monitor(MonitorPid, Options) -> MonSettings

busy_dist_port
If a process in the system gets suspended because it sends to a process on a remote node whose inter-node communication was handled by a busy port, a message {monitor, SusPid, busy_dist_port, Port} is sent to MonitorPid. SusPid is the pid that got suspended when sending through the inter-node communication port Port.

比如说 riak_sysmon 就用了以下代码:

 BusyDistPortP = get_busy_dist_port(),
    Opts = lists:flatten(
             [[{long_gc, GcMsLimit} || lists:member(gc, MonitorProps)
                                           andalso GcMsLimit > 0],
              [{large_heap, HeapWordLimit} || lists:member(heap, MonitorProps)
                                                  andalso HeapWordLimit > 0],
              [busy_port || lists:member(port, MonitorProps)
                                andalso BusyPortP],
              [busy_dist_port || lists:member(dist_port, MonitorProps)
                                     andalso BusyDistPortP]]),
    _ = erlang:system_monitor(self(), Opts),

当我们收到{monitor, SusPid, busy_dist_port, Port}消息的时候,就可以确认系统经常有阻塞问题。

那么如何解决呢?

社区早就认识到这个问题, 所以设计dist_buf_busy_limit是个可配置的值。
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

whatsapp深度使用Erlang有感

April 30th, 2013 13 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: whatsapp深度使用Erlang有感

这么多年过去了,社区还在讨论erlang是不是小众语言,各种怀疑的时候,whatsapp已经把erlang用到了极致。

logo-text-ver-color

whatsapp是什么? 参见它的 官网

WhatsApp Messenger is a cross-platform mobile messaging app which allows you to exchange messages without having to pay for SMS.

更为搞笑的是 主要开发者Rick Reed(rr@whatsapp.com),之前在Yahoo!, SGI工作,有着深厚的系统性能的背景。

在2012年开发push服务器的时候:efsf2012-whatsapp-scaling

Joined WhatsApp in 2011,New to Erlang

完全是个新手。

在2013年开发多媒体支持系统的时候:reed-efsf2013-whatsapp

Joined server team at WhatsApp in 2011,No prior Erlang experience

2-3年后他已经是Erlang的最高级别的行家了。

从他的二篇ppt的内容来看, 他把erlang的特性发挥到了极致,利用到了它最好的vm、 集群基础设施、数据库mnesia, 消除了非常多的数据Scale、内存池和锁的问题, 提到的技术和修正点非常值得我们参考。

虽然大部分的解决方法我们在日常都差不多用过。但是他很系统的整理出来,用在商业系统了,这是个非常大的飞跃。

下面摘抄几个数据,希望能让继续怀疑erlang的人能重新思考下:

whatsapp后台架构以erlang为主:
wa1
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

为什么Erlang是软实时的

January 16th, 2013 6 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 为什么Erlang是软实时的

之前在微博上@老师木 同学发起了个关于Erlang抢占式调度的讨论,相对于其他语言Erlang是真正的抢占式调度服务,这也是erlang能够号称软实时的很重要的原因之一,另外二个原因分别是erlang的GC是针对每个进程的,每次GC通常只需要收集几K或者几十个对象;BIF是用trap机制来保证公平的。

erlang_preemptive

今天在微博上看到erlang调度器的工作细节的文章来源见这里。这篇文章很准确的描述了Erlang调度器是如何工作的,很好的澄清了大家对各种语言调度器的误解。 本来我前段时间想自己写,看来没必要了,就顺手贴出来给大家。

How Erlang does scheduling

In this, I describe why Erlang is different from most other language runtimes. I also describe why it often forgoes throughput for lower latency.

TL;DR – Erlang is different from most other language runtimes in that it targets different values. This describes why it often seem to perform worse if you have few processes, but well if you have many.

From time to time the question of Erlang scheduling gets asked by different people. While this is an abridged version of the real thing, it can act as a way to describe how Erlang operates its processes. Do note that I am taking Erlang R15 as the base point here. If you are a reader from the future, things might have changed quite a lot—though it is usually fair to assume things only got better, in Erlang and other systems.
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , ,

低成本和高性能MySQL云数据的架构探索

October 25th, 2012 9 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 低成本和高性能MySQL云数据的架构探索

原文地址:http://www.alibabatech.org/article/detail/3405/0?ticket=d69f07f8-b60b-43f8-9572-7d795bb8429d
作者:鸣嵩
PPT这里下载:

该文已在《程序员》2012年10期上发表。

MySQL作为一个低成本、高性能、可靠性好而且开源的数据库产品,在互联网企业应用非常广泛,例如淘宝网有数千台MySQL服务器的规模。虽然近两年来NoSQL的发展很快,新产品层出不穷,但在业务中应用NoSQL对开发者来说要求比较高,而MySQL拥有成熟的中间件、运维工具,已经形成一个良性的生态圈等,因此从现阶段来看,MySQL占主导性,NoSQL为辅。
在过去一年时间里,我们(阿里集团核心系统数据库团队)在MySQL托管平台方向做了大量工作,设计和实现了一套UMP(Unified MySQL Platform)系统,提供低成本和高性能的MySQL云数据服务。开发者从平台上申请MySQL实例资源,通过平台提供的单一入口来访问数据,UMP系统内部维护和管理资源池,以对用户透明的形式提供主从热备、数据备份、迁移、容灾、读写分离、分库分表等一系列服务。平台通过在一台物理机上运行多个MySQL实例的方式来降低成本,并且实现了资源隔离,按需分配和限制CPU、内存和IO资源,同时支持不影响提供数据服务的前提下根据用户业务的发展动态的扩容和缩容。

架构的演变
UMP系统第一版基于mysql-proxy 0.8版修复若干bug,并对proxy插件中管理用户连接和数据库连接的状态机流程进行一些修改,同时编写Lua脚本实现去中心数据库获取用户认证信息和后台数据库地址,对用户进行验证,建立到后台数据库的连接和转发数据包等逻辑。

图1 UMP系统的第一版采用MySQL Proxy

在开发和部署第一版的过程中,我们逐渐认识到几个问题:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Erlang虚拟机基础设施dtrace探测点介绍和使用

April 28th, 2012 2 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Erlang虚拟机基础设施dtrace探测点介绍和使用

最新的Erlang虚拟机(R15B01)很大的一个改进就是加入了对dtrace探测点的支持了, 具体参见这里, 主要目标是方便在生产实践中定位复杂的性能问题。

目前Erlang的虚拟机的探测点支持Linux的systemtap和freebsd的dtrace,我们刚好能够享受的到。

作者Scott Lystig Fritchie在去年的euc中做了个很有意思的报告,参见这里,该PPT很详细的介绍了利用dtrace的探测点可以观察到erlang的行为如下:

Processes: spawn, exit, hibernate, scheduled, …
Messages: send, queued, received, exit signals
Memory: GC minor & major, proc heap grow & shrink
Data copy: within heap, across heaps
Function calls: function & BIF & NIF, entry & return
Network distribution: monitor, port busy, output events
Ports: open, command, control, busy/not busy
Drivers: callback API 100% instrumented
efile_drv.c fifile I/O driver: 100% instrumented

这些探测点基本上属于IO,进程调度,消息发送,driver等虚拟机最底层的和操作系统耦合的部分,对性能的影响巨大。

目前Erlang自己的基础设施并没有涵盖到这部分内容,如dbg,trace机制都无法了解到这些数据,导致在大型的集群系统里面一旦发现性能问题无法很好的展开调查,所以这些探测点刚好填补了空白。

目前这些dtrace probe点是用static marker实现的,细节可以参看这里这里,好处是不用这些特性的时候,不会对性能有任何的影响,只需要为使用付代价。目前支持这种机制的语言和系统有java,python,mysql,pgsql等,可见威力强劲。

好拉,废话少说,我们来体验下。
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Erlang节点互联失败原因分析以及解决方案

March 28th, 2012 6 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Erlang节点互联失败原因分析以及解决方案

今天和项仲在部署新系统的时候发现节点间ping不成功的情况,类似

1> net_adm:ping(‘xx@ip1’).
pang

由于这个问题比较普遍,我就记录下一步步的排除步骤.

首先从原理上分析下!由于erlang节点间通讯是透过tcp来进行的,所以我们确保以下几点:
1. 确保网络连接是通的,可以透过ping来查看。
2. 确保网络连接上tcp是可以通的,可以透过netcat在二个节点所在的机器上分别开个服务器端和客户端进行验证。
3. 确保端口是防火墙友好的。erlang的节点是登记在epmd服务上的,所以4369端口要能访问,其次节点的动态端口是可以访问的。

epmd -names
epmd: up and running on port 4369 with data:
name xx at port 46627

同样可以用netcat来验证。
4. erlang节点的cookie是一样的,可以透过setcookie来解决。

这几点确认无误后,就可以开始排查问题了。
首先交代下环境,二台机器IP分别是10.1.150.12,10.232.31.89, 上面分别运行Erlang版本R16B和R14B04,cookie统一设置为456789。
接着我们来演习下,首先我们10.1.150.12在节点A上起个节点’xx@10.1.150.12’,如下:

Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.