3

我正在努力在 Go 中本地创建一个 Pastry 版本。从设计[PDF]:

假设应用程序提供了一个功能,允许每个 Pastry 节点确定具有给定 IP 地址的节点到自身的“距离”。具有较低距离值的节点被认为是更可取的。应用程序应根据其选择的邻近度度量来实现此功能,使用诸如跟踪路由或 Internet 子网映射之类的网络服务,以及适当的缓存和近似技术以最小化开销。

我试图找出从 Go 中以编程方式确定两个 EC2 实例之间“接近度”(即网络延迟)的最佳方法。不幸的是,我对低级网络不够熟悉,无法区分我可以使用的不同类型的请求。谷歌搜索没有提出任何测量 Go 延迟的建议,一般延迟技术似乎总是 Linux 二进制文件,我希望以减少依赖项的名义避免这种情况。有什么帮助吗?

另外,我注意到两个 EC2 实例之间的延迟应该在 1 毫秒的范围内。虽然我计划在 EC2 上使用该实现,但假设它可以在任何地方使用。延迟是否通常如此糟糕,以至于我应该努力确保两个节点的网络接近?请记住,大多数 Pastry 请求可以以集群中服务器数量的 16 为基数提供服务(因此对于 10,000 台服务器,平均大约需要 3 个请求才能找到正在搜索的密钥)。例如,从 EC2 的亚太地区到 EC2 的美国东部地区的延迟是否足以证明增加节点时延迟检查引入的复杂性和开销是合理的?

4

1 回答 1

5

网络中一个常见的距离度量是计算数据包到达其目的地所需的跳数(中间的节点跳数)。您引用的文本中也提到了该指标。即使对于您提到的低延迟环境(EC2“本地”),这也可以为您提供足够的距离值。

对于 go 逻辑本身,人们会认为net就是你要找的东西。事实上,对于延迟测试(ICMP ping),您可以使用它来创建 IP 连接

conn, err := net.Dial("ip4", "127.0.0.1")

创建您的ICMP 包结构和数据,然后发送。(参见ICMP 上的 Wikipedia 页面;IPv6 需要不同的格式。)不幸的是,您不能像使用 TCP 和 UDP 那样直接创建 ICMP 连接,因此您必须自己处理包结构。

由于conntypeConn是 a Writer,然后您可以将您的数据(您定义的 ICMP 数据)传递给它。

ICMP 类型字段中,您可以指定消息类型。值 8、1 和 30 是您要查找的值。8 对于您的回显请求,回复将是类型 1。也许 30 可以为您提供更多信息。

不幸的是,为了计算网络跳数,您将需要 IP 数据包标头字段。这意味着,您将不得不构建自己的 IP 数据包,这net似乎不允许。

检查 的来源Dial(),它使用internetSocket未导出/公开的 。我不确定我是否遗漏了什么,但似乎没有简单的方法来构建您自己的 IP 数据包以发送,并具有可自定义的标头值。您必须进一步检查如何使用该代码/概念DialIP发送包,internetSocket并复制和调整该代码/概念。或者,您可以使用 cgo 和系统库来构建您自己的包(虽然这会增加更多的复杂性)。

如果您打算使用IPv6,则(还)必须研究ICMPv6。这两个软件包的 v4 版本具有不同的结构。


所以,我建议使用简单的延迟(定时 ping)作为简单的(r)实现,然后在以后/之后添加节点跳,如果你需要的话。如果你有两个地方,也许你也想结合这两个(更少的跳跃并不意味着更好;想想长的海外电缆等)。

于 2012-04-17T22:03:12.177 回答