Archive

Archive for the ‘Erlang探索’ Category

erlang和其他语言读文件性能大比拼

August 28th, 2013 26 comments

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

本文链接地址: erlang和其他语言读文件性能大比拼

百岁同学说:

今天公司技术比武,比赛题目是给一个1.1g的大文本,统计文本中词频最高的前十个词。花了两天用erlang写完了代码,但是放到公司16核的机器上这么一跑,结果不比不知道,一比吓一条。erlang写的代码执行时间花了55秒左右,同事们有的用java,有的用C,还有的用C++,用C最快一个老兄只花了2.6秒,用java的也只用了3.2秒。相比之下erlang的代码,真是一头大蜗牛,太慢了。

详细参见这篇文章:http://www.iteye.com/topic/1131748

读取文件并且分析这是很多脚本语言如perl, python,ruby经常会干的事情.这个同学的问题是很普遍的问题,不只一个人反映过慢的问题。
今天我们来重新来修正下这个看法, 我们用数据说话。

首先我们来准备下文件, 这个文件是完全的随机数,有1G大小:

$ dd if=/dev/urandom  of=test.dat count=1024 bs=1024K
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 188.474 s, 5.7 MB/s
$ time dd if=test.dat of=/dev/null 
2097152+0 records in
2097152+0 records out
1073741824 bytes (1.1 GB) copied, 1.16021 s, 925 MB/s

real    0m1.162s
user    0m0.219s
sys     0m0.941s
$ time dd if=test.dat of=/dev/null bs=1024k
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB) copied, 0.264298 s, 4.1 GB/s

real    0m0.266s
user    0m0.000s
sys     0m0.267s

我们准备了1G大小左右的文件,由于用的是buffered io, 数据在准备好了后,全部缓存在pagecache里面,只要内存足够,这个测试的性能和IO设备无关。 我们试着用dd读取这个文件,如果块大小是4K的话,读取这个文件花了1.16秒,而如果块大小是1M的话,0.26秒,带宽达到4.1GB每秒,远超过真实设备的速度。

那么我们用erlang来读取下这个文件来比较下,我们有三种读法:
1. 一下子读取整个1G文件。
2. 一个线程一次读取1块,比如1M大小,直到读完。
3. 多个线程读取,每个读取一大段,每次读取1M块大小。
然后比较下性能。

首先普及下背景:
1. erlang的文件IO操作由efile driver来提高,这个driver内部有个线程池,大小由+A 参数控制,所以IO是多线程完成的。
2. erlang的文件分二种模式: 1. raw模式 2. io模式 在raw模式下,数据直接由driver提供给调用进程, io模式下数据先经过file_server做格式化,然后再给调用进程。
3. 数据可以以binary和list方式返回,list方式下文件内容的byte就是一个整数,在64位机器上占用8个字节内存。
Read more…

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

erlang关键的环境变量

August 23rd, 2013 Comments off

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

本文链接地址: erlang关键的环境变量

Erlang新增全面的系统信息收集器-system_information模块 这个模块列出来以下的环境变量,对系统运行非常关键,你都了解吗?

