Erlang---啟動引數學習/研究
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
erlang啟動引數有3種:emulator flags, flags 和plain arguments。
emulator flags 是以“+”開頭的,用來控制模擬器的行為,附送一個非常實用的例子:
相關閱讀:http://www.linuxidc.com/Linux/2011-07/39156.htm
- C:\>erl +V
- Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 5.8.2
flags 是以“-”開頭的, 是erlang執行時系統的引數,可以用init:get_argument/1獲得。
plain arguments 普通引數,在第一個flag引數前,或在-- flag之後,-extra後的引數都是普通引數。
- </pre><p><span class="bold_code">erl +W w -sname arnie +R 9 -s my_init -extra +bertie</span></p><p><strong></strong> </p><pre class="plain" name="code">% erl +W w -sname arnie +R 9 -s my_init -extra +bertie
- ([email protected])1> init:get_argument(sname).
- {ok,[["arnie"]]}
- ([email protected])2> init:get_plain_arguments().
- ["+bertie"]
Here +W w and +R 9 are emulator flags.-s my_init is an init flag, interpreted by init. -sname arnie is a user flag, stored by init. It is read by Kernel and will cause the Erlang runtime system to become distributed. Finally, everything after-extra (that is, +bertie) is considered as plain arguments.
Flags
-Application Par Val 把應用中的Par引數設定為值Val;
-args_file FileName 從檔案FileName讀取命令列引數;
-boot File 指定啟動使用的boot檔案,預設是 $ROOT/bin/start.boot,在這個目錄下還有start_clean.boot,start_sasl.boot。如果需要sasl的話,就“-boot start_sasl ”; -boot_var Var Dir 代替$ROOT用的;-code_path_cache 不常用;
-compile Mod1 Mod2 ... 不推薦使用了,應該使用erlc;
-config Config 指定配置檔案,這個是很有用的,比如在Programming Erlang裡,就用到 erl -boot start_sasl -config elog3,其中檔案全名是elog3.config,內容如下:- %% rotating log and minimal tty
- [{sasl,[
- {sasl_error_logger,false},
- %%define the parameters of the rotating log
- %%the log file directory
- {error_logger_mf_dir,"D:/erlang/otpexample/error_logs"},
- %% # bytes per log file
- {error_logger_mf_maxbytes,10485760}, %10 MB
- %%maximum number of logfiles
- {error_logger_mf_maxfiles,10}
- ]}].
配置的含義,請參考相關書籍;
-cookie Cookie 被-setcookie代替了;
-detached 脫離console,跑後臺erlang程序用的,看做"nohup **** &";
-emu_args debug用的,打印出實際傳給模擬器的值;
-env Variable Value 設定作業系統環境變數用的,比如:
- erl -env DISPLAY gin:0
-eval Expr(init flag) 表示式做啟動引數,比如(下列程式碼在本機執行出錯,以後再研究):
- % erl -eval '{X,Y,Z}' = now(), random:seed(X,Y,Z).'
-id Id 給erlang程序設定一個id,一般和-sname 和-name一起用;
-init_debug 在啟動/初始化erlang程序時,列印debug資訊; -instr -loader Loader 為 erl_prim_loader指定裝載模組的方法,相當於java裡指定classloader; -make -man Module -mode interactive | embedded -name Name 給一個erlang節點/程序設定一個名稱 -noinput -noshell -nostick
-pa Dir1 Dir2 ...
-pz Dir1 Dir2 ... -remsh Node 遠端啟動一個erlang節點,比如(當然RSA神馬的,要先搞定):- erl -sname node1 -remsh [email protected]
- erl -setcookie SFEWRG34AFDSGAFG35235 -name nodex
並且它是執行時可以改的:
- erlang:set_cookie(node(), 'SFEWRG34AFDSGAFG35235').
-shutdown_time Time 關閉節點需要的時間,如果超過,就直接kill,預設是infinity;
Emulator Flags
+a size 一般實用預設值就可以了。
Suggested stack size, in kilowords, for threads in the async-thread pool. Valid range is 16-8192 kilowords. The default suggested stack size is 16 kilowords, i.e, 64 kilobyte on 32-bit architectures. This small default size has been chosen since the amount of async-threads might be quite large. The default size is enough for drivers delivered with Erlang/OTP, but might not be sufficiently large for other dynamically linked in drivers that use thedriver_async() functionality. Note that the value passed is only a suggestion, and it might even be ignored on some platforms.
+A size 一步執行緒池的大小,預設是0;比如執行werl +A 1,會看到:
- Erlang R14B01 (erts-5.8.2) [smp:2:2] [rq:2] [async-threads:1]
- Eshell V5.8.2 (abort with ^G)
+B [c | d | i]
+d 預設情況下erlang程序遇到內部錯誤,比如oom,會產生一個crash dump和core dump,+d讓節點只產生後者;
+e Number ETS表的最大數量; +ec強制ETS表啟動壓縮,一般不用的; +fnl 如果檔名使用了ISO-latin-1編碼; +fnu如果檔名使用了UTF-8 編碼;+fna 和當前作業系統一致;
+hms Size 指定erlang程序的預設(最小?)堆記憶體大小(這個應該不用太擔心); +hmbs Size 程序預設二進位制虛擬記憶體堆大小; +K true | false 是否開啟kernel poll,就是epoll; +l +MFlag Value+P Number erlang節點系統的最大併發程序數;
+R ReleaseNumber
+r
+rg ReaderGroupsLimit Limits the amount of reader groups used by read/write locks optimized for read operations in the Erlang runtime system. By default the reader groups limit equals 8.
+S Schedulers:SchedulerOnline
+sFlag Value
+t size
+T Level
+V 模擬器版本號
+v verbose+W w | i
+zFlag ValueEnvironment variables
ERL_CRASH_DUMP
ERL_CRASH_DUMP_NICE
ERL_CRASH_DUMP_SECONDS
ERL_AFLAGS
ERL_ZFLAGS 和 ERL_FLAGS
ERL_LIBS
ERL_EPMD_PORT
關於Erlang和SMP的一些說明
by.Kenneth Erlang/OTP team, Ericsson
譯:ShiningRay
以下是一些Erlang SMP實現的細節和與效能與伸縮性相關一些簡單介紹。
幾周之內還有有一個關於多核如何運作以及未來如何發展的更詳細的介紹。我打算將一些內容放在我的報告中,將於9月27日的ICFP2008,Erlang Workshop在Victoria BC展示給大家。
沒有SMP支援的Erlang VM只有1個執行在主處理執行緒中的排程器。該排程器從執行佇列(run-queue)中取出可以執行的Erlang程序以及IO任務,而且因為只有一個執行緒訪問他們所以無須鎖定任何資料。
而帶有SMP支援的Erlang VM可以有一個或多個排程器,每個執行在一個執行緒中。排程器從同一個公共執行佇列中取出可執行的Erlang程序和IO任務。在SMP VM中所有的共享資料結構都會由鎖進行保護,執行佇列就是這樣一個由鎖保護的資料結構。
從OTP R12B開始,如果作業系統報告有多於1個的CPU(或者核心)VM的SMP版本會自動啟動,並且根據CPU或者核心的數量啟動同樣數量的排程器。
你可以從“erl”命令打印出來的第一行看到它選擇了哪些引數。例如:
Erlang (BEAM) emulator version 5.6.4 [source] [smp:4] [asynch-threads:0] …..其中“[smp:4]”表示SMP VM運行了4個排程器。
預設值可以用“-smp [enable|disable|auto]”來替換,auto是預設的。如果smp被啟用了(-smp enable),要設定排程器的數量可以使用“+S Number”其中Number是排程器的數量(1到1024)
注意1:執行多於CPU或核心總數的排程器不會有任何提升。
注意2:在某些作業系統中一個程序可使用的CPU或者核心的數量可以被限制。例如,在Linux中,命令“taskset”就可以實現這個功能。Erlang VM目前還只能探測CPU或者核心的總數,不會考慮“taskset”所設定的掩碼。正因如此,例如可能會出現(已經出現過了)即使Erlang VM運行了4個排程器,也只使用了2個核心。OS會進行限制因為它要考慮“taskset”所設定的掩碼。
每個Erlang VM的排程器都運行於一個OS執行緒上,是OS來決定執行緒是否執行在不同的核心上。一般來說OS會很好地處理這個問題並且會保證執行緒在執行期間運行於同一個核心上。
Erlang程序會被不同的排程器執行,因為他們是從一個公共執行佇列中被取出,由首先可用的排程器執行。
效能和伸縮性
只有一個排程器的SMP VM要比非SMP的VM稍微慢那麼一點點。SMP VM內部需要用到各種鎖,不過只要不存在鎖的爭用,那麼由鎖引起的開銷不會非常大(就是鎖爭用上面需要花時間)。這也解釋了為何在某些情況下,執行多個只有一個排程器的SMP VM要比包含多個排程器的單一SMP VM更加高效。當然執行多個VM要求應用可以按照多個並行任務的方式執行並且之間沒有或者幾乎不通訊。
一個程式是否能在多核上的SMP VM中良好地進行提升很大程度上取決於程式的性質,某些程式可以保持線性提升至8核甚至16核,同時其他某些程式基本不能提升,連2核都不行。實際應用中很多程式都能在主流市場的核心數上得到提升,見下文。
若並行的持續“通話”由每個核心一個或多個Erlang程序來表示,實際的支援大量通話的電信產品已經先現出在雙核和四核處理器上不俗的伸縮性。注意,這些產品是在SMP VM和多核處理器出現很久以前按照普通的Erlang風格來寫的,他們也能無須任何修改甚至不需重新編譯程式碼就能從Erlang SMP VM中獲益。
SMP效能得到持續改進
SMP實現正被不斷改進以便能得到更好的效能和伸縮性。在每個服務釋出版R12B-1,2,3,4,5…,R13B等等中,你都能發現新的優化。
一些已知的瓶頸
單一的常見執行佇列隨著CPU或核心的數量的增加會成為一個顯著的瓶頸。
這從4核開始往上就會顯現出來,不過4核仍然可以為多數應用程式提供不錯的效能。我們正在從事一個每個排程器一個執行佇列的解決方法作為目前最重要的改進。
Ets表格會引入鎖。在R12B-4之前在每次對一個ets-table的訪問中會用到兩個鎖,但是在R12B-4中meta-table的鎖被優化過,可以顯著減少爭用(前面已經提到爭用是有很大代價的)。如果很多Erlang程序訪問同一個表格,就會有很多鎖爭用造成效能降低尤其當這些程序主要工作是訪問ets-table。鎖存在於表級而非記錄級。注意!這也會影響到Mnesia因為Mnesia用到了很多ets-table。
我們關於SMP的策略
當我們開始實現SMP VM的最初,我們就確定了策略:“首先讓它可以執行,然後測量,然後優化”。自從2006年五月我們釋出了第一個穩定的SMP VM(R11B)以來,我們一直遵循著這個策略。
還有更多已知的東西可以改進,我們會按照效能的收益大小先後各個擊破。
我們將主要的精力放在多核(大於4)上更好的連續伸縮性上。
卓越典範
即使SMP系統有還有一些已知的瓶頸不過已經有不錯的整體效能和伸縮性,同時我相信在讓程式設計師利用多核機器事半功倍方面,我們是一個卓越的典範。
Erlang叢集節點集合的啟動
一、配置SSH客戶端:無需密碼的連線1. SSH客戶端RSA key授權
i). 生成SSH RSA key:
ssh-keygen -t rsa
全回車取預設,將在~/.ssh目錄下將生成id_rsa和id_rsa.pub倆檔案
ii) 將生產的公共RSA key拷貝到目標機器上:
a).將id_rsa.pub檔案拷貝到目標機器上:
scp ~/.ssh/id_rsa.pub [email protected]_server:id_rsa.pub
b). ssh登陸目標機器,在目標機器的~/.ssh目錄下生成檔案內容:
cat id_rsa.pub >>$HOME/.ssh/authorized_keys
刪掉id_rsa.pub
以上兩步命令可以用一條命令實現:
ssh-copy-id ssh2-server
本質上都是把master上生成的id_rsa.pub檔案拷貝到slave機器./ssh目錄下,同時改名為authorized_keys
這一步完成後,從master機器上登入slave機器直接
ssh slave
就行了,不用輸入密碼。
同樣的,slave到master也得這樣:不用輸入密碼直接ssh
叢集內所有的機器相互之間都要這樣實現無密碼輸入就能直接ssh
2. 在啟動master節點的那個機器上,啟動SSH-agent軟體並新增你的使用者ID
這樣每次連線時就不需要passphrase了,辦法是讓ssh-agent記住你
i) 首先確認你的機器上有ssh-agent在執行(一般都沒有)
ps aux|grep ssh-agent
檢視ssh-agent執行在當前視窗管理器(或者shell)下
pstree
如果不是,在shell中建立一個ssh-agent會話:
ssh-agent screen
這回啟動了一個帶ssh-agent的screen會話視窗,以後這個screen控制檯內的所有命令都要經過ssh-agent
ii) 新增你的ID
ssh-add
你可以檢視當前ssh-agent中已新增的ID
ssh-add -l
也可以刪除一個ID
ssh-add -d
3. 叢集的路由進出
當建立集群后,經常需要訪問作為閘道器(或者負載均衡器)的前端計算機。要訪問其它節點,你需要告訴作為網管的機器將你的請求路由到機器節點中。
例如,假設你的閘道器是80.65.232.137。控制用的計算機在叢集之外,這個機器是操作員用於控制叢集的計算機。叢集內部網路是192.0.0.0。在你的客戶計算機上,啟動命令:
route add -net 192.0.0.0 gw 80.65.232.137 netmask 255.255.255.0
這個命令需要確保閘道器計算機上IP forwarding 可用
要確保正確的路由,可以維護一個常用的/etc/hosts檔案,該檔案中記錄了你的叢集中的所有計算機,例子中,叢集有7臺計算機組成.
10.9.195.12 controler
80.65.232.137 gateway
192.0.0.11 eddieware
192.0.0.21 yaws1
192.0.0.22 yaws2
192.0.0.31 mnesia1
192.0.0.32 mnesia2
也可以設定DNS伺服器,但對小網路來說/etc/hosts檔案就已經足夠了
二、啟動Erlang master節點並建立Erlang叢集
一旦通過SSH連線叢集不再提示輸入密碼後建立一個Erlang叢集將變得非常容易。
1. 啟動Erlang master節點的模組:
Erlang程式碼
- -module(cluster).
- -export([slaves/1]).
- %% Argument:
- %% Hosts: List of hostname (string)
- slaves([]) ->
- ok;
- slaves([Host|Hosts]) ->
- Args = erl_system_args(),
- NodeName = "cluster",
- {ok, Node} = slave:start_link(Host, NodeName, Args),
- io:format("Erlang node started = [~p]~n", [Node]),
- slaves(Hosts).
- erl_system_args()->
- Shared = case init:get_argument(shared) of
- error -> " ";
- {ok,[[]]} -> " -shared "
- end,
- lists:append(["-rsh ssh -setcookie ",
- atom_to_list(erlang:get_cookie()),
- Shared, " +Mea r10b "]).
- %% Do not forget to start erlang with a command like:
- %% erl -rsh ssh -sname clustmaster
啟動master
- [email protected]:~/cvs/cluster$ erl -rsh ssh -sname demo
- Erlang (BEAM) emulator version 5.3 [source] [hipe]
- Eshell V5.3 (abort with ^G)
- ([email protected])1> cluster:slaves(["gateway", "yaws1", "yaws2", "mnesia1", "mnesia2", "eddieware"]).
- Erlang node started = [[email protected]]
- Erlang node started = [[email protected]]
- Erlang node started = [[email protected]]
- Erlang node started = [[email protected]]
- Erlang node started = [[email protected]]
- Erlang node started = [[email protected]]
- ok
這裡的要點是:叢集間所有節點(至少是master對所有slave節點)之間都要能實現“相互”無密碼輸入的ssh登入
我想無密碼輸入的原理可能是:
機器A生成RSA key,有一個公開的金鑰,別的機器B要想無密碼ssh這同機器,B必須在本地擁有A的公開金鑰