[Studiu de caz] Migrare magazin online

Salut,
Cred ca e primul meu script de migrare pe care il fac care manipuleaza un volum foarte mare de date.
Ce face mai exact: Ia produsele dintr-o platforma de ecommerce si il le muta in alta.
Ce tehnologii folosesc: NodeJS/TS/Sqlite
Cifre: 13k produse, 350 categorii, 33k imagini, 86k combinatii de produs in categorie. probabil vreo 500k-800k linii de log
Lucruri interesante de care m-am lovit au fost:

  • din 2 module de loggere (pino/ winston) am observat ca dupa o vreme inceteaza sa mai trimita atat log catre fisier dar si catre consola
  • datele trebuiesc procesate in batchuri. De exemplu in loc sa iau toate produsele si apoi sa fac operatii pe ele, ele trebuisc luate in batchuri mici pentru se incarca datele in memorie si crapa Node-ul.
  • selecturile trebuiesc optimizare . Select * consuma multe resurse degeaba
  • db-ul sqlite este destul de performant. Acum nu am stat sa fac o comparatie intre el si un altul dar pare ca isi face bine treaba
  • db-ul dupa ce am luat datele de la client a ajuns la 13gb
  • dupa ce se convertesc toate datele primite in taskuri catre platforma destinatie rezulta 103k taskuri.
  • durata totala unei migrari complete este de 2 zile (inca rumega la date). Problema cea mai mare este ca in platforma destiantie pot sa adaug un task la 1.5 secunde .
  • pana acum nu am rulat o migrare completa dar am vazut ca cel mai mult db-ul s-a dus in 47gb. Acum nu stiu daca sqlite isi face vacum automat. (In el am tot sters o tabela de mai multe ori)
  • pe magazinul de test cu cateva produse merge bine. Scriptul a functionat bine. Cand l-am pus pe multe date a inceput sa crape in special din cauza leakului de memorie generat de mai multe date.
  • db-ul are 3 tablele : resources (unde tin ce iau din magazinul destinatie), dest_resources (unde din resursele primite de la destinatie creez noile obiecte) si tasks (unde tin fiecare task cu payload si raspuns)
  • modulul de sqlite crapa daca ii trimiti un array gol cand faci un select… in() pentru ca el de fapt aduce toate datele, dar pentru ca este o tabela mare o incarca in memorie si lesina
  • am aflat cu ocazia asta ca pot sa triggeruiesc manual garbage collector-ul . Nu a fost cazul la mine.
  • ma gandesc la diverse optimizari precum: Poate in loc sa tin in tabela resources datele separat (e.g: product, product_stocks, product_attributes, …) pe linii diferite as putea sa am o singura linie product si sa bag in json informatiile de mai sus. Ar economisii ceva timp dar de fapt buba cea mare este la destinatie si la limitarea de 1 request la 1.5 secunde.
  • daca gasesc o modalitate sa bag produsele in categorii la destinatie in batchuri in loc de unu cate unu as economisii 80% din timp. (am vazut ceva dar trebuie sa incerc)
  • sunt cazuri in care sunt 4500 de produse intr-o categorie . Imi e teama ca daca fac in batchuri sa nu crape api-ul la destinatie. Ori datorita loadului, ori sa dea un timeout de toata frumusetea, ori sa aiba rise condition si sa execute partial daca nu sunt facute in tranzactii.
  • aplicatia de node sta intre 300 si 800 mb constant.

Asta e cam tot ce mi-a venit in cap.
Voi ce experienta aveti cu migrari mai de date? Ce abordari folositi?

2 Likes

sunt curios catre ce platforma ai migrat. mi se pare enorm timpul de migrare.

acum cativa ani am facut o migrare, la fel, intre platforme de ecomm. am avut ~60-70k produse, 150-200 de categorii plus dumnezeu stie cate imagini. tin minte ca a durat importul cateva ore, in niciun caz zile

1 Like

ne poti spune si care sunt platformele?

din shopify am extras cu graphql si python si merge chiar bine (la fel si pentru update in shopify).
din / in drupal si alte similare… pe baza de csv.
ce mi se pare important e sa reusesti sa mapezi corect entitatile si sa tratezi la migrare diferentele (inevitabile as zice) intre cele doua magazine

1 Like

Prestashop → Shopify.

2 Likes

Shopify e lent la alte optiuni . Adica daca la get poti lua 250 de produse, nu poti insera si 250 de produse odata.

2 Likes

mi-e greu sa cred ca nu exista un saas de migrate2shopify conform unui csv/json in asa fel incat rolul tau sa fie doar generarea acelui csv/json.

site-ul a avut 2 zile downtime pt a face migrarea?

Exista solutii de migrat dar nici una gratuita.
Referitor la 2 zile . Am explicat ca shopify are un rate limit de 40 requesturi pe minut si fiind multe taskuri se ajunge la numarul ala impresionant de ore. Am gasit solutia de batching la produse in categorii si reusesc sa il fac in sub 10 ore :slight_smile:

1 Like

La un site care (bănuiesc) că produce bani serioși, mă gândesc că poate s-ar merita, decât să stai să îți bați capul atâta.

Sau dacă o faci și ca activitate didactică, să capeți experiență e ok, și eu fac așa de multe ori.

aveam impresia ca prin graphql e mai rapid.
depinde de cat de complexa e structura entitatii (cu cat ai mai mult nesting cu atat costul de resursa creste accelerat), dar un insert la 1.5s mi se pare mult.

eu foloseam apiul google sheets (da, uneori excel e db :slight_smile: ) pentru migrari din astea si piedica era acolo, nu la shopify.

pe de alta parte… eu n-am transferat recent volume asa de mari spre shopify, deci nu te contrazic

1 Like

Partea asta n-am inteles-o. N-ai zis ca a ajuns la 13gb?

Dupa ce am tras tot continutul a fost de 13gb. Dupa ce sm pregatit si datele de trimis si am salvat si raspunsul a mai crescut oleacă:)

Las si eu cateva lucruri despre scripturi de migrare, din experienta. Un script de migrare:

  • ar trebui sa fie capabil sa reia operatiunea de unde s-a oprit
  • ideal ar trebui sa poata rula din nou daca ceva n-a mers, adica sa nu migreze un item a doua oara
  • ar trebui sa ruleze iterativ, pe item sau batch-uri mici de items, ideal parametrizabil sa poti face un warmup
  • ideal ar trebui sa poata rula pe mai multe threaduri fara conflicte intre ele
  • ar trebui sa aiba un mecanism de verificare
  • ar trebui sa logeze tot, atat succes cat si fail
  • ar trebui sa scuipe output in real timesa il poti opri daca sunt probleme

Astea imi vin pe moment, posibil sa fi sarit ceva major. Also, nu mai trebuie sa zic ca trebuie backup inainte si optiune de rollback in caz de ceva.

6 Likes

de acord, ar fi excelent sa fie asa.
totusi, din experienta mea am remarcat si urmatoarele:

  • migrarea se intampla spre finalul proiectului, adica in faza de “trebuie sa fie gata ieri” si resursele de timp sunt limitate
  • de prea putine ori se estimeaza / bugeteaza suficient pentru migrare
  • de multe ori migrarea se intampla pentru ca locul sursa nu mai corespunde (proiect vechi, messy / spaghetti, fara a fi in standarde / bune practici), lucru care te impinge macar in parte la niste improvizatii
  • migrarea se intampla o singura data cu datele astea de intrare / iesire (la urmtoarea o sa ai alta destinatia la sursa si oricum in alta forma + probabil sa fie alte chestii la moda)
  • uneori e mai ieftin sa rulezi de 3 ori complet scriptul decat sa il dotezi cu posibilitatea de resume
  • loggingul de succes e greu sa il verifici la migrare (de obicei verifici niste chei relevante direct in platforma destinatie unde imaginea asupra rezultatului e mai buna).

lucrurile se schimba putin daca vb de “proiecte corporate” unde trasabilitatea e cerinta.
in practica, daca migrezi suficient de coerent catalogul de produse deja ai rezolvat problema principala.
daca ai migrat si clientii deja esti bine.
cand tratezi si istoricul comenzilor esti top.

1 Like

Din ce imi amintesc poti pacali “rate limit” daca creezi mai multe chei (mai multe private apps).
Daca adaugi in shopify 3 apps = 40x3 = 120 req.

Sper ca imi amintesc bine si sa nu te duc in eroare :blush:

2 Likes

Asa e, se poate. Asta înseamnă sa ai mai multe appuri. :slight_smile:

Folosiți careva Pino (NodeJs)? Am văzut ca după o vreme nu mai printeaza in loguri sau fisier… Am citit ceva la ei pe paginacde git dar nu a ajutat.
Aveți experiențe similare?
Ce folosiți pentru logare?

Shopify nu ofera vreun mod rapid de a insera date? Ar fi in interesul lor sa ajute lumea sa migreze cat mai usor la platforma lor.

Vad ca ofera si ceva de bulk operations. Si-au dat si ei probabil seama ca e nevoie.
La shopify restApi-ul se pare ca e asa foarte basic . Adica sunt facute pentru operatii CRUD.
Pe cand Graphql-ul este mai avansat dar trebuie multa atentie ca sa citesti ce face fiecare query/mutation in parte.
Am scazut timpul de la 40 de ore la undeva la 8 ore si cred ca se poate mai bine de atat.
Ce am gasit prin documentatie este ca la o categorie poti sa adaugi produse in batchuri. Nu spun cat de mari pot sa fie batchurile dar eu o sa incerc cu 100. Asta inseamna ca practic nu mai am 80k taskuri de productToCategory si o sa am de 100 ori mai putin. As putea sa incerc si cu 200 daca merge.
Ce e iar foarte aiurea e unele se intorc cu timeout si apoi trebuie verificat daca a crapat si ce a crapat.
Acum sunt destul de avansat cu rest-api-ul si ar fi aiurea sa schimb la graphql.

1 Like

daca am retinut corect
shopify se concentreaza pe graphql, rest urmand sa ramana deprecated

2 Likes

Asa este.
Am vazut ca graphql-ul e mai interesant.
Am dat peste o problema care nu stiu daca exista pe graphql.
Uploadez produse si din cand in când primesc request timeout.
Ati vazut si pe gql aceaid problrma?
Pe gql am posibilitatea de a incarca produse in batch. Le-as pune undeva sus si i-as da link de la imagine. Acum daca imi da request timeout frecvent ca apoi sa le cer eu sa vad daca chiar sunt nu castig prea mult. Este alta strategie mai ok?
(Idea cu batchurilemcu callback nu imi plac prea tare )

1 Like