`
20.Shadow
  • 浏览: 5009 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Erlang - 分布式的Mnesia学习记录

阅读更多
Mnesia的机制稍微有些奇怪, 今天一天都比较闲,于是测试study了下, 看看是如果动作.

目标:
  逐渐新增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步可以确保依次增加新的节点并确保数据同步.
对应的代码如下:
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,告诉自己上来了,这样即可解决刚才的问题.

对应的代码如下:
-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.


------------------------------------------------
题外话,erlang的编译器比较怪,我在WinXP上面如果使用类似-record定义,然后使用%%-comment的话,就会报告错误@__@...... 因此上述的代码均没有注释...哪位好心人如果知道请告诉我下这个是为撒,Thanks~~
1
0
分享到:
评论
2 楼 aiquantong 2013-01-02  
3. 在每个已知存活的节点上调用(可以用rpc:call)mnesia:change_config(extra_db_nodes, [NewNode]),这样可以通知每个节点, 有一个新的节点要加入进来了  
应该是 通知互联erl节点网络中一个节点就可以了
不需要每个把??
1 楼 aiquantong 2013-01-02  
我是在 windows 下有eclipse 开发的  但是编译是在linux环境中 没有问题的啊

相关推荐

    erlang-18.3-1.el7.centos.x86_64.zip

    Erlang是一种高级编程语言,特别为构建分布式、并发、实时和容错系统而设计。在标题中的"erlang-18.3-1.el7.centos.x86_64.zip",我们看到的是Erlang的一个特定版本,18.3,针对64位的CentOS 7操作系统(el7)的...

    erlang-rpm-21.3.4.zip

    Erlang是一种高级编程语言,特别为并发、分布式计算和实时系统设计,广泛应用于电信、银行、互联网服务和软件开发领域。"erlang-rpm-21.3.4.zip"是一个包含Erlang版本21.3.4的RPM(Red Hat Package Manager)包的...

    Erlang-game-server开发实践.zip

    Mnesia是Erlang内置的分布式数据库,适用于实时、分布式和高可用性应用。在游戏服务器中,它可以用来存储玩家数据、游戏状态等信息,支持快速读写和容错。 ### 7. WebSockets集成 游戏服务器常常需要与客户端建立长...

    erlang_版本24.3.4.4

    Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson开发,主要用于构建高可用性、分布式和实时系统。版本24.3.4.4是Erlang的一个更新版本,包含了对先前版本的改进和修复。Erlang以其强大的错误...

    Erlang-OTP-API 离线查询英文全手册

    此“Erlang-OTP-API 离线查询英文全手册”是Erlang OTP的官方文档,包含了所有API的详细信息,是学习和开发Erlang OTP应用的重要资源。手册内容广泛,包括了以下几个核心部分: 1. **模块和函数**:手册详细列出了...

    Erlang的高级特性和应用

    Mnesia 是Erlang的分布式数据库系统,适合读多写少的场景。它提供了软实时性,大部分数据存储在本地内存,支持水平分割和数据冗余,可以自动在节点间进行数据迁移。Mnesia 与其他数据库(如UnixODBC)可交互,但存在...

    mnesia数据库文档

    ### Mnesia数据库:Erlang中的分布式数据库管理系统 #### 引言 Mnesia,作为Erlang编程语言的一部分,是一款由爱立信公司开发的分布式数据库管理系统(DBMS)。自1997年以来,Mnesia一直是Open Telecom Platform...

    Mnesia用户手册.zip

    Mnesia是Erlang OTP (Open Telephony Platform) 库中的一个核心组件,它是一个强大的分布式数据库系统,特别适用于需要高可用性、容错性和实时性能的场景,比如电信和相关领域。 Mnesia的设计理念是与Erlang的并发...

    Erlang6大数据存储方式总结

    Mnesia是Erlang的分布式事务型数据库系统,它结合了ETS和DETS的优点。Mnesia可以在内存和磁盘上存储数据,并且支持跨多个节点的复制和事务操作。这使得Mnesia成为构建分布式应用程序的理想选择。Mnesia提供了记录...

    分布式应用Erlang:Erlang_OTP_19_win64

    Erlang OTP 19_win64是一款专为Windows 64位系统设计的Erlang软件开发工具包,它包含Erlang编程...通过学习和掌握Erlang OTP,开发者可以利用其强大的并发机制和分布式特性,构建出能够应对复杂并发场景的高可靠系统。

    Mnesia用户手册

    在Erlang编程语言中,Mnesia是一个分布式数据库管理系统,专为实时系统设计,具有高可用性和容错性。本手册旨在为开发者提供全面的Mnesia使用指南,帮助他们理解并有效地利用这个强大的工具。 **1. Mnesia概述** ...

    Erlang高级应用和原理

    Erlang的分布式数据库Mnesia则提供了一种实时性较强、支持水平分割和数据冗余的解决方案,特别适合读多写少的场景。 Mnesia数据库在Erlang生态系统中扮演着重要角色,它可以避免传统数据库的实时性问题和IPC通讯...

    erlang 学习笔记1

    【标题】"Erlang 学习笔记1" 在深入探讨Erlang这一强大的并发编程语言之前,我们先来理解一下Erlang的基本概念。Erlang是由瑞典电信设备制造商Ericsson开发的一种函数式编程语言,它最初设计的目的是为了处理分布式...

    Mnesia用户手册(docx版)

    Mnesia 是一个强大的分布式数据库管理系统(DBMS),专门为Erlang编程语言设计,特别适用于需要高可用性、持续运行和软实时特性的电信和其他关键业务应用。这个系统允许在多个节点间同步数据,提供了一种在分布式...

    erlang 设计指南

    Erlang的分布式特性还包括分布式进程和分布式数据库Mnesia,后者是一个事务型数据库,特别适合实时和高可用性系统。 Erlang的 OTP(Open Telecom Platform)框架进一步简化了并发和分布式系统的开发。OTP提供了一...

    erlang22最新下载包

    Erlang是一种面向并发的、函数式编程语言,由瑞典电信设备制造商Ericsson为了实现分布式实时、高可靠性系统而开发。...学习和掌握Erlang22的新特性有助于提升开发效率和应用质量,特别是在构建高并发、分布式系统时。

    erlang学习资料

    Erlang是一种面向并发的、函数式编程语言,由瑞典电信...总的来说,Erlang的学习涉及函数式编程思想、并发处理、分布式系统设计等多个方面,深入学习并实践这些知识点,将使你具备开发高效、可靠的并发应用程序的能力。

Global site tag (gtag.js) - Google Analytics