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?
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
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
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
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 ) 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
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.
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?
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.
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 )