Ich habe eine Liste von Webseiten, die ich kratzen, analysieren und dann die resultierenden Daten in einer Datenbank speichern muss. Die Summe beträgt rund 5.000.000.
Meine derzeitige Annahme, dass dies am besten angegangen werden kann, besteht darin, ~ 100 EC2-Instanzen bereitzustellen, jeder Instanz 50.000 Seiten zum Scrapen bereitzustellen und diese dann laufen zu lassen. Sobald der Prozess abgeschlossen ist, werden die Datenbanken zusammengeführt. Die Annahme ist, dass die Ausführung ungefähr einen Tag dauern würde (600 ms zum Laden, Parsen und Speichern jeder Seite).
Hat jemand Erfahrung damit, innerhalb einer begrenzten Zeit so viel Seiten zu kratzen? Ich habe schon große Zahlen gemacht (1,5 m), aber das war von einer einzigen Maschine und dauerte etwas mehr als eine Woche.
Der Engpass in meiner Situation ist das Herunterladen der Seiten. Das Parsen dauert nicht länger als 2 ms. Daher suche ich nach etwas, das den Prozess des Herunterladens der Seiten rationalisieren kann.
quelle
Antworten:
Unter der Annahme, dass die Downloadzeit (und damit die Bandbreitennutzung) Ihr begrenzender Faktor ist, würde ich folgende Vorschläge machen:
Wählen Sie zunächst m1.large-Instanzen. Von den drei E / A-Leistungsstufen (einschließlich Bandbreite) bieten die Instanzen m1.large und m1.xlarge eine hohe E / A-Leistung. Da Ihre Aufgabe nicht an die CPU gebunden ist, ist die kostengünstigste davon die bevorzugte Wahl.
Zweitens kann Ihre Instanz viel schneller herunterladen, als jede Site Seiten bereitstellen kann. Laden Sie nicht jeweils eine Seite auf einer bestimmten Instanz herunter, führen Sie die Aufgabe gleichzeitig aus. Sie sollten jedoch mindestens 20 Seiten gleichzeitig ausführen können (obwohl Ich würde vermuten, dass Sie wahrscheinlich 50-100 ohne Schwierigkeiten machen können). (Nehmen Sie das Beispiel des Herunterladens aus einem Forum aus Ihrem Kommentar - das ist eine dynamische Seite, deren Generierung die Serverzeit in Anspruch nimmt - und es gibt andere Benutzer, die die Bandbreite dieser Site usw. verwenden.) Erhöhen Sie die Parallelität weiter, bis Sie die Grenzen der Instanzbandbreite erreichen. (Stellen Sie natürlich nicht mehrere gleichzeitige Anfragen an dieselbe Site).
Wenn Sie wirklich versuchen, die Leistung zu maximieren, können Sie Instanzen in geografisch geeigneten Zonen starten, um die Latenz zu minimieren (dies würde jedoch die Geolokalisierung aller Ihrer URLs erfordern, was möglicherweise nicht praktikabel ist).
Zu beachten ist, dass die Instanzbandbreite variabel ist, manchmal eine höhere Leistung erzielt wird und manchmal eine geringere Leistung erzielt wird. In den kleineren Fällen ist die Leistungsschwankung bedeutender, da die physischen Verbindungen von mehr Servern gemeinsam genutzt werden und diese die verfügbare Bandbreite verringern können. Zwischen m1.large-Instanzen sollten Sie innerhalb des EC2-Netzwerks (gleiche Verfügbarkeitszone) einen theoretischen Gigabit-Durchsatz erreichen.
Im Allgemeinen ist es mit AWS fast immer effizienter, eine größere Instanz zu verwenden, als mehrere kleinere Instanzen (es sei denn, Sie betrachten speziell etwas wie Failover usw., bei dem Sie mehrere Instanzen benötigen).
Ich weiß nicht, was Ihr Setup beinhaltet, aber als ich dies zuvor versucht habe (zwischen 1 und 2 Millionen Links, regelmäßig aktualisiert), bestand mein Ansatz darin, eine Datenbank mit den Links zu führen, neue Links hinzuzufügen, sobald sie gefunden wurden, und Prozesse zu forken die Seiten zu kratzen und zu analysieren. Eine URL wird (zufällig) abgerufen und in der Datenbank als in Bearbeitung markiert markiert. Das Skript lädt die Seite herunter. Wenn dies erfolgreich ist, markiert es die in der Datenbank heruntergeladene URL und sendet den Inhalt an ein anderes Skript, das die Seite analysiert hat, sowie neue Links wurden der Datenbank hinzugefügt, sobald sie gefunden wurden. Der Vorteil der Datenbank war hier die Zentralisierung: Mehrere Skripte konnten die Datenbank gleichzeitig abfragen, und (solange Transaktionen atomar waren) konnte sichergestellt werden, dass jede Seite nur einmal heruntergeladen wurde.
Einige zusätzliche Erwähnungen: Es gibt Beschränkungen (ich glaube 20) für die Anzahl der On-Demand-Instanzen, die gleichzeitig ausgeführt werden können. Wenn Sie diese Beschränkungen überschreiten möchten, müssen Sie AWS anfordern, um die Anzahl Ihrer Konten zu erhöhen Grenzen. Es wäre viel wirtschaftlicher für Sie, Spot-Instanzen auszuführen und Ihre Zahlen zu skalieren, wenn der Spot-Preis niedrig ist (möglicherweise eine On-Demand-Instanz, um alles zu organisieren, und die verbleibenden Spot-Instanzen).
Wenn die Zeit für Sie eine höhere Priorität als die Kosten hat, bieten die Cluster-Recheninstanzen eine Bandbreite von 10 Gbit / s - und sollten die größte Download-Bandbreite bieten.
Fazit: Probieren Sie einige große Instanzen (anstelle vieler kleiner Instanzen) aus und führen Sie mehrere gleichzeitige Downloads für jede Instanz aus. Fügen Sie weitere Instanzen hinzu, wenn Sie eine begrenzte Bandbreite haben. Wechseln Sie zu größeren Instanzen, wenn Sie feststellen, dass die CPU / der Speicher gebunden ist.
quelle
Wir haben versucht, etwas Ähnliches zu tun, und hier sind meine 5 Cent:
Holen Sie sich 2-3 billige Server ohne Messgerät, z. B. zahlen Sie nicht für die Bandbreite.
Verwenden Sie Python mit Asyncore. Asyncore ist die alte Art, Dinge zu tun, aber wir haben festgestellt, dass es schneller funktioniert als jede andere Methode. Nachteil ist, dass die DNS-Suche blockiert, dh nicht "parallel". Mit Asyncore haben wir es geschafft, 40 Minuten lang 1 Million URLs mit einzelnen XEON 4-Kernen und 8 GB RAM zu kratzen. Der durchschnittliche Auslastungsgrad auf dem Server betrug weniger als 4 (das ist hervorragend für 4 Kerne).
Wenn Sie Asyncore nicht mögen, versuchen Sie es mit gevent. Es wird sogar DNS nicht blockiert. Unter Verwendung von gevent wurde 1M für ca. 50 Minuten auf dieselbe Hardware heruntergeladen. Die durchschnittliche Auslastung des Servers war enorm.
Beachten Sie, dass wir viele Python-Bibliotheken wie Grequests, Curl, Liburl / Liburl2 getestet haben, Twisted jedoch nicht .
quelle