ChessBrain:基于 Linux 的分布式计算实验

作者:Carlos Justiniano

2003 年 5 月 27 日,646 台机器协同工作,完成了一局国际象棋比赛。这是首次完成这样的壮举,这要归功于 Linux 的强大功能、开源软件以及来自 37 个不同国家的数百名贡献者。

ChessBrain(chessbrain.net)是一个分布式计算项目,它利用分布式机器的空闲处理能力来解决计算密集型问题。ChessBrain 是一个专注于下国际象棋的系统,但其底层系统也可以适用于其他游戏以及非游戏相关的应用程序。

想象一下,您正在与对手下棋,但每次他走一步,您就拿起电话开始打电话给朋友寻求帮助。您打电话给 Sue,描述当前局面,并让她在有答案时给您回电。然后您打电话给 Ryan,询问您是否应该担心即将到来的攻击;同样,您要求他在有答案时回电。在给 20 位其他朋友打完电话后,您坐下来等待回复。这与 ChessBrain 下国际象棋的方式类似。

ChessBrain 由一个基于 Linux 的服务器应用程序 SuperNode 和客户端软件 PeerNode 组成。SuperNode 连接到在线游戏服务器,允许访问成员相互对弈、挑战 ChessBrain 进行比赛或观看 ChessBrain 与其当前对手的比赛。当 ChessBrain 下棋时,它会检查局面,将数百个潜在的走法分派到远程 PeerNode 进行分析,收集来自 PeerNode 的反馈,处理这些信息并做出最佳走法。ChessBrain 作为一个不断变化的网络机器池而存在。从哲学和科学的角度来看,这是一件美好的事情。

我在 2001 年夏天启动了 ChessBrain,作为一个分布式计算实验。到那年年底,我拥有了一个可工作的原型,并且需要一个地方来托管服务器。我的老朋友,HackerWhacker(hackerwhacker.com)的网站管理员 Walter Howard,主动提出在他的个人 T1 专线上托管服务器。

ChessBrain: a Linux-Based Distributed Computing Experiment

图 1. 第一批 ChessBrain 服务器

2002 年 6 月 9 日,ChessBrain 出现在 Slashdot 上,积极的曝光带来了数百名新的 PeerNode 运营商。Gavin Roy 是新成员之一,他拥有 bteg 网络(www.bteg.net)并主动提出免费托管 SuperNode 服务器。6 月 27 日,我与 Gavin 共进晚餐,并将一台 Pentium III 机器上的 SuperNode 服务器交给了这位几乎是陌生人的朋友。ChessBrain 增加了一台服务器,我多了一位朋友,而 Gavin 也成为了 ChessBrain 项目的重要支持者。我将 SuperNode 转移到 Gavin 的站点,而 Walt 继续托管原始的 SuperNode 作为辅助备份和实验服务器。

在接下来的几个月中,我们获得了惊人的曝光量。似乎很少有人介意 ChessBrain 实际上不会下棋。2002 年的前八个月用于开发 SuperNode 服务器并将 PeerNode 客户端移植到 Microsoft Windows 和 Apple 的 Mac OS X。

一旦服务器和客户端运行良好,重点就转移到让 ChessBrain 真正地下棋。荷兰的 wbec-ridderkerk(www.wbec-ridderkerk.nl)网站列出了近 200 个免费提供的国际象棋程序。我审查了一些程序,寻找代码相对干净且能够在多个操作系统下编译的程序。我在 Colin Frayn 编写的 Beowulf 中找到了一个理想的程序,他当时是英国剑桥大学的博士候选人。我们交换了几封电子邮件,Colin 加入了该项目。我们完全通过电子邮件和即时消息 (IM) 在线协作,并开始进行必要的修改。Colin 将他的国际象棋程序改编为分布式计算,我修改了 SuperNode 和 PeerNode 客户端以使用他的引擎。伦敦和洛杉矶之间的时差被证明是理想的。我会在我的凌晨 3 点和白天再次给 Colin 发 IM。到我的傍晚,Colin 会去睡觉,而我会工作到他的晚上。在睡觉之前,我会给 Colin 留下反馈。这种昼夜循环持续了数月。

