mnesia fragment分片逻辑

mnesia的disc单表有4GB的大小限制,因此在项目开始之初就要评估下数据大小,避免以后修改,扩容的麻烦。而且用了mnesia分片,读写方法将不能使用mnesia:read,mnesia:write了,需要统一使用mnesia:activity来包装,声明使用mnesia_frag。

mnesia默认使用Linear Hashing进行分片管理,查询。

核心代码mnesia_frag_hash.erl:

init_state(_Tab, State) when State == undefined ->
    #hash_state{n_fragments     = 1,
        next_n_to_split = 1,
        n_doubles       = 0,
        function        = phash2}.

add_frag(#hash_state{next_n_to_split = SplitN, n_doubles = L, n_fragments = N} = State) ->
    P = SplitN + 1,
    NewN = N + 1,
    State2 = case power2(L) + 1 of
         P2 when P2 == P ->
             State#hash_state{n_fragments      = NewN,
                      n_doubles        = L + 1,
                      next_n_to_split = 1};
         _ ->
             State#hash_state{n_fragments     = NewN,
                      next_n_to_split = P}
         end,
    {State2, [SplitN], [NewN]}.

del_frag(#hash_state{next_n_to_split = SplitN, n_doubles = L, n_fragments = N} = State) ->
    P = SplitN - 1,
    if
    P < 1 ->
        L2 = L - 1,
        MergeN = power2(L2),
        State2 = State#hash_state{n_fragments     = N - 1,
                      next_n_to_split = MergeN,
                      n_doubles       = L2},
        {State2, [N], [MergeN]};
    true ->
        MergeN = P,
        State2 = State#hash_state{n_fragments     = N - 1,
                      next_n_to_split = MergeN},
        {State2, [N], [MergeN]}
    end.

key_to_frag_number(#hash_state{function = phash2, n_fragments = N, n_doubles = L}, Key) ->
    A = erlang:phash2(Key, power2(L + 1)) + 1,
    if
    A > N ->
        A - power2(L);
    true ->
        A
    end.

按照代码,列出8个分片生成过程中,各变量的值以及哪些分片的数据需要迁移去新分片

n_fragmentsnext_n_to_splitn_doublessplit_frag(分离分片)write_frag(新增分片)
110
21112
32113
41224
52215
63226
74237
81348

根据源码,我们可以总结出

  • 每次只增加或减少一个分片
  • 扩充时受影响分片中有将近一半数据迁到新分片中
  • 缩减时一个分片中的数据都迁到另一个分片中
  • 在大多数情况下,各分片中数据数量不均衡。因此推荐分片数量为2的N次方个,刚好分出一半数据来做分片,数据能均衡分布。

转载于:https://my.oschina.net/rongtou/blog/845896

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值