+%% get known useful erts environment
+
+os_getenv_erts_specific() ->
+ os_getenv_erts_specific([
+ “BINDIR”,
+ “DIALYZER_EMULATOR”,
+ “CERL_DETACHED_PROG”,
+ “EMU”,
+ “ERL_CONSOLE_MODE”,
+ “ERL_CRASH_DUMP”,
+ “ERL_CRASH_DUMP_NICE”,
+ “ERL_CRASH_DUMP_SECONDS”,
+ “ERL_EPMD_PORT”,
+ “ERL_EMULATOR_DLL”,
+ “ERL_FULLSWEEP_AFTER”,
+ “ERL_LIBS”,
+ “ERL_MALLOC_LIB”,
+ “ERL_MAX_PORTS”,
+ “ERL_MAX_ETS_TABLES”,
+ “ERL_NO_VFORK”,
+ “ERL_NO_KERNEL_POLL”,
+ “ERL_THREAD_POOL_SIZE”,
+ “ERLC_EMULATOR”,
+ “ESCRIPT_EMULATOR”,
+ “HOME”,
+ “HOMEDRIVE”,
+ “HOMEPATH”,
+ “LANG”,
+ “LC_ALL”,
+ “LC_CTYPE”,
+ “PATH”,
+ “PROGNAME”,
+ “RELDIR”,
+ “ROOTDIR”,
+ “TERM”,
+ %”VALGRIND_LOG_XML”,
+
+ %% heart
+ “COMSPEC”,
+ “HEART_COMMAND”,
+
+ %% run_erl
+ “RUN_ERL_LOG_ALIVE_MINUTES”,
+ “RUN_ERL_LOG_ACTIVITY_MINUTES”,
+ “RUN_ERL_LOG_ALIVE_FORMAT”,
+ “RUN_ERL_LOG_ALIVE_IN_UTC”,
+ “RUN_ERL_LOG_GENERATIONS”,
+ “RUN_ERL_LOG_MAXSIZE”,
+ “RUN_ERL_DISABLE_FLOWCNTRL”,
+
+ %% driver getenv
+ “CALLER_DRV_USE_OUTPUTV”,
+ “ERL_INET_GETHOST_DEBUG”,
+ “ERL_EFILE_THREAD_SHORT_CIRCUIT”,
+ “ERL_WINDOW_TITLE”,
+ “ERL_ABORT_ON_FAILURE”,
+ “TTYSL_DEBUG_LOG”
+ ]).

翻文档吧,都是很有意思的控制参数。

祝玩得开心!

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

Categories: Erlang探索, 源码分析 Tags:

再谈crashdump产生注意事项

August 23rd, 2013 Comments off

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

本文链接地址: 再谈crashdump产生注意事项

在前面的博文里面,我们提到了crashdump的作用, 以及看门狗heart的工作原理,我们可以在程序crash后,让heart看门狗重新帮我们拉起来。

这里有几个问题需要注意:
1. 看门狗检查失效的时间,默认是65秒。
2. erlang系统在crash的时候会记录crashdump, 操作系统会产生coredump, 这个时间到底是多长。

代码证明如下:

/* heart.c */
...
/*  Maybe interesting to change */
/* Times in seconds */
#define  HEART_BEAT_BOOT_DELAY       60  /* 1 minute */
#define  SELECT_TIMEOUT               5  /* Every 5 seconds we reset the                                                  
                                            watchdog timer */

/* heart_beat_timeout is the maximum gap in seconds between two                                                           
   consecutive heart beat messages from Erlang, and HEART_BEAT_BOOT_DELAY                                                 
   is the the extra delay that wd_keeper allows for, to give heart a                                                      
   chance to reboot in the "normal" way before the hardware watchdog                                                      
   enters the scene. heart_beat_report_delay is the time allowed for reporting                                            
   before rebooting under VxWorks. */

int heart_beat_timeout = 60;
int heart_beat_report_delay = 30;
int heart_beat_boot_delay = HEART_BEAT_BOOT_DELAY;
...

这二个时间都会影响系统重新启动的间隔时间。
而crashdump的dump文件名、dump时间和优先级由下面几个变量来控制:

ERL_CRASH_DUMP
If the emulator needs to write a crash dump, the value of this variable will be the file name of the crash dump file. If the variable is not set, the name of the crash dump file will be erl_crash.dump in the current directory.

ERL_CRASH_DUMP_NICE
Unix systems: If the emulator needs to write a crash dump, it will use the value of this variable to set the nice value for the process, thus lowering its priority. The allowable range is 1 through 39 (higher values will be replaced with 39). The highest value, 39, will give the process the lowest priority.

ERL_CRASH_DUMP_SECONDS
Unix systems: This variable gives the number of seconds that the emulator will be allowed to spend writing a crash dump. When the given number of seconds have elapsed, the emulator will be terminated by a SIGALRM signal.

If the environment variable is not set or it is set to zero seconds, ERL_CRASH_DUMP_SECONDS=0, the runtime system will not even attempt to write the crash dump file. It will just terminate.

If the environment variable is set to negative valie, e.g. ERL_CRASH_DUMP_SECONDS=-1, the runtime system will wait indefinitely for the crash dump file to be written.