Colin 将他最初的 Beowulf 国际象棋引擎改编为两个国际象棋组件 BeoServer 和 BeoClient。他开发了这对组件以支持 ChessBrain 框架内的分布式国际象棋游戏。2002 年 12 月 22 日,ChessBrain 进行了其第一局分布式国际象棋比赛。到 2003 年 1 月,ChessBrain 社区已提供了 62 台机器,并正在测试常规构建。

概述

SuperNode 和 PeerNode 是用 C++ 编写并使用 Red Hat Linux 7.1、7.2 和 8.0 下的 GCC 编译的多线程应用程序。主 SuperNode 服务器在 Slackware 8.0 下运行,位于北加利福尼亚州 bteg 网络的托管站点(图 2)。

ChessBrain: a Linux-Based Distributed Computing Experiment

图 2. ChessBrain 系统架构

由于应用程序是高度多线程的,因此我花费了相当多的时间来解决线程问题。我使用了 GDB、DDD 和自定义日志来解决调试问题。在开发过程的早期,Perl 脚本被证明在帮助测试新功能和压力测试软件方面特别有效。我在家有 12 台机器;这些机器,加上 Perl 脚本大军冲击本地服务器,被证明是非常强大的测试工具。

XML、SOAP 和 Web 服务

在项目初期,我意识到 SuperNode 服务器需要与其他服务器通信。当时,XML 提供了一种可行的方法,后来 XMLRPC(www.xmlrpc.org)带来了额外的优势。简单对象访问协议 (SOAP) 不断发展以满足与其他服务器对话的服务器的需求。在改进互操作性的承诺的鼓励下,我采用了 SOAP 作为 SuperNode 服务器和 PeerNode 客户端的首选通信方法。

从外部来看,SuperNode 的行为类似于具有基于 SOAP 的接口的 Web 服务器。尽管 SuperNode 服务器处理 HTTP GET 和 POST,但 POST 消息最常用。SuperNode 解析 HTTP 和基于 XML 的 SOAP 请求,处理这些请求,并返回带有嵌入式 SOAP 负载的 HTTP 包。

SuperNode 和 PeerNode 解析 SOAP 请求并将命令路由到内部命令调度程序,该调度程序确保正确的命令处理程序处理请求。在 SuperNode 中,最常见的请求来自 PeerNode 客户端;PeerNode 必须连接以请求作业单元。作业单元是一个 XML 块,其中包含游戏局面和有关如何分析局面的说明。PeerNode 包含一个完整的国际象棋引擎组件,该组件被编译并链接为静态库。当 PeerNode 接收到作业单元时,它会处理 SOAP 响应,提取特定于作业的信息,并将指令传递给其内部国际象棋组件以进行分析。

然后,SuperNode 服务器将当前游戏局面传递到外部 BeoServer 进程。SuperNode 和 BeoServer 之间的进程间通信是使用两个管道完成的。在不久的将来,我们希望将 BeoServer 移动到其自己的盒子中,并切换到基于 1000Base-T 以太网的 UDP。

安全

安全且防篡改的通信对于 ChessBrain 来说是必不可少的。恶意用户创建的无效结果可能会使游戏效果不佳,并最终令人尴尬。敏感通信使用高级加密标准 AES Rijndael(发音为 Rhine-doll)进行保护。AES 是一种可变块对称加密算法,由比利时密码学家 Joan Daemen 和 Vincent Rijmen 开发,旨在替代老化的 DES 和 Triple DES 标准。

在探索 Rijndael 之前,使用了 Blowfish 对称密码,直到 PeerNode 客户端移植到 Mac OS X 并且在使用 Blowfish 的实现中出现涉及字节序问题的问题。AES 是一种字节序中性算法,事实证明非常适合我们的情况。

PeerNode 的原始设计涉及将客户端及其国际象棋引擎作为两个单独的进程。PeerNode 启动国际象棋引擎进程并重定向标准 I/O 以建立松散绑定。最初,我们避免将国际象棋代码与 PeerNode 客户端直接链接,以便在软件的未来迭代中可以快速轻松地替换国际象棋代码。后来,我们转向静态链接方法来处理潜在的安全问题。问题在于,完全有可能编写一个位于 PeerNode 和实际国际象棋引擎程序之间的国际象棋引擎代理。这将提供一种在将结果发送到 SuperNode 服务器之前轻松更改结果的方法。我们决定静态链接引擎组件,因为有两个关键优势,更严格的安全性以及基于函数而不是基于 I/O 的消息传递。

