minio 系统自动纠删码处理算法简单说明

内容来自web的计算使用,可能会有不一致的地方,建议参考官方文档(理论上server 端以及web 端应该是一致的)

参考处理

主要是以下js 处理的
https://min.io/static/js/min-72976390afcf/page/erasure-code-calculator.js

简单说明

核心是calculateInformation 函数

  • 处理流程
 
-  server node 是否是大于256 以及小于1 
-  磁盘大小,(1T-20T 判断)
-  基于磁盘以及server node 数量计算纠删码条纹(calculateStripeSizes),后续的一些处理依赖此,默认取最大值
-  基于纠删码条纹以及输入的信息获取纠删码的奇偶校(beginECCalculation 函数)
-  显示集群容错信息(singleSetConfiguration 函数)
  • calculateStripeSizes 函数说明
传递的e 以及a 是server nodes 以及每个server 的磁盘数,服务器node 应该是4以及以上
默认分片是1,同时每个分片的服务器为传递的总数,但是会基于1-16 进行重新计算,但是每个分片的
server 数是需要可以整除的,然后取一个最大的数,分片总数为商
calculateStripeSizes = (e, a) => {
        window.numShardsGlobal = 1,
            window.numServersPerShardGlobal = e;
        let t = e;
        for (let e = 1; e <= 16; e++)
            t % e == 0 && (window.numServersPerShardGlobal = e,
                window.numShardsGlobal = t / e);
        if (window.numServersPerShardGlobal <= 3)
            return resetParityTable(),
                $("#error-message").html("Invalid number of servers").css("display", "block"),
                [];
        let r = [];
        if (1 === window.numShardsGlobal) {
            let e = 1
                , t = window.numServersPerShardGlobal * e;
            //   此处会遍历计算可用的纠删码条纹核心算法是 那个分片的服务数*每个节点的磁盘数与小于等于16计算余数如果为零,放入数组中
           //  遍历的step 是基于那个分片的server 总数*step 次数,之后降序排列
            for (; t <= 16;)
                window.numServersPerShardGlobal * a % t == 0 && r.push(t),
                    e++,
                    t = window.numServersPerShardGlobal * e
        } else
            r = [window.numServersPerShardGlobal];
        return r.length > 1 && r.sort(((e, a) => a - e)),
            r
    }
  • beginECCalculation 函数 (主要是计算纠删码奇偶校验的)
beginECCalculation = (e, a, t, r, s = !1) => {
        getBytes(t, "TiB");
        const i = e * a;
        s || $("#ec-stripe-options").html("").attr("disabled", !1),
            $("#error-message").html("").css("display", "hidden");
        const o = calculateParityCount(r); // 计算可用的奇偶校验数
        return s || $(window.stripeSizes).each(((e, a) => {
            $("#ec-stripe-options").append('<option value="' + a + '">' + a + "</option>")
        }
        )),
            i < 4 ? (resetParityTable(),
                void $("#error-message").html("Specify a configuration with 4 or more total&nbsp;drives").css("display", "block")) : 0 === o.length ? (resetParityTable(),
                    void $("#error-message").html("Invalid configuration set. Please try other combination").css("display", "block")) : ($("#ec-parity-options").html("").attr("disabled", !1),
                        $(o).each(((e, a) => {
                            $("#ec-parity-options").append('<option value="' + a + '">' + a + "</option>")
                        }
                        )),
                        i >= 16 && o.includes(4) && $("#ec-parity-options").val(4),
                        void singleSetConfiguration()) // 信息系统容错信息
    }
  • calculateParityCount 计算
    输入参数e 实际上基于纠删码条纹处理的,默认参数使用的是最大值,对于生产集群环境来说默认使用的推荐值是4,但是可以通过配置参数调整
 
calculateParityCount = e => {
        const a = [];
        let t = e;
        for (; t >= 4;) {
            if (t % 2 == 0) {
                const e = t / 2;
                a.push(e)
            }
            t--
        }
        return a
    }
  • singleSetConfiguration
    注意对于如果纠删码条纹与奇偶校验是2倍的处理会有一些不一样,读写的处理是read + write quorum is (Stripe Size - (M + 1))
 
singleSetConfiguration = () => {
        const e = parseInt($("#number-of-nodes").val())
            , a = parseInt($("#drives-per-server").val())
            , t = $("#drive-capacity").val()
            , r = parseInt(getBytes(t, "TiB"))
            , s = parseInt($("#ec-stripe-options").val())
            , i = parseInt($("#ec-parity-options").val())
            , o = window.numServersPerShardGlobal
            , l = window.numShardsGlobal;
        let n = i;
        n === s / 2 && n--;
        // 此处是核心,可以了解到实际的容错情况
        const d = e * a * r
            , c = (s - i) / s
            , p = d * c
            , m = Math.floor(n / s * e * a)
            , u = Math.floor(n * o / s)
            , v = Math.floor(n * o / s * l)
            , h = Math.floor(100 * c) + "%";
        $("#usable-capacity").html(niceBytes(p)),
            $("#raw-capacity").html(niceBytes(d)),
            $("#storage-efficency").html(h),
            $(".drive-failures-tolerance").html(n),
            $(".server-failures-tolerance").html(u), // 每个分片总数*奇偶校验数/纠删码条纹,取最大整数
            $(".of-drives").html(s),
            $("#total-drives").html(m),
            $("#of-servers").html(o),
            $(".total-servers").html(v),
            l > 1 ? $("#server-tolerance-main").css("display", "block") : $("#server-tolerance-main").css("display", "none")
    }

说明

以上是一个简单通过web学习了解minio 的计算机制,实际上应该结合golang 源码分析下

参考资料

https://min.io/product/erasure-code-calculator

posted on 2022-03-27 20:44  荣锋亮  阅读(717)  评论(0编辑  收藏  举报

导航