在解决了我最近提出的有关 mnesia fragmentation的问题之后,我仍然面临许多挑战。考虑以下场景(我要问的问题基于以下内容):
您有一个数据驱动的企业应用程序,它应该
在企业内高度可用。如果内部信息源因任何原因而关闭,企业应用程序必须切换到从异地(远程)恢复中心
获取数据。您决定将数据库复制到企业内的两个节点上
(称为DB 端 A和DB 端 B)。这两者在单独的
硬件上运行,但通过快速以太网或光纤链路连接在一起。从逻辑上讲,您在这两个 Mnesia DB
之间创建了某种隧道或安全通信。
两者(A 和 B)应该具有相同的数据副本并且
始终保持同步。现在,与此同时,恢复中心也必须拥有相同的数据副本并
始终保持同步,以防本地数据访问因攻击
或硬件故障而中断。因此,必须在 3
个站点(A面、B 面和恢复中心)之间复制相同的数据库模式。
现在,在企业内部,应用程序中间件能够在数据库站点之间切换数据请求。如果 A 宕机,那么在应用程序没有意识到的情况下,请求被重新路由到数据库 B,依此类推。中间件层可以配置为进行负载平衡(请求多路复用)或灵活地使用故障转移技术。
进一步分析:
在创建数据库/模式时,所有涉及的节点都必须启动并运行
Mnesia。为了实现这一点,你创建说:'db_side_A@domain.com',
'db_side_B@domain.com'最后,'db_recovery_center@domain.com'
现在,在创建表时,您可能希望将您的 mnesia 表分段。因此,您决定以下参数:
n_disc_only_copies =:= 池中涉及的节点数 =:= 3 原因:您遵循此参数规定然后根据以下安排创建所有表
每个片段应具有多少 disc_only_copies 副本的文档。
因此,您希望每个表在每个 mnesia 节点上都有其每个片段。
node_pool =:= 涉及的所有节点 =:= ['db_side_A@domain.com',
'db_side_B@domain.com',
'db_recovery_center@domain.com']
节点 = [ 'db_side_A@domain.com', 'db_side_B@domain.com', 'db_recovery_center@domain.com' ], No_of_fragments = 16, {atomic,ok} = mnesia:create_table( TABLE_NAME ,[ {frag_properties,[ {node_pool,Nodes}, {n_fragments,No_of_fragments}, {n_disc_only_copies,length(Nodes)}] }, {指数,[]}, {属性,记录信息(字段,RECORD_NAME_HERE)}] ),注意:在上面的语法
RECORD_NAME_HERE
中,实际上不能是变量,因为在 Erlang 编译时必须知道记录。从安装中,您可以看到对于每个表,每个片段,例如table_name_frag2
,出现在每个节点的文件系统上。
挑战和出现的问题:
按照上面列出的内容进行操作后,您的第一次数据库启动是可以的,因为 mnesia 正在所有节点上运行。随着应用程序的运行,一些挑战开始出现,并列出以下内容:
假设您决定首先尝试所有写入,
DB Side A
并且如果此时 A 端不可用,则重新尝试调用DB Side B
,以此类推recovery center
,如果调用在所有 3 个数据库节点上均未返回,则应用程序网络中间件层报告数据库服务器全部不可用(这个决定可能受到以下事实的影响:如果您让应用程序随机写入您的 mnesia 副本,则很可能会出现不一致的数据库错误,以防您的 mnesia 节点丢失彼此之间建立网络连接,但不同的 Erlang 应用程序正在各自提交写入。如果您决定拥有master_nodes
,那么您可能会面临丢失数据的风险)。所以通过行为,你是在强迫DB Side A
成为主人。这使得其他数据库节点一直处于空闲状态,只要DB Side A
启动并运行,并且与命中方 A 一样多的请求并且它不会关闭,则根本没有请求会到达 B 方和恢复中心。通常,Mnesia 在启动时应该看到所有相关节点都在运行(mnesia 必须在所有相关节点上运行),以便它可以进行协商和一致性检查。这意味着如果 mnesia 在所有节点上都出现故障,则必须在所有节点上启动 mnesia,然后才能完全初始化和加载表。如果 Erlang VM 在远程站点上与 Mnesia 一起死掉,那就更糟了。好吧,这里和那里的一些调整和脚本可以帮助重新启动整个 VM 以及如果它出现故障的预期应用程序。
长话短说,让我回答问题。
问题:
如果 mnesia在不希望
inconsistent_database, starting to run database behind a partitioned network
设置 a 的情况下(因为担心数据丢失)生成 的事件,数据库管理员会怎么做?mnesia master node
mnesia 事件
inconsistent_database, starting to run database behind a partitioned network
对我的申请有什么影响?如果我不对这个事件做出反应,让事情继续原样发生怎么办?我会丢失数据吗?在大型 mnesia 集群中,如果 Mnesia 与远程站点上的 Erlang VM 一起出现故障,该怎么办?是否有任何已知的自动处理这种情况的好方法?
有时由于网络问题或故障导致一两个节点无法访问,并且幸存节点上的 mnesia 报告给定文件不存在,尤其是在您拥有
indexes
. 那么在运行时,如果某些副本出现故障,我的应用程序的行为会怎样?你会建议我在 mnesia 集群中有一个主节点吗?
当您回答上述问题时,您还可以突出显示开头描述的布局,它是否能确保可用性。您可以提供有关在生产中使用 mnesia 碎片和复制数据库的个人经验。关于本文开头的链接(引用)问题,请提供可以在创建数据库时提供更高可靠性的替代设置,例如片段数量、操作系统依赖关系、节点池大小、表副本类型, ETC。