This environment variable is used in conjuction with heart if heart is running:

ERL_CRASH_DUMP_SECONDS=0
Suppresses the writing a crash dump file entirely, thus rebooting the runtime system immediately. This is the same as not setting the environment variable.

ERL_CRASH_DUMP_SECONDS=-1
Setting the environment variable to a negative value will cause the termination of the runtime system to wait until the crash dump file has been completly written.

ERL_CRASH_DUMP_SECONDS=S
Will wait for S seconds to complete the crash dump file and then terminate the runtime system.

如果我们不想产生coredump 可以透过 -env ERL_CRASH_DUMP_SECONDS 0 来关掉,避免产生dump时间过长的悲剧。同时每次crashdump产生的文件名相同,可以在启动通过 -env ERL_CRASH_DUMP erl_crash_date_time.dump 来修改,避免覆盖掉。

祝玩得开心!

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

Categories: Erlang探索, 源码分析 Tags:

Erlang heart – 高可靠性的最后防线

August 23rd, 2013 Comments off

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

本文链接地址: Erlang heart – 高可靠性的最后防线

我们写的程序不可能都没有bug, 都存在crash的危险。很多时候我们需要个看门狗(watchdog)程序,在发现系统不正常的时候,就把系统重新启动。这类watchdog程序从内核到各种高可用程序都会设置有一个。erlang系统当然不能免俗,也会有几个heart.

我们来看下流程和效果:

$ export HEART_COMMAND="erl -heart"
$ erl -heart
heart_beat_kill_pid = 12640
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:16:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.3.1  (abort with ^G)
1> os:getpid().
"12640"
2> 
CTRL + Z 挂起erlang

$ pstree -p

+-beam.smp(12640)-+-heart(12670)
| | | |-{beam.smp}(12647)
| | | |-{beam.smp}(12648)
| | | |-{beam.smp}(12650)
| | | |-{beam.smp}(12653)
| | | |-{beam.smp}(12654)
| | | |-{beam.smp}(12655)
| | | |-{beam.smp}(12656)
| | | |-{beam.smp}(12657)
| | | |-{beam.smp}(12658)
| | | |-{beam.smp}(12659)
| | | |-{beam.smp}(12660)
| | | |-{beam.smp}(12661)
| | | |-{beam.smp}(12662)
| | | |-{beam.smp}(12663)
| | | |-{beam.smp}(12664)
| | | |-{beam.smp}(12665)
| | | |-{beam.smp}(12666)
| | | |-{beam.smp}(12667)
| | | |-{beam.smp}(12668)
| | | `-{beam.smp}(12669)
| | `-pstree(13702)

$ heart: Fri Aug 23 20:36:25 2013: heart-beat time-out, no activity for 65 seconds
heart_beat_kill_pid = 27920

我们看到erl重新被启动起来了。 现在简单的分析下原理:
heart由2部份组成:1. 外部程序: heart 2. erlang port模块: heart.erl

当开启heart的时候(erl – heart …) 外部程序heart被erlang模块heart.erl作为独立的进程启动起来,监视emulator的运作. heart.erl 每隔一定的时间向heart外部程序报告状态。当外部heart没有监测到心跳的时候就要采取行动, 重新运行$HEART_COMMAND所指定的命令。
Read more…

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

Categories: Erlang探索, 源码分析 Tags:

application之染色特性分析和应用

August 18th, 2013 Comments off

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

本文链接地址: application之染色特性分析和应用

我们知道典型的erlang虚拟机里面会运行好多application,这些app互相依赖,相互协作,形成一个生态圈。典型场景见下图:

Screen Shot 2013-08-18 at 3.22.01 PM

每个app里面都会有很多进程,这些进程为这个app负责,会有些共同特性。那么这些进程如何区分出来属于哪个app的呢?就像我们伟大的祖国,有56个民族一样,这些民族都有自己的文化、服饰,甚至相貌,一看就和其他族群不太一样。他们的基因里面就携带了某种东西,这些东西子子孙孙传下去,一直保持下去。那么同样的,每个app里面的进程就和我们人,一样也会生老病死,也会有生命周期。他们是靠什么来识别的呢? 典型的application里面有很多层次的进程,通常成树状,和我们人类的组织差不多,见下图:

