2015-02-11 49 views
0

目標:循環訪問160,000個URL(來自數據庫)並打4個不同的API並將結果存儲到數據庫中。從多個服務器中均勻分配來自數據庫的URL

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. 與數據庫
    • 返回一個URL在服務器上創建一個API,當你在/api/v1/next-url
    • 執行GET
    • 接受POST請求至/api/v1/store-results
  2. 手動啓動〜25臺服務器
  3. 創建腳本,命中我的API以獲取URL,點擊4個外部API,然後通過我的API將數據發回我的數據庫。當沒有URL通過第一個API端點返回時,腳本終止。
  4. 手動減速服務器

任何幫助非常感謝!

+0

速率限制是如何執行的?如果它是通過API密鑰的話,那麼你絕對會吼出錯誤的樹。我只問,因爲速率限制很少通過知識產權強制執行,這就是你所暗示的情況。 – 2015-02-11 06:28:07

+0

我沒有使用API​​密鑰,因此必須通過IP地址強制實施http://stackoverflow.com/a/8713296/899904 – Abundnce10 2015-02-11 06:32:34

+0

您將在哪裏啓動虛擬機? - 因爲他們需要有不同的公共IP。除此之外,你的想法聽起來不錯,除了手冊部分,嘗試使用[ansible](http://www.ansible.com/home)之類的東西來啓動機器,分發python腳本並開始運行它 – peter 2015-02-11 08:24:23

回答

0

如何防止多個服務器使用相同的URL?

一個簡單的方法是採用URL模數服務器計數的散列。這爲您提供了應該處理該URL的服務器的索引。

E.g.:

server_idx = zlib.crc32(url) % server_count 
+0

你能給我一個這樣的例子嗎? – Abundnce10 2015-02-11 15:44:43

+0

@ Abundnce10爲你更新了答案 – 2015-02-11 16:03:59