从多个服务器均匀地分配数据库中的URL

时间:2015-02-11 05:54:47

标签: python postgresql distributed-computing

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

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

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

问题

  • 如何阻止多台服务器使用相同的网址?
  • 您还有其他建议/指导吗?

详细信息/需求

  • Postgres数据库
  • 带数据库的服务器只有512MB的RAM(如果需要可以增加)
  • 我希望工作的总运行时间不超过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时返回一个网址
    • 接受对/api/v1/store-results
    • 的POST请求
  2. 手动启动~25台服务器
  3. 创建访问我的API以获取URL的脚本,点击4个外部API,然后通过我的API将数据发布回我的数据库。当没有通过第一个API端点返回URL时脚本终止。
  4. 手动关闭服务器
  5. 非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

  

如何阻止多台服务器使用相同的网址?

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

E.g:

server_idx = zlib.crc32(url) % server_count