【问题标题】:Distribute URLs from database evenly across multiple servers将数据库中的 URL 均匀分布在多个服务器上
【发布时间】:2015-02-11 05:54:46
【问题描述】:

目标:循环访问 160,000 个 URL(来自数据库)并点击 4 个不同的 API 并将结果存储到数据库中。

I tried to solving the problem with multiprocessing 但事实证明存在 API 速率限制(600 秒内最多 600 个请求)阻止我在同一服务器上生成多个进程。

所以,看起来我将不得不启动多个服务器,运行脚本(修改为从数据库服务器中提取 URL),然后将结果保存回数据库服务器。

问题

  • 如何防止多个服务器使用同一个 URL?
  • 您还有其他建议/指导吗?

详情/要求

  • Postgres 数据库
  • 带数据库的服务器只有 512MB 内存(如果需要可以增加)
  • 我希望作业的总运行时间少于 2 小时

这是当前格式的 Python 脚本:

import psycopg2
from socialanalytics import pinterest
from socialanalytics import facebook
from socialanalytics import twitter
from socialanalytics import google_plus
from time import strftime, sleep

conn = psycopg2.connect("dbname='***' user='***' host='***' password='***'")
cur = conn.cursor()

# Select all URLs
cur.execute("SELECT * FROM urls;")
urls = cur.fetchall()

for url in urls:

    # Pinterest
    try:
        p = pinterest.getPins(url[2])
    except:
        p = { 'pin_count': 0 }
    # Facebook
    try:
        f = facebook.getObject(url[2])
    except:
        f = { 'comment_count': 0, 'like_count': 0, 'share_count': 0 }
    # Twitter
    try:
        t = twitter.getShares(url[2])
    except:
        t = { 'share_count': 0 }
    # Google
    try:
        g = google_plus.getPlusOnes(url[2])
    except:
        g = { 'plus_count': 0 }

    # Save results
    try:
        now = strftime("%Y-%m-%d %H:%M:%S")
        cur.execute("INSERT INTO social_stats (fetched_at, pinterest_pins, facebook_likes, facebook_shares, facebook_comments, twitter_shares, google_plus_ones) VALUES(%s, %s, %s, %s, %s, %s, %s, %s);", (now, p['pin_count'], f['like_count'], f['share_count'], f['comment_count'], t['share_count'], g['plus_count']))
        conn.commit()
    except:
        conn.rollback()

这是我目前正在考虑的解决问题的方法:

  1. 使用数据库在服务器上创建 API
    • 在您对/api/v1/next-url 执行GET 时返回一个URL
    • 接受对/api/v1/store-results的POST请求
  2. 手动启动约 25 台服务器
  3. 创建脚本,通过我的 API 获取 URL,点击 4 个外部 API,然后通过我的 API 将数据发送回我的数据库。当没有通过第一个 API 端点返回 URL 时,脚本终止。
  4. 手动关闭服务器

非常感谢任何帮助!

【问题讨论】:

  • 如何执行速率限制?如果它是通过 API 密钥,那么你绝对是在叫错树。我只是问,因为速率限制很少通过 IP 强制执行,这必须是您所暗示的情况。
  • 我没有使用 API 密钥,因此必须通过 IP 地址stackoverflow.com/a/8713296/899904 强制执行它们
  • 您将在哪里启动虚拟机? - 因为他们需要有不同的公共 IP。除了手动部分之外,您的想法听起来不错,尝试使用 ansible 之类的东西来启动机器,分发 python 脚本并开始运行它
  • 您不应该联系API提供商并询问他们吗?存在限制是有原因的,试图规避这些限制听起来不是一个好主意。
  • @peter 我使用 DigitalOcean 作为我的 VPS 提供商。我只是假设每个 Droplet 都有自己唯一的公共 IP,不是这样吗?

标签: python postgresql distributed-computing


【解决方案1】:

如何防止多个服务器使用同一个 URL?

一种简单的方法是获取 URL 模服务器计数的哈希值。这为您提供了应该处理该 URL 的服务器的索引。

例如:

server_idx = zlib.crc32(url) % server_count

【讨论】:

  • 你能给我举个例子,看看这在代码中是什么样子的吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
  • 2012-10-16
  • 2011-04-08
  • 2011-12-05
  • 2018-02-06
相关资源
最近更新 更多