小编sne*_*son的帖子

排除非排他性的价值对

使用英语很难描述这个问题,所以我将给出一些例子.

我有一张名为Games的桌子.每个游戏由游戏编号和玩家组成,分为两列:GameNum,PlayerNum.

我的问题是,我想选择那些参加过比赛的球员,而不是其他人.

以下是一些示例数据:

GameNum PlayerNum
1       100
1       101
2       102
2       103
3       102
3       104
4       105
4       106
5       106
5       107
6       100
6       101
Run Code Online (Sandbox Code Playgroud)

我想找回结果:

PlayerNum1 PlayerNum2
100        101
Run Code Online (Sandbox Code Playgroud)

这是因为我们可以看到玩家100和101是唯一一个彼此玩游戏的玩家,而没有其他玩家.102也玩了104,所以我们排除102和104.虽然105只玩了106的游戏,106也玩了107游戏,所以我们排除玩家105和106(因此107)的结果.这让我们只有玩家100和101.

每个GameNum只会在表格中出现两次(即每个游戏总是会有两个玩家).另请注意,我们并不关心玩家是否一起玩过多个游戏(例如GameNum 1和6) - 前提是他们只是互相玩过这些游戏.

我尝试使用min/max进行类似下面的查询,但我无法弄清楚如何排除与其他玩家玩过游戏的玩家.

SELECT *
FROM
(
    SELECT AU1.PlayerNum AS PlayerNum1, AU2.PlayerNum AS PlayerNum2
    FROM
    (
      SELECT GameNum, MIN(PlayerNum) AS PlayerNum
      FROM GAMES
      GROUP BY GameNum
      HAVING count(GameNum) = 2
    ) AU1
    INNER JOIN 
    (
      SELECT GameNum, MAX(PlayerNum) …
Run Code Online (Sandbox Code Playgroud)

sql oracle

5
推荐指数
1
解决办法
96
查看次数

设计分布式网络抓取器

问题

最近,我一直在考虑如何抓取某个大型跨国网站的内容,以获取该公司出售的产品的具体详细信息。该网站没有 API,但您可以通过将带有产品 ID 的 GET 请求发送到特定 URL 来下载每个产品的一些 XML。所以至少是这样。

问题在于,可能存在数亿个潜在产品 ID(例如,000000001 到 500000000 之间),但实际存在的产品只有几十万个。而且不可能知道哪些产品 ID 是有效的。

方便的是,向产品 URL 发送 HEAD 请求会根据产品 ID 是否有效(即产品实际存在)产生不同的响应。一旦我们知道该产品确实存在,我们就可以下载完整的 XML 并从中获取所需的数据位。

显然,如果在单个服务器上运行,发送数亿个 HEAD 请求将花费大量时间才能完成,因此我想借此机会学习如何开发某种分布式应用程序(对于我)。在这一点上,我应该提到这个特定的网站可以轻松地每秒处理大量传入请求,而不会出现 DOS 风险。我不想透露该网站的名称,但它每天很容易获得数百万次点击。该抓取工具对网站性能的影响可以忽略不计。不过,如果公司投诉,我会立即制止。

该设计

我不知道这是否是正确的方法,但我当前的想法是启动一个“协调服务器”,以及一些与该服务器通信并执行抓取的节点,所有这些都作为 EC2 实例运行。

每个节点将启动一定数量的进程,并且每个进程将由协调服务器指定一个作业,其中包含要抓取的不同范围的潜在产品ID(例如产品ID 00001 到10000)。这些作业将存储在协调服务器上的数据库表中。每个作业将包含以下信息:

  • 产品 ID 起始编号
  • 产品 ID 尾号
  • 作业状态(空闲、进行中、完成、过期)
  • 职位到期时间
  • 时间开始
  • 完成时间

当节点启动时,查询将被发送到协调服务器,询问一些配置数据以及要处理的作业。当节点完成作业时,将发送一个查询来更新刚刚完成的作业的状态,并发送另一个查询来请求执行新作业。每个作业都有一个到期时间,因此如果进程崩溃,或者节点因任何原因发生故障,另一个节点可以接管过期的作业并重试。

为了最大限度地提高系统性能,我需要计算出应立即启动多少个节点、每个节点有多少个进程、发送 HTTP 请求的速率以及哪种 EC2 实例类型将提供最大的性价比(我猜测高网络性能、高 CPU 性能和高磁盘 I/O 将是关键因素?)。

目前,计划是用 Python 编写抓取工具,在 Ubuntu EC2 实例上运行,可能在 Docker 容器中启动,并使用某种键值存储数据库来保存协调服务器(MongoDB?)上的作业。关系数据库也应该可以工作,因为作业表的 I/O 应该相当低。

我很想知道更有经验的工程师这是否是正确的方法,或者我是否完全忽略了完成此任务的更好方法?

非常感谢,谢谢!

cloud distributed-computing amazon-web-services

0
推荐指数
1
解决办法
3421
查看次数