mnesia数据库学习笔记四
雜項
前二章講了如何啟動數(shù)據庫,如何構建數(shù)據庫,接下來會為講一些創(chuàng)建分布式容錯數(shù)據所需的高級特征:
- 索引
- 分布式和容錯
- 表分段
- 本地內容表
- 無磁盤節(jié)點
- 高級方案管理
- 調用應用程序
- 并行進程
- 原形研究
- 基于對象的編程
1、索引
如果數(shù)據添加索引,那位定位會很快,如果沒有索引,就需要遍歷表,可能會消耗較長時間。Mnesia提供了如下兩個函數(shù)操作索引:
mnesia:add_table_index(Tab, AttributeName)
mnesia:delete_table_index(Tab,AttributeName)
可能通過如下函數(shù)進行索引查找:
mnesia:index_read(Tab, SecondaryKey, AttributeName) mnesia:index_match_object(Pattern, AttributeName) mnesia:match_object(Pattern)’
2、分布式和容錯
mnesia提供了多種方式把表復制到多個不同的Erlang節(jié)點上。編程人員除表名不用關心表的具體在那個節(jié)點上。實現(xiàn)具體位置透明化。(當然如果數(shù)據在遠程節(jié)點,處理會慢一點), 數(shù)據庫可以反復配置, 表可以在節(jié)點間移動。這并不影響編程人員。
以下是創(chuàng)建一個表,帶有兩個復件:
??? mnesia:create_table(foo,
??????????????????????? [{ram_copies, [N1, N2]},
???????????????????????? {attributes, record_info(fields, foo)}]).
?
表可能擁有如下類型,每個類型都可以有一個Erlang節(jié)點列表:
ram_copies,RAM復件會在每個節(jié)點上存在。可以通過mnesia:dump_table函數(shù)將RAM表保存到磁盤上。
disc_copies,表復件會在每個節(jié)點的內存和磁盤上存在。寫操作會影響RAM和磁盤。
disc_only_copies,表復件只會出在各節(jié)點的磁盤上。會影響訪問速度,但會節(jié)約內存。
運行時也是可以修改表屬性的。使用表復件有兩個原因, 容錯和速度。如果我們擁有兩個活動節(jié)點, 任一節(jié)點故障后,復件節(jié)點仍然可用。 此外,假如一個表存在兩個節(jié)點,應用程序在任一節(jié)點上讀數(shù)據而無需訪問網絡。網絡訪問意味著比本地操作低效。
對于數(shù)據經常讀,而少量寫的應用,表復件是非常具有優(yōu)勢的。劣勢就是增加了寫操作時間。假如一個表有兩個復件,每一個寫操作必需訪問兩個表復件。甚至其中一個寫操作為網絡操作。消耗比非復件表大很多。
3、表片段
?表片段主用于應對超大表。其核心就是把一個表分隔成多個可控表片段。每個片段被實現(xiàn)為第一級的Mnesia表,就像普通表一樣,可以復件,可以索引等。但是不能擁有l(wèi)ocal_content和snmp活動連接。
mnesia提供了mnesia_frag模塊, 實現(xiàn)了mnesia_access回調行為用于訪問片該記錄。
在訪問記錄前,mnesia_frag先計算記錄鍵值的hash值 ,然后通過hash值確定表片段名字。最終就像普通表一樣進行訪問處理。如果不能預先知道記錄鍵值, 需要在所有表片段中進行匹配。注,在ordered_set表中,記錄在表片段內進行排序。select 和match_object等函數(shù)的返回結果也是無序的。如下就是展示了如何將一個現(xiàn)存表轉換成片段表,如何添加更多表片段。
?
Eshell V4.7.3.3? (abort with ^G)(a@sam)1> mnesia:start().
ok
(a@sam)2> mnesia:system_info(running_db_nodes).
[b@sam,c@sam,a@sam]
(a@sam)3> Tab = dictionary.
dictionary
(a@sam)4> mnesia:create_table(Tab, [{ram_copies, [a@sam, b@sam]}]).
{atomic,ok}
(a@sam)5> Write = fun(Keys) -> [mnesia:write({Tab,K,-K}) || K <- Keys], ok end.
#Fun<erl_eval>
(a@sam)6> mnesia:activity(sync_dirty, Write, [lists:seq(1, 256)], mnesia_frag).
ok
(a@sam)7> mnesia:change_table_frag(Tab, {activate, []}).
{atomic,ok}
(a@sam)8> mnesia:table_info(Tab, frag_properties).
[{base_table,dictionary},
?{foreign_key,undefined},
?{n_doubles,0},
?{n_fragments,1},
?{next_n_to_split,1},
?{node_pool,[a@sam,b@sam,c@sam]}]
(a@sam)9> Info = fun(Item) -> mnesia:table_info(Tab, Item) end.
#Fun<erl_eval>
(a@sam)10> Dist = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
[{c@sam,0},{a@sam,1},{b@sam,1}]
(a@sam)11> mnesia:change_table_frag(Tab, {add_frag, Dist}).
{atomic,ok}
(a@sam)12> Dist2 = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
[{b@sam,1},{c@sam,1},{a@sam,2}]
(a@sam)13> mnesia:change_table_frag(Tab, {add_frag, Dist2}).
{atomic,ok}
(a@sam)14> Dist3 = mnesia:activity(sync_dirty, Info, [frag_dist], mnesia_frag).
[{a@sam,2},{b@sam,2},{c@sam,2}]
(a@sam)15> mnesia:change_table_frag(Tab, {add_frag, Dist3}).
{atomic,ok}
(a@sam)16> Read = fun(Key) -> mnesia:read({Tab, Key}) end.
#Fun<erl_eval>
(a@sam)17> mnesia:activity(transaction, Read, [12], mnesia_frag).
[{dictionary,12,-12}]
(a@sam)18> mnesia:activity(sync_dirty, Info, [frag_size], mnesia_frag).
[{dictionary,64},
?{dictionary_frag2,64},
?{dictionary_frag3,64},
?{dictionary_frag4,64}]
(a@sam)19>?
?表片段屬性
可以能過mnesia:table_info(Tab, frag_properties).取得表性能, 其中有如下屬性:
{n_fragments, Int}表上有多少片段
{node_pool, List}
{n_ram_copies, Int}
{n_disc_only_copies, Int}
{foreign_key, ForeignKey}
{hash_module, Atom}
表片段管理
?mnesia:change_table_frag(Tab,? Change)? 用作重新配置片段表。可以有如下參數(shù):
?{activate, FragProps}激活現(xiàn)存表的片段屬性
deactivate? 停止片段屬性
{add_frag, NodesOrDist}添加一個新片段
del_frag刪除 一個片段
{add_node, Node}添加一個新節(jié)點到節(jié)點池。
{del_node, Node}從節(jié)點池刪除一節(jié)點
擴展憶存在的函數(shù)
函數(shù)?mnesia:create_table/2 通過指定?frag_properties 屬性創(chuàng)建片段表。
?mnesia:delete_table/1 刪除片段表,并刪除所有片段。
??mnesia:table_info/2能夠取出所有frag_properties 項目。
負載平衡
在做負載平衡可能要注意以下情況:
節(jié)點發(fā)生永久變化, 如節(jié)點添加或者移除,此時可能要變化節(jié)點池。也可能引起表片段發(fā)生變化,進行重新分配。
內存使用超過閥值,此時也許要重新考慮添加表片段等。
臨時節(jié)點故障,這種情可能可能需要添加些復件,用于冗余 。
4、本地內容表
復件表擁有相同內容在所有節(jié)點上,有時要可能需要各個節(jié)點保存不一樣的數(shù)據。當我們創(chuàng)建表時指定屬性{local_content, true},表存在于我們指定的節(jié)點上存在, 所有操作僅在本地備份上。另外,我們在啟動時,只初始化本地版本,不會與會遠端節(jié)點進行同步。
5、無磁盤節(jié)點
?可以在無磁盤節(jié)點上運行mnesia, 當然不能在這些節(jié)點上運行disc_copies,disc_only_copies類型的節(jié)點, 所有mnesia啟動自己需要的schema表會比較麻煩。
shema表像其它表一樣,存在于一個或多個節(jié)點上,它的存儲類型是disc_copies或者ram_copies(不可為disc_only_copies).在啟動mnesia方案的時候,確定了哪些節(jié)點需要建立聯(lián)系,如果有任何其它節(jié)點已經啟動了,就從已經已經啟動了節(jié)點取得表定義與本地的進行合并。參數(shù)extra_db_nodes就是用于指定節(jié)點列表。
所以,當一個無磁盤節(jié)點需要從網絡的遠端節(jié)點上找到一個方案定義 , 我們應該提供節(jié)點列表信息,參數(shù)如:-mnesia extra_db_nodes NodeList。對于沒有進行配置指定的, mnesia會作為一個單節(jié)點系統(tǒng)啟動, 也可以通過使用mnesia:change_config/2重置'extra_db_nodes',強制連接。
6、更多方案管理
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/freebird92/archive/2011/12/26/2298195.html
總結
以上是生活随笔為你收集整理的mnesia数据库学习笔记四的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UDPRouter
- 下一篇: linux下测试RTC驱动相关的命令da