我正在尝试构建分布式文件系统中文件可用性的数学模型。我在MathOverflow上发布了这个问题,但这可能也被归类为CS问题,所以我也在这里给它一个镜头。
系统的工作方式如下:一个节点在r * b遥控节点存储一个文件(使用纠删码编码),其中r是复制因子,b是整数常量。如果远程节点中至少有b个可用,则删除编码文件具有可以恢复文件的属性,并返回其文件的一部分。
最简单的方法是假设所有远程节点彼此独立并具有相同的可用性p。根据这些假设,文件的可用性遵循二项分布,即Binomial distribution http://bit.ly/dyJwwE
不幸的是,这两个假设可能会引入一个不合理的错误,如本文所示:http://deim.urv.cat/~lluis.pamies/uploads/Main/icpp09-paper.pdf。
克服所有节点具有相同可用性的假设的一种方法是计算可用/不可用节点的每种可能组合的概率,并取所有这些结果的总和(这是他们在上面的论文,比我刚才描述的更正式。您可以将此方法视为具有深度r * b的二叉树,并且每个离开是可用/不可用节点的一种可能组合。该文件的可用性与您使用> = b可用节点的休假可能性相同。这种方法更正确,但计算成本为Ordo http://bit.ly/cEZcAP。此外,它不涉及节点独立性的假设。
你们是否有任何关于良好近似的想法,它引入的误差小于二项式分布 - 近似,但计算成本比http://bit.ly/d52MM9 http://bit.ly/cEZcAP更好?
您可以假设每个节点的可用性数据是由(measurement-date, node measuring, node being measured, succes/failure-bit)
组成的一组元组。使用此数据,您可以计算节点之间可用性与可用性差异的相关性。
答案 0 :(得分:5)
对于大型r
和b
,您可以使用名为蒙特卡罗积分的方法,例如, Monte Carlo integration on Wikipedia(和/或SICP的第3.1.2章)计算总和。对于较小的r
和b
以及明显不同的节点失败概率p[i]
,确切的方法更为出色。 small 和 large 的确切定义取决于几个因素,最好通过实验进行尝试。
特定示例代码:这是一个非常基本的示例代码(在Python中),用于演示此类过程如何工作:
def montecarlo(p, rb, N):
"""Corresponds to the binomial coefficient formula."""
import random
succ = 0
# Run N samples
for i in xrange(N):
# Generate a single test case
alivenum = 0
for j in xrange(rb):
if random.random()<p: alivenum += 1
# If the test case succeeds, increase succ
if alivenum >= b: succ += 1
# The final result is the number of successful cases/number of total cases
# (I.e., a probability between 0 and 1)
return float(succ)/N
该函数对应于二项式测试用例并运行N
测试,检查b
个节点中的r*b
个节点是否存活且p
失败的可能性。在您获得任何合理结果之前,一些实验将使您确信在数千个样本范围内需要N
的值,但原则上复杂度为O(N*r*b)
。结果的准确性可以缩放为sqrt(N)
,即,为了将准确度提高两倍,您需要将N
增加四倍。对于足够大的r*b
,这种方法显然会更优越。
近似的扩展:您显然需要设计测试用例,使其尊重系统的所有属性。您已经建议了一些扩展,其中一些扩展可以轻松实现,而其他扩展则无法实现。让我给你一些建议:
1)在不同但不相关p[i]
的情况下,上述代码的变化是最小的:在函数头中传递数组而不是单个float p
并替换该行<{1}}来自
if random.random()<p: alivenum += 1
2)在相关if random.random()<p[j]: alivenum += 1
的情况下,您需要有关系统的其他信息。我在评论中提到的情况可能是这样的网络:
p[i]
在这种情况下,A--B--C
| |
D E
|
F--G--H
|
J
可能是“根节点”,节点A
的失败可能意味着自动失败,节点概率为100%D
,F
,G
和H
;虽然节点J
的失败会自动降低F
,G
和H
等等。至少这是我在评论中提到的情况(这是一个因为你在原问题中谈论概率的树结构,所以似乎是合理的解释。在这种情况下,您需要修改J
引用树结构的代码,p
遍历树,一旦测试失败,就跳过当前节点的下层分支。当然,结果测试仍然是for j in ...
。
3)如果网络是无法用树结构表示的循环图,则此方法将失败。在这种情况下,您需要首先创建死或活的图节点,然后在图上运行路由算法以计算唯一的可达节点的数量。这不会增加算法的时间复杂度,但显然会增加代码的复杂性。
4)如果你知道mtbf / r(故障之间的平均次数/修复),时间依赖是一个非常重要但可能的修改,因为这可以为你提供树的概率alivenum >= b
-structure或不相关的线性p
乘以指数。然后,您必须在不同时间运行MC程序,并使用p[i]
的相应结果。
5)如果您只是拥有日志文件(如上一段所示),则需要对该方法进行实质性修改,这超出了我在此板上的功能。日志文件需要足够彻底,以允许重建网络图的模型(以及p
的图表)以及p
的所有节点的各个值。否则,准确性将是不可靠的。这些日志文件还需要比故障和修复的时间尺度长得多,这种假设在现实生活中可能并不现实。
答案 1 :(得分:2)
假设每个节点都具有恒定的,已知的和独立的可用率,我们会想到一种分而治之的方法。
假设您有N
个节点。
N/2
个节点。[0,N/2]
)关闭的概率。[0,N]
)的概率下降的概率。第2步可以递归完成,在最高级别,您可以根据需要求和,以查找超过某些数字的频率。
我不知道这种情况的复杂程度,但如果我不得不猜测,我会说等于或低于O(n^2 log n)
这种机制可以在终端案例中说明。假设我们有5个节点,其上升时间为。我们可以将此细分为A
和B
。然后我们可以处理这些以找到每个段的“N个节点”时间:
对于A:
对于B:
此阶段的最终结果可以通过将每个a
与每个b
相乘并相应地求和来找到。
v[0] = a[0]*b[0]
v[1] = a[1]*b[0] + a[0]*b[1]
v[2] = a[2]*b[0] + a[1]*b[1] + a[0]*b[2]
v[3] = a[2]*b[1] + a[1]*b[2] + a[0]*b[3]
v[4] = a[2]*b[2] + a[1]*b[3]
v[5] = a[2]*b[3]