Artikelimport über Cronjob verdoppelt jedes Mal Artikelbilder - Server voll

Hallo, wir haben einen regelmäßig laufenden Artikelimport via CronJob. Dieser liest Daten von einer Quelle ein und spielt sie über die REST API wieder ein.

Dafür wird das Konstrukt mit **Manager::getResource(„article“) **genutzt.

Es werden auch 1x pro Woche die Artikelbilder mit diesem Import eingespielt, da man nicht weiß, welche Bilder sich ggf. geändert haben. Wir übergeben auch das Flag  __options_images

blöderweise bleiben die alten Bilder physisch immer im MedienManager bzw. auf dem Server liegen. Da wir ungefähr 15GB Bilder haben, ist der Server spätestens nach dem 3. Durchlauf voll… 

gibt es eine Möglichkeit, die Bilder nicht nur in der DB zu überschreiben, sondern auch die entstehenden Leichen zu löschen?

Es gibt ja diesen MediaCrawler Cronjob, der alle ungenutzten Bilder in den Papierkorb schiebt. Kann man diesen Cronjob in unserem Cron aufrufen, und anschließend auch ein Leeren des Papierkorbs triggern?

Oder gibt es eine andere automatische Möglichkeit?

Nur so eine Idee: Was wäre denn jetzt wenn ihr vor dem Import der neuen Bilder erst die alten Bilder per API löscht?

@R4M‍ dann ist unser Shop für einige Stunden (bis die neuen drin sind) komplett ohne Bilder. Nicht sonderlich praktikabel leider.

Hm, vielleicht mißverstanden. Ich meinte direkt vor dem Import die Delete Funktion ausführen.

Wobei, bei der REST API gibt es doch PUT für Update. Da sollte das Bild doch ausgetauscht werden.

wir nutzen nicht direkt die REST API, sondern lediglich die Article-Resource. Da gibt es create oder update. Bei einem Update kann man zwar die Bilder im Artikel überschreiben, die Bilddateien von vorher bleiben aber auf dem Server liegen.

Hm, dann vielleicht einen anderen Weg gehen. Über die Article-Ressource die ID ermitteln und über die Media-Ressource mit der ermittelten ID das Bild updaten. Mehr fällt mir eben auch nicht ein.

Das wäre möglich, ist bei einer Artikelanzahl von ca. 17.000 und daraus folgend ca. 50.000 Artikelbildern aber ziemlich laufzeitintensiv…

In der Regel werden ja nur die Bilder ersetzt, die auch ersetzt werden müssen. Eventuell kann man dies noch eingrenzen - ggf. extra Schnittstelle anpassen.

Um zu wissen, welche Bilder sich geändert haben, müsste ich die Bilder ja alle vergleichen. Das ist bei der Anzahl nicht machbar…

Hallo

Wir haben das gleiche Problem.

Die Artikelbilder haben wir alle löschen müssen, weil der Shop sich nicht mehr aufgerufen werden konnte. Nicht einmal mehr mail kamen durch, weil der Server voll war.

Wir haben festgestellt, dass die CronJobs anscheinend nicht greifen. Müssen die denn an anderer Stelle ein oder ausgeschaltet werden?

Es gibt keine Anleitung darüber und wir haben keinen gefunden der das Problem lösen kann.

Natürlich gibt es eine Dokumentation dazu:

https://docs.shopware.com/de/shopware-5-de/einstellungen/system-cronjobs

https://docs.shopware.com/de/shopware-5-de/inhalte-und-medien/medien#konsolentools

Shopware kann nur Bilder löschen, die es noch kennt. Wenn die Bilder also noch im Media Manager vorhanden sind und nicht mehr dem Artikel zugeordnet, dann findet die auch der Garbage Collector. Wenn die nur noch im Dateisystem liegen und nicht mehr im Mediamanager, dann kennt Shopware die Bilder nicht mehr. Zusätzlich kann man pro Album definieren ob es durchsucht wird.

Unabhängig davon ist es ja auch ein großer Unterschied ob man die API, die Models oder das Import/Export Tool nutzt. Hier geht es ja um die Models, also ein eigenes Plugin/Erweiterung. Da würde ich empfehlen das Medium vorher zu löschen und dann das Update zu fahren. Oder halt den Cleanup zu nutzen, wenn das Bild im mediamanager bleibt Unmut vom Artikel gelöst wird.

 

gibt es eine Mögllchkeit den Media Clean Job programmatisch in einem Plugin aufzurufen?

ich kann nicht für 17.000 Artikeln und 50.000 Bildern bei jedem einzelnen Artikel erstmal die Medien IDs ermitteln, dann die Medien löschen und danach 50.000 Bilder wieder einspielen… 

wieso löscht der Updatebefehl nicht die Bilddateien?

Du hast doch sicherlich einen Cronjob für dein Plugin. Dann kannst du den cleanup auch einfach direkt danach laufen lassen. Geht ja per Cronjob oder per Shell. Wüsste nicht, warum man das per Plugin machen müsste.

Unabhängig davon würde ich auch nicht alle Bilder jedes Mal mit updaten, dass ist ja auch Mega inperformant. Da ist es doch sicherlich schneller vorher ein Get zu machen und dann in PHP zu prüfen ob es neue Bilder gibt. Wenn nicht, dann die Bilder erst garnicht mit zu schicken.