Screen Shot 2013-08-18 at 3.21.45 PM

我们先来看下application的文档和关键的几个函数:

which_applications() -> [{Application, Description, Vsn}]
Returns a list with information about the applications which are currently running. Application is the application name. Description and Vsn are the values of its description and vsn application specification keys, respectively.

示例如下:

1> application:which_applications().
[{os_mon,”CPO CXC 138 46″,”2.2.9″},
{sasl,”SASL CXC 138 11″,”2.2.1″},
{stdlib,”ERTS CXC 138 10″,”1.18.3″},
{kernel,”ERTS CXC 138 10″,”2.15.3″}]

我们可以看到我们运行的几个app的名字,版本号,描述等基本信息,再细节的就没有了。那第一,二个图中的这些信息是哪里来的呢?

Read more…

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

Erlang新增全面的系统信息收集器-system_information模块

July 29th, 2013 Comments off

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

本文链接地址: Erlang新增全面的系统信息收集器-system_information模块

Erlang其实是个操作系统,从下面的图可以看出它的架构:

erlang-vm

erlang系统设计的时候是完全按照unix的理念来平行移植的,它的引导进程叫otp_ring0,第一个进程叫init,有没有感觉很熟悉?
既然是一个操作系统,那么这个系统就是一个非常复杂的系统。erlang vm运行的时候是以unix的进程方式体现的,然后这个进程本身是个小世界,这个世界会跑着很多application,每个application包含配置,数据,模块代码等,多个applcaiton之间相互协作,完成指定的业务目标。

当我们的业务系统出现不按预期执行的时候,那么问题出在哪里呢?我们如何调查呢?
首先erlang当然提供了非常多的调查类的函数,如erlang:system_info,erlang:memory,os:getenv等提供各种各样的信息。但是问题是这些信息是散落在各地的,很难汇集起来提供全面的诊断信息。

官方在最近也认识到了这个问题,在最新的R16版本添加了system_information模块来解决这个问题,具体的patch参考 这里

这个patch总的来讲做了三件比较大的事情:

1. Add system information aggregate
2. Add erts app-file
3. erts: Add cflags, ldflags and config.h into executable

除聚合信息以外,还有一个就是把编译beam的时候的配置, cflags, ldflags 什么的都聚合进去。因为beam vm是依靠操作系统提供各种服务的,如锁,原子,epoll,网络等服务,这些服务每个系统都是不太一样的,出了问题很有必要先调查这些结合处。

新增加的system_information模块位于runtime_tools应用中,它的注释里面也写的清楚:

%% The main purpose of system_information is to aggregate all information
%% deemed useful for investigation, i.e. system_information:report/0.

简单的分析下代码,它聚合的信息主要有以下几块:
Read more…

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

webtool小问题

July 29th, 2013 Comments off

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

本文链接地址: webtool小问题

erlang的观察工具如crashdump,appmon,cover等工具有二种不同的界面:gs(wx)和web。这些tool都遵循一定的接口,用户可以自行扩展这些功能,使的能够融入toolbar或者webtool体系。 其中webtool在线上使用的时候比较方便,因为是web界面,容易过防火墙什么的。

webtool的使用界面如下:
webtool
但是默认的webtool在启动的时候,默认只在127.0.0.1:8888网络上监听,无法在其他机器上查看状态,这样使用起来很不方便。

演示下:

$ erl
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:16:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.3.1  (abort with ^G)
1> webtool:start().
WebTool is available at http://localhost:8888/
Or  http://127.0.0.1:8888/
{ok,<0.35.0>}
2> 

粗粗的研究下webtool的启动代码,可以透过下面的方式来绕开这个问题,注意下面这三个参数都需要的,具体的值用户自己配:

webtool:start(standard_path, [{bind_address, {0,0,0,0}},{port, 8888},{server_name, “foobar”}]).

这种方式默认是全部接口监听:

$ hostname -i
10.232.64.76

看下具体的网卡地址就可以访问到服务了,本例子中是: http://10.232.64.76:8888

祝玩的开心!

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

Categories: Erlang探索, 源码分析 Tags: