热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

逐渐新增N个Mnesia节点,并确保数据在这些节点上保持同步.

逐渐新增N个Mnesia节点,并确保数据在这些节点上保持同步.标签:tableschemaioerlangsystemtimer20
逐渐新增N个Mnesia节点,并确保数据在这些节点上保持同步.
标签: tableschemaioerlangsystemtimer
1645人阅读 评论(0) 收藏 举报

  逐渐新增N个Mnesia节点,并确保数据在这些节点上保持同步. 

过程如下: 
1. Mnesia的分布式可以从一个节点开始, 然后慢慢新增. 
2. 新增加一个节点的时候, 首先要确保新节点上已经调用过mnesia:start() 
3. 在每个已知存活的节点上调用(可以用rpc:call)mnesia:change_config(extra_db_nodes, [NewNode]),这样可以通知每个节点, 有一个新的节点要加入进来了 
4. 改变NewNode上的schema表的存储方式: mnesia:change_table_copy_type(schema, NewNode, disc_copies) 
5. 重启动NewNode的Mnesia,并稍微等待一段时间.(这大概是由于远程新节点的schema改变后,不能及时反应的缘故,可能不是必要的) 
6. 向NewNode追加TableList : mensia:add_table_copy(Table, NewNode, disc_copies), 这里可能会调用多次,有多少用户表,就调用多少次 
---- Over All ---- 

上面的6步可以确保依次增加新的节点并确保数据同步. 
对应的代码如下: 

Erlang代码   收藏代码

addNode(NewNode) ->  

    io:format("New Node = ~p~n", [NewNode]),  

    RunningNodeList = mnesia:system_info(running_db_nodes),  

    io:format("-----------Adding Extra Node---------~n"),  

    addExtraNode(RunningNodeList, NewNode),  

    io:format("-----------Chang schema -> disc_copies---------~n"),  

    Rtn = mnesia:change_table_copy_type(schema, NewNode, disc_copies),  

    io:format("Rtn=~p~n", [Rtn]),  

    io:format("-----------Reboot Remote Node Mnesia---------~n"),  

    rpc:call(NewNode, mnesia, stop, []),  

    timer:sleep(1000),  

    rpc:call(NewNode, mnesia, start, []),  

    timer:sleep(1000),  

    io:format("-----------Adding Table List---------~n"),  

    addTableList(?TableList, NewNode),  

    io:format("-----------Over All---------~n").  

  

addExtraNode([], _NewNode) ->  

    null;  

addExtraNode(_RunningNodeList = [Node | T], NewNode) ->  

    Rtn = rpc:call(Node, mnesia, change_config, [extra_db_nodes, [NewNode]]),  

    io:format("Node = ~p, Rtn=~p~n", [Node, Rtn]),  

    addExtraNode(T, NewNode).  

  

addTableList([], _NewNode) ->  

    null;  

addTableList(_TableList = [Table | T], NewNode) ->  

    Rtn = mnesia:add_table_copy(Table, NewNode, disc_copies),  

    io:format("Table = ~p, Rtn = ~p~n", [Table, Rtn]),  

    addTableList(T, NewNode).  





额外的, 可能会有这种情况, 一个A节点可能已经断开了,然后一个新的B节点被追加了进来, 这个时候如果A节点在上线,可能检测不到B节点其实是于自己保持同步的,这样有可能造成数据不同步, 解决该问题的方法即调用net_adm:ping(Node) :即每一个新节点上线后,即mnesia:start()以后, 立即查找与自己相连接的节点(mnesia:system_info(db_nodes)),然后用net_adm:ping()去ping下每一个连接的node,告诉自己上来了,这样即可解决刚才的问题. 

对应的代码如下: 
Erlang代码   收藏代码

-module(ping).  

-compile(export_all).  

  

ping() ->  

    case whereis(ping) of  

        undefined ->  

            null;  

        OldPid ->  

            OldPid ! {exit},  

            unregister(ping)  

    end,  

    PingID = spawn(?MODULE, pingMain, []),  

    register(ping, PingID),  

    PingID.  

  

pingMain() ->  

    AllNodeList = mnesia:system_info(db_nodes),  

    pingList(AllNodeList),  

    NodeListCount = length(AllNodeList),  

    receiveMsg(0, 0, NodeListCount).  

  

receiveMsg(PingOK, PingFailed, NodeListCount) ->  

    receive  

        {ping, Result} ->  

            case Result of  

                true ->  

                    NewPingOK = PingOK + 1,  

                    NewPingFailed = PingFailed;  

                false ->  

                    NewPingOK = PingOK,  

                    NewPingFailed = PingFailed  + 1  

            end,  

            case (NewPingOK + NewPingFailed < NodeListCount) of  

                true ->  

                    receiveMsg(NewPingOK, NewPingFailed, NodeListCount);  

                false ->  

                    io:format("-------Ping Over---------~n"),  

                    io:format("Ping OK = ~p~n", [NewPingOK]),  

                    io:format("Ping Failed = ~p~n", [NewPingFailed])  

            end;  

        {exit} ->  

            io:format("Receive to exit~n");  

        _Any ->  

            receiveMsg(PingOK, PingFailed, NodeListCount)  

    after 30000 ->  

        io:format("Error : Time out~n")  

    end.  

  

pingList([])  ->  

    null;  

pingList(_NodeList = [Node | T]) ->  

    spawn(?MODULE, pingOne, [Node]),  

    pingList(T).  

          

pingOne(Node) ->  

    Rtn = net_adm:ping(Node),  

    PingID = whereis(ping),  

    case Rtn of  

        pong ->  

            PingID ! {ping, true};  

        pang ->  

            PingID ! {ping, false}  

    end.  


推荐阅读
  • 本文详细解析了 Android 系统启动过程中的核心文件 `init.c`,探讨了其在系统初始化阶段的关键作用。通过对 `init.c` 的源代码进行深入分析,揭示了其如何管理进程、解析配置文件以及执行系统启动脚本。此外,文章还介绍了 `init` 进程的生命周期及其与内核的交互方式,为开发者提供了深入了解 Android 启动机制的宝贵资料。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • 本文深入解析了 Kuangbin 数学训练营中的经典问题——Ekka Dokka,并通过详细的代码示例和数学推导,探讨了该问题的多种解法及其应用场景。通过对算法的优化和扩展,本文旨在为读者提供全面的理解和实用的参考。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 在尝试对从复杂 XSD 生成的类进行序列化时,遇到了 `NullReferenceException` 错误。尽管已经花费了数小时进行调试和搜索相关资料,但仍然无法找到问题的根源。希望社区能够提供一些指导和建议,帮助解决这一难题。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • Android 图像色彩处理技术详解
    本文详细探讨了 Android 平台上的图像色彩处理技术,重点介绍了如何通过模仿美图秀秀的交互方式,利用 SeekBar 实现对图片颜色的精细调整。文章展示了具体的布局设计和代码实现,帮助开发者更好地理解和应用图像处理技术。 ... [详细]
author-avatar
longning817
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有