Der Unterschied ist einfach. Columns werden aktualisiert (bspw. Artikelname), Entries hinzugefügt (bspw. Bilder, ähnliche Artikel, …). Wenn man das anders braucht, muss man das aktuell selbst lösen.

 

mir ist bewusst, dass das sehr inperformant ist… ich wüsste leider nicht, wie das anders gehen soll.

Ein Artikel liefert im Import beispielsweise 3 URLs zu Bildern mit. Der Artikel in der Datenbank hat aktuell ebenfalls 3 Bilder. Ich weiß jetzt nicht, ob die identisch sind oder ob sich eines davon geändert hat. Denn die ursprüngliche Bild-URL gibt es ja nicht mehr, der Artikel in der Datenbank hat eigene Shopware-URLs.

Ja, der Import läuft als Cron. Allerdings sind das bei einem vollen Durchlauf aller Bilder ungefähr 25GB Bilder. Also die alten Bilder 25GB + die neuen Bilder 25GB. Ergibt 50GB, so viel Webspace haben wir nicht. Die alten Bilder würden dann ja erst nach dem Import entfernt werden.

ps: habe gesehen, dieser MediaCrawler löscht keine Bilder, er verschiebt sie nur in den Papierkorb. Sie bleiben also auf dem Server. Kann man die auch automatisch komplett aus dem Papierkorb entfernen lassen?

Der hat einen zusätzlichen Flag für --delete, wenn du die Shopware-Konsole benutzt.
Naja, du kannst das ja auch im Batch machen - erst x-Produkte updaten, Bilder löschen, die nächsten x updaten. Das funktioniert natürlich nur, wenn die Bilder auch im Mediamanager bleiben und nicht komplett verschwinden.

Ansonsten kannst du die ursprüngliche URL ja bspw. in einem Attribut des Bildes mitspeichern und dann kannst du auch wieder vergleichen.

Um zu wissen, welche Bilder sich geändert haben, müsste ich die Bilder ja alle vergleichen.

Vielleicht stehe ich ja auf dem Schlauch, aber bei einem Kunden von uns (auf einem andeern Shopsystem) läuft das ganz easy.

Artikel werden per API importiert. Im Anschluss werden die Bilder mit Hilfer der Artikelnumer in das System eingespielt. Sollten nun im laufe der Zeit neue Bilder ergeben, dann wird ein extra Import mit den neuen Bildern gestartet. Hierbei haben die Bilder die Artikelnummer im Dateinamen. Die neuen Bilder werden als ZIP-Datei in einen Ordner abgelegt. Ein Cronjob läuft die Ordner durch und aktiviert den Import-Prozess. Beim Import werden die alten gelöscht und die neuen angelegt. Ich kann mir das nicht vorstellen, dass dies hier bei Shopware nicht gehen sollte. Kein Mensch tauchst den kompletten Bildbestand regelmäßig aus, wenn es dafür keinen Grund gibt. Eventuell muss man seine Schnittstelle umstellen, anpassen wie auch immer. Ähnlich verhällt es sich mit den Artikel-Updates. CSV-Datei werden als ZIP in einem Ordner abgelegt. Ein Cronjob macht dann den Rest.

Das war jetzt nur ein Beispiel, aber dies sollte hier auch möglich sein. Ggf. kann man auch eine eigene Schnittestelle bauen.

 

Ja, der Import läuft als Cron. Allerdings sind das bei einem vollen Durchlauf aller Bilder ungefähr 25GB Bilder.

Hier würde ICH mir Gedanken machen wie ich das Effektiver gestalten könnte. Voller Durchlauf ist jedenfalls nicht der richtige Weg.

eigentlich möchte ich ungern 17.000 Artikel laden um ihre Bilder zu vergleichen… das ist ja auch nicht gerade eine verkürzung der Verarbeitungszeit…

es gibt also wirklich keine Möglichkeit für ein ECHTES Ersetzen der Bilder? Schade…

ich möchte für einen Aufruf des Media-Delete-Jobs natürlich nicht die Console nutzen, sondern er soll von einem Cron auf unserem Server angestoßen werden über die https://www.meinshop.de/backend/cron

 

eigentlich möchte ich ungern 17.000 Artikel laden um ihre Bilder zu vergleichen

Das soll ja auch keiner. Es sollen nur die Bilder hochgeladen werden die der Kunde als neue Bilder definiert hat. Das muss man doch irgendwie in den Griff bekommen? 

@FloC3 schrieb:

ich möchte für einen Aufruf des Media-Delete-Jobs natürlich nicht die Console nutzen, sondern er soll von einem Cron auf unserem Server angestoßen werden über die https://www.meinshop.de/backend/cron

So würde man aber auch nie einen Cronjob einrichten, wenn man will, dass der performant läuft. Auch hierzu gibt es einen Konsolen-Befehl, der die Cronjob-Queue anstößt. Der Aufruf von /backend/cron per wget oder Browser unterliegt den Begrenzungen des Webservers (bspw. max_execution_time). Sinniger wäre schon ein aufruf per Konsole, auch für den Cronjob. Das Web-Interface ist nur für Hosting-Umgebungen die keinen SSH-Zugang haben und/oder keine möglichkeit einen „richtigen“ Cronjob einzurichten.