標籤:des style blog http color 使用
[Erl_Question11] Mnesia分布式應用樣本
情景:
設計一個圖書管理系統,需求:
1. 基本的增刪查改功能;
2. 支援多節點備份(其中一個節點掛了進,對外介面不影響)。
方案一:
Erlang 代碼如下:https://gist.github.com/zhongwencool/28f7db8d52134b082f97
啟動shell:
erl -name [email protected]127.0.0.1 -pa "../ebin/" -setcookie best -run cloud_server start_link erl -name [email protected]127.0.0.1 -pa "../ebin/" -run deal_book_server -extra [email protected]127.0.0.1 erl -name [email protected]127.0.0.1 -pa "../ebin/" -run deal_book_server -extra [email protected]127.0.0.1
.......
erl -name [email protected]127.0.0.1 -pa "../ebin/" -run deal_book_server -extra [email protected]127.0.0.1
Tip: 實現的關鍵在於:每個節點起來後會自動連接到Cloud Center Node 上,並在每15scheck一下與Cloud的串連,Cloud時刻保證最新了節點串連狀態資料,並定時廣播給連上來的所有節點。
如果你自己寫完這個例子,就會對節點互接有更深認識。
方案二:
使用Mnesia的分布特性:
1. 首先我們來實現一個簡單的1+1(一個資料處理節點 + 一個備份節點)
-module(db_sync). -author("[email protected]"). %% API -export([create_schema/0, create_table/0,i/0]). -export([add_account/3,del_account/1,read_account/1]).
-record(account, {id = 0, name = "", phone = 138000001}). create_schema() –> net_kernel:connect(‘[email protected]‘), io:format("Self:~w,Connect Nodes:~w",[node(),nodes()]), mnesia:create_schema([node()|nodes()]). create_table() –> mnesia:create_table(account, [{disc_copies,[node()|nodes()]}, {attributes, record_info(fields, account)}] ). %%查看資料庫狀態 i() –> mnesia:system_info(). add_account(ID, Name, Phone) –> mnesia:transaction( fun() –> mnesia:write(#account{id = ID, name = Name, phone = Phone}) end). del_account(ID) –> mnesia:transaction( fun() –> mnesia:delete({account, ID}) end). read_account(ID) –> mnesia:transaction( fun() –> mnesia:read({account, ID}) end).
1.1 在xterm 1中:
> erl erl -sname one -mnesia dir "one"
1.2 在xterm 2中:
> erl -sname two -mnesia dir "two" > db_sync:create_schema().
1.3 分別在one shell ,two shell中啟動mnesia
> mnesia:start().
1.4 在任意節點中建立account表
> db_sync:create_table().
這裡的account表就是one , two 節點所共用的了,你可以在節點one上增加一個資料,在節點two上查詢這個資料,對於使用者來說:這完全是透明的!!
1.5 Test:
one 節點上增加資料:
two 節點上查詢資料:
2. 節點one掛了後,重啟怎麼把從two資料同步到節點one?
節點one重啟後把資料庫表重建立一次就可以啦,如果資料在one掛掉至重啟過程中在節點two上發生了變化了,也可以使用mnesia:add_table_copy來做到資料同步。
相信如果掌握了mnesia這2個特性,就可以實現比方案一更加簡潔的分布系統啦!
看Mnesia文檔裡發現一個有意思的點:
是不是覺得mnesia只有使用一個key(當然你可以使用複雜的match運算式來做實現複雜查詢條件),但因為match的效率比較低,所有如果你頻繁的使用,是不推薦的,這裡你應該看看下面這個函數:可以增加一個index哦!【真福利】
add_table_index(Tab, AttrName) -> {aborted, R} | {atomic, ok}
Table indices can and should be used whenever the user wants to frequently use some other field than the key field to look up records. If this other field has an index associated with it, these lookups can occur in constant time and space. For example, if our application wishes to use the name field of accountto efficiently find all account with a specific name, it might be a good idea to have an index on the namefield. This can be accomplished with the following call:
mnesia:add_table_index(account, name).
Indices do not come free, they occupy space which is proportional to the size of the table. They also cause insertions into the table to execute slightly slower.
這樣做總比再做一張表來對應Id和Name好多了。
個人覺得Mnesia的源碼寫得真好,值得精讀.