• mnesia数据库学习笔记四


    杂项

    前二章讲了如何启动数据库,如何构建数据库,接下来会为讲一些创建分布式容错数据所需的高级特征:

    • 索引
    • 分布式和容错
    • 表分段
    • 本地内容表
    • 无磁盘节点
    • 高级方案管理
    • 调用应用程序
    • 并行进程
    • 原形研究
    • 基于对象的编程

    1、索引

    如果数据添加索引,那位定位会很快,如果没有索引,就需要遍历表,可能会消耗较长时间。Mnesia提供了如下两个函数操作索引:

    mnesia:add_table_index(Tab, AttributeName)

    mnesia:delete_table_index(Tab,AttributeName)

    可能通过如下函数进行索引查找:

    mnesia:index_read(Tab, SecondaryKey, AttributeName) mnesia:index_match_object(Pattern, AttributeName) mnesia:match_object(Pattern)’

    2、分布式和容错

    mnesia提供了多种方式把表复制到多个不同的Erlang节点上。编程人员除表名不用关心表的具体在那个节点上。实现具体位置透明化。(当然如果数据在远程节点,处理会慢一点), 数据库可以反复配置, 表可以在节点间移动。这并不影响编程人员。

    以下是创建一个表,带有两个复件:

        mnesia:create_table(foo,
                            [{ram_copies, [N1, N2]},
                             {attributes, record_info(fields, foo)}]).
     

    表可能拥有如下类型,每个类型都可以有一个Erlang节点列表:

    ram_copies,RAM复件会在每个节点上存在。可以通过mnesia:dump_table函数将RAM表保存到磁盘上。

    disc_copies,表复件会在每个节点的内存和磁盘上存在。写操作会影响RAM和磁盘。

    disc_only_copies,表复件只会出在各节点的磁盘上。会影响访问速度,但会节约内存。

    运行时也是可以修改表属性的。使用表复件有两个原因, 容错和速度。如果我们拥有两个活动节点, 任一节点故障后,复件节点仍然可用。 此外,假如一个表存在两个节点,应用程序在任一节点上读数据而无需访问网络。网络访问意味着比本地操作低效。

    对于数据经常读,而少量写的应用,表复件是非常具有优势的。劣势就是增加了写操作时间。假如一个表有两个复件,每一个写操作必需访问两个表复件。甚至其中一个写操作为网络操作。消耗比非复件表大很多。

    3、表片段

     表片段主用于应对超大表。其核心就是把一个表分隔成多个可控表片段。每个片段被实现为第一级的Mnesia表,就像普通表一样,可以复件,可以索引等。但是不能拥有local_content和snmp活动连接。

    mnesia提供了mnesia_frag模块, 实现了mnesia_access回调行为用于访问片该记录。

    在访问记录前,mnesia_frag先计算记录键值的hash值 ,然后通过hash值确定表片段名字。最终就像普通表一样进行访问处理。如果不能预先知道记录键值, 需要在所有表片段中进行匹配。注,在ordered_set表中,记录在表片段内进行排序。select 和match_object等函数的返回结果也是无序的。如下就是展示了如何将一个现存表转换成片段表,如何添加更多表片段。

    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)  用作重新配置片段表。可以有如下参数:

     {activate, FragProps}激活现存表的片段属性

    deactivate  停止片段属性

    {add_frag, NodesOrDist}添加一个新片段

    del_frag删除 一个片段

    {add_node, Node}添加一个新节点到节点池。

    {del_node, Node}从节点池删除一节点

    扩展忆存在的函数

    函数 mnesia:create_table/2 通过指定 frag_properties 属性创建片段表。

     mnesia:delete_table/1 删除片段表,并删除所有片段。

      mnesia:table_info/2能够取出所有frag_properties 项目。

    负载平衡

    在做负载平衡可能要注意以下情况:

    节点发生永久变化, 如节点添加或者移除,此时可能要变化节点池。也可能引起表片段发生变化,进行重新分配。

    内存使用超过阀值,此时也许要重新考虑添加表片段等。

    临时节点故障,这种情可能可能需要添加些复件,用于冗余 。

    4、本地内容表

    复件表拥有相同内容在所有节点上,有时要可能需要各个节点保存不一样的数据。当我们创建表时指定属性{local_content, true},表存在于我们指定的节点上存在, 所有操作仅在本地备份上。另外,我们在启动时,只初始化本地版本,不会与会远端节点进行同步。

    5、无磁盘节点

     可以在无磁盘节点上运行mnesia, 当然不能在这些节点上运行disc_copies,disc_only_copies类型的节点, 所有mnesia启动自己需要的schema表会比较麻烦。

    shema表像其它表一样,存在于一个或多个节点上,它的存储类型是disc_copies或者ram_copies(不可为disc_only_copies).在启动mnesia方案的时候,确定了哪些节点需要建立联系,如果有任何其它节点已经启动了,就从已经已经启动了节点取得表定义与本地的进行合并。参数extra_db_nodes就是用于指定节点列表。

    所以,当一个无磁盘节点需要从网络的远端节点上找到一个方案定义 , 我们应该提供节点列表信息,参数如:-mnesia extra_db_nodes NodeList。对于没有进行配置指定的, mnesia会作为一个单节点系统启动, 也可以通过使用mnesia:change_config/2重置'extra_db_nodes',强制连接。

    6、更多方案管理

  • 相关阅读:
    sublime text3在指定浏览器上本地服务器(localhost)运行文件(php)
    关于Content-Type的问题
    为什么开发要用一个大的背景图
    2017-04-17
    我的第一篇博客
    b站计算机网络谢希仁6网络层续3
    b站计算机网络谢希仁6网络层续2
    b站计算机网络谢希仁6网络层续1
    b站操作系统2.10互斥
    b站操作系统2.9并发
  • 原文地址:https://www.cnblogs.com/freebird92/p/2298195.html
Copyright © 2020-2023  润新知