来自 Slashdot 的兴趣激增很快使得降低 ChessBrain 的带宽需求成为必要。为此,SOAP 的使用提供了许多优势,但其大小仍有不足之处。Zlib 数据压缩库(www.zlib.org)现在在加密之前使用,以减小基于 SOAP 的消息传递的大小。当然,添加压缩和加密会降低互操作性的潜力;但是,XML 加密规范(www.w3.org/TR/xmlenc-core)提供了另一种方法。

机器人、在线状态和自主游戏

SuperNode 服务器有一个名为 Shannon 的 Bot(作为线程实现),它连接到在线游戏服务器并维护在线状态。游戏服务器的成员键入命令以挑战 ChessBrain 或观看正在进行的游戏。对 Shannon 进行编程很有趣,Shannon 现在理解各种命令。在线 Bot 具有巨大的潜力,可以指示它们代表其主机执行操作。

在 ChessBrain 的开发过程中,我下载了免费互联网国际象棋服务器 (FICS) 的源代码,并在运行 Linux 的旧 Pentium 200 MMX Toshiba 笔记本电脑上对其进行了编译。FICS 是用 C 编写的,它使用 GCC 编译时没有出现任何问题。游戏服务器允许用户通过 Telnet 连接到端口 5000 并使用用户名和密码登录。几个月后,流量增加,我们将 FICS 服务器移动到我们在 distributedchess.net 的辅助域的另一台 ChessBrain 机器。用户现在有多种选项可以在线观看 ChessBrain 游戏。他们可以直接 Telnet 连接到 ChessBrain 正在玩的游戏服务器,也可以使用我们的查看器程序之一。

在 ChessBrain 可以在线游戏服务器上玩游戏后,我编写了一个 Java 游戏查看器,以允许人们观看直播游戏。作为 Java 查看器的替代方案,我还编写了基于 PHP 和 Macromedia Flash 的查看器(www.chessbrain.net/viewers.html)。ChessBrain 贡献者 Anthony Bravo 编写了一个基于 Java 的网络查看器,以显示世界各地的活动 PeerNode。用户可以单击节点以查看特定国家/地区中有多少机器处于活动状态。ChessBrain 站点上的所有查看器都使用 SOAP 与 SuperNode 通信。

作为安全预防措施,浏览器插件(例如 Java 和 Macromedia 的 Flash ActionScript)不允许程序连接到下载小程序所在的服务器以外的服务器。为了解决这个问题,我编写了一个简单的 XML 代理脚本,该脚本接受一台服务器上的 HTTP GET 请求,并代表客户端连接到 SuperNode 服务器。例如,如果您想查询 SuperNode 服务器的当前游戏局面,您可以在浏览器中输入以下 URLhttp://www.chessbrain.net/xmlproxy.php?command=CBSGetPos。服务器将响应类似于图 4 中的 SOAP 包。在 Mozilla 上,您可以查看页面源代码以查看实际的 SOAP 文档。

列表 1. ChessBrain XML 响应包

<?xml version="1.0" ?>
<env:Envelope xmlns:env=
  http://www.w3.org/2001/12/soap-envelope
  xmlns:enc=
    "http://www.w3.org/2001/12/soap-encoding">
  <env:Body>
    <cbs:CBSGetPosResponse
        >
      <return>
        rn1qk2r/p2p1ppp/bb2pn2/1p6/1P6/
        P2Q1NP1/1BP1PP1P/RN2KB1R b KQkq -
      </return>
    </cbs:CBSGetPosResponse>
  </env:Body>
</env:Envelope>

监视 SuperNode

监视服务器的运行状况是系统管理的重要组成部分。幸运的是,对于开发人员来说,Linux 提供了许多方法来解决服务器监视问题。Linux /proc 虚拟文件系统包含大量有价值的系统数据,为开发人员提供了一种简便的方法来分析和监视系统行为。/proc/net/dev 提供设备数据,例如在网络接口上发送和接收的字节数和数据包数,而 /proc/meminfo 提供大量内存统计信息。如果数据挖掘 /proc 不是您喜欢的事情,则 sysinfo() 提供了一种快速简便的方法来填充包含系统统计信息的结构,例如系统负载、可用内存和进程总数。

SuperNode 服务器提供一个 SOAP 请求,该请求返回类似于列表 2 中显示的系统信息。ChessBrain 成员 Greg Davis 用 Perl 编写了第一个 SuperNode 监视器,该监视器发出 SOAP 请求并显示类似于 top 命令的屏幕。

列表 2. XML 服务器状态消息

<?xml version="1.0" ?>
<env:Envelope

>
  <env:Body>
    <cbs:CBSSysInfoResponse
      >
    <Uptime days="1" hours="14"
            minutes="43" seconds="18" />
    <System proccnt="546" totmem="250.13"
            freemem="4.38"
            memu="98"
            cpustates="3627078,0,2151891,8160852"
            loadavg="0.50,0.30,0.33" />
      <Recv Bytes="2301480887.000000"
            Packets="16652816.000000"
            Errors="0.000000"
            Drop="0.000000" />
      <Send Bytes="2443488824.000000"
            Packets="12142245.000000"
            Errors="0.000000"
            Drop="0.000000" />
     </cbs:CBSSysInfoResponse>
   </env:Body>
</env:Envelope>

PeerNode 监视

由于 ChessBrain 社区的许多成员在多台机器上运行 PeerNode 客户端,因此他们希望有一种方便的方法来监视一组机器的状态。PeerNode 客户端已修改为将 SOAP 请求发布到端口 3434,以便 PeerNode 监视器应用程序可以侦听该端口并显示实时状态信息。我编写了第一个 PeerNode 监视器应用程序,其他成员也提交了自己的监视器。Greg Davis 和 Oliver Otte 都提交了基于 Perl 的 PeerNode 监视器。最受欢迎的 PeerNode 监视器 CBMoc 是由 Kris Drent 用 Java 编写的。

ChessBrain: a Linux-Based Distributed Computing Experiment

图 3. 基于 Java 的 CBMoc

跨平台图形和数据可视化

ChessBrain 收集了大量数据,我们目前正在探索数据可视化作为一种跟踪和调查系统行为的方法。我们正在添加基于 3D 的游戏导航工具,以便我们能够以可视方式跟踪网络游戏。我们的常驻 3D 专家 Sven Herrmann 创建了一个基于 OpenGL 的渲染器,我们在 SuperNode 监视器应用程序中使用它。我们还将在我们的下一代屏幕保护程序和游戏查看器中使用新的渲染器。

ChessBrain: a Linux-Based Distributed Computing Experiment

图 4. 实时 OpenGL 渲染

结论

今天,ChessBrain 是一个可工作的原型,它使用数百台运行 Linux、FreeBSD、Mac OS X 和 Microsoft Windows 的机器下棋。它的棋力达到国际大师水平,我们看到了许多继续改进的方法。

ChessBrain 证明了使用开源工具来解决复杂问题的用途。我们正在准备将 ChessBrain 本身作为开源项目发布,希望其他人加入并扩展这项工作。ChessBrain 的美妙之处在于有很多贡献方式。任何拥有 PC 和互联网连接的人都可以参与。从 ChessBrain 网站下载 PeerNode 客户端,在一台或多台计算机上运行该软件,并帮助扩大 ChessBrain 的规模。

我们目前正在努力争取使用最多机器玩单局游戏的官方世界纪录。我们与伦敦世界纪录办公室建立了联系,并在多个官方国际象棋联合会内建立了联系。ChessBrain 项目得到了强大的核心团队的支持,包括世界国际象棋联合会 (FIDE) 计算机国际象棋和互联网委员会前主席 Peter Wilson。ChessBrain 团队目前正在探索公开和基于互联网的演示的潜在场所,该演示涉及分布式计算和国际象棋的新吉尼斯世界纪录。请查看 ChessBrain 网站以获取官方公告。

致谢

非常感谢 Janus Daniels、Cedric Griss 和其他 ChessBrain 团队成员对本文准备工作的支持。有关联系信息和 ChessBrain 团队成员名单,请访问 www.chessbrain.net/friends.html

Carlos Justiniano 是一位拥有 20 年软件行业经验的资深人士。ChessBrain 让他能够实践几个座右铭:“拥抱复杂性”、“从事非凡的追求”和“使用开源软件来完成它”!有关本文的评论可以发送至 cjus@chessbrain.net

加载 Disqus 评论