Mion-sgrùdadh obrachaidh ann an ailtireachd microservice: cuidich agus brosnaich Postgres FDW

Tha na buannachdan agus na h-eas-bhuannachdan aig ailtireachd microservice, mar a h-uile càil san t-saoghal seo. Bidh cuid de phròiseasan a’ fàs nas fhasa leis, cuid eile nas duilghe. Agus air sgàth astar an atharrachaidh agus scalability nas fheàrr, feumaidh tu ìobairtean a dhèanamh. Is e aon dhiubh iom-fhillteachd an anailis. Mas urrainn ann am monolith a h-uile mion-sgrùdadh obrachaidh a lughdachadh gu ceistean SQL gu mac-samhail anailis, an uairsin ann an ailtireachd ioma-sheirbheis tha a stòr-dàta fhèin aig gach seirbheis agus tha e coltach nach eil aon cheist gu leòr (no is dòcha gum bi?). Dhaibhsan aig a bheil ùidh ann an mar a dh’ fhuasgail sinn an duilgheadas a thaobh mion-sgrùdadh obrachaidh anns a’ chompanaidh againn agus mar a dh’ ionnsaich sinn a bhith beò leis an fhuasgladh seo - fàilte.

Mion-sgrùdadh obrachaidh ann an ailtireachd microservice: cuidich agus brosnaich Postgres FDW
Is e m ’ainm Pavel Sivash, aig DomClick tha mi ag obair ann an sgioba air a bheil uallach airson an taigh-bathair dàta anailis a chumail suas. Gu h-àbhaisteach, faodar ar gnìomhachd a thoirt air sgàth innleadaireachd dàta, ach, gu dearbh, tha an raon de ghnìomhan mòran nas fharsainge. Tha innleadaireachd dàta àbhaisteach ETL / ELT, taic agus atharrachadh innealan sgrùdaidh dàta agus leasachadh nan innealan aca fhèin. Gu sònraichte, airson aithrisean obrachaidh, chuir sinn romhainn “leigeil oirnn” gu bheil monolith againn agus aon stòr-dàta a thoirt do luchd-anailis anns am bi an dàta gu lèir a tha a dhìth orra.

San fharsaingeachd, bheachdaich sinn air diofar roghainnean. Bha e comasach taigh-tasgaidh làn-chuimseach a thogail - dh’ fheuch sinn eadhon, ach, a bhith onarach, cha b’ urrainn dhuinn caraidean a dhèanamh le atharrachaidhean gu math tric anns an loidsig le pròiseas caran slaodach airson stòr a thogail agus atharrachaidhean a dhèanamh air ( ma shoirbhicheas le cuideigin, sgrìobh anns na beachdan ciamar). Dh’ fhaodadh tu a ràdh ri luchd-anailis: “Guys, ionnsaich python agus rach gu loidhnichean mion-sgrùdaidh," ach tha seo na riatanas fastaidh a bharrachd, agus bha e coltach gum bu chòir seo a sheachnadh ma ghabhas sin dèanamh. Cho-dhùin sinn feuchainn ris an teicneòlas FDW (Foreign Data Wrapper) a chleachdadh: gu dearbh, is e dblink àbhaisteach a tha seo, a tha ann an inbhe SQL, ach leis an eadar-aghaidh tòrr nas goireasaiche aige. Air a bhunait, rinn sinn co-dhùnadh, a thàinig gu crìch mu dheireadh, shocraich sinn air. Tha am mion-fhiosrachadh aige mar chuspair artaigil air leth, agus is dòcha barrachd air aon, oir tha mi airson bruidhinn mu dheidhinn tòrr: bho shioncronachadh sgeama stòr-dàta gus faighinn gu smachd agus dì-phearsanachadh dàta pearsanta. Bu chòir a thoirt fa-near cuideachd nach eil am fuasgladh seo an àite fìor stòran-dàta anailis agus stòran, chan eil e a’ fuasgladh ach duilgheadas sònraichte.

Aig an ìre as àirde tha e a’ coimhead mar seo:

Mion-sgrùdadh obrachaidh ann an ailtireachd microservice: cuidich agus brosnaich Postgres FDW
Tha stòr-dàta PostgreSQL ann far an urrainn do luchd-cleachdaidh an dàta obrach aca a stòradh, agus nas cudromaiche, tha mac-samhail anailis de na seirbheisean uile ceangailte ris an stòr-dàta seo tro FDW. Tha seo ga dhèanamh comasach ceist a sgrìobhadh gu grunn stòran-dàta, agus chan eil e gu diofar dè a th’ ann: PostgreSQL, MySQL, MongoDB no rudeigin eile (faidhle, API, mura h-eil pasgan iomchaidh ann gu h-obann, faodaidh tu do chuid fhèin a sgrìobhadh). Uill, tha coltas gu bheil a h-uile dad fìor mhath! A 'briseadh suas?

Nam biodh a h-uile càil a 'tighinn gu crìch cho luath agus cho sìmplidh, an uairsin, is dòcha, cha bhiodh an artaigil ann.

Tha e cudromach a bhith soilleir mu mar a làimhsicheas postgres iarrtasan gu frithealaichean iomallach. Tha e coltach gu bheil seo loidsigeach, ach gu tric chan eil daoine a’ toirt aire dha: bidh postgres a’ roinn a’ cheist gu pàirtean a thèid a chuir gu bàs gu neo-eisimeileach air frithealaichean iomallach, a’ cruinneachadh an dàta seo, agus a’ dèanamh an àireamhachadh deireannach fhèin, agus mar sin bidh astar cur an gnìomh na ceiste gu mòr an urra ri ciamar tha e sgrìobhte. Bu chòir a thoirt fa-near cuideachd: nuair a thig an dàta bho fhrithealaiche iomallach, chan eil clàran-amais aca tuilleadh, chan eil dad ann a chuidicheas an clàr-ama, mar sin, is urrainn dhuinn fhèin a chuideachadh agus a mholadh. Agus is e sin a tha mi airson bruidhinn mu dheidhinn nas mionaidiche.

Iarrtas sìmplidh agus plana leis

Gus sealltainn mar a bhios Postgres a’ ceasnachadh clàr sreath 6 millean air frithealaiche iomallach, leig dhuinn sùil a thoirt air plana sìmplidh.

explain analyze verbose  
SELECT count(1)
FROM fdw_schema.table;

Aggregate  (cost=418383.23..418383.24 rows=1 width=8) (actual time=3857.198..3857.198 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.00..402376.14 rows=6402838 width=0) (actual time=4.874..3256.511 rows=6406868 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Remote SQL: SELECT NULL FROM fdw_schema.table
Planning time: 0.986 ms
Execution time: 3857.436 ms

Le bhith a’ cleachdadh an aithris VERBOSE leigidh sin dhut a’ cheist fhaicinn a thèid a chuir chun t-seirbheisiche iomallach agus na toraidhean a gheibh sinn airson tuilleadh giollachd (sreath RemoteSQL).

Rachamaid beagan nas fhaide agus cuir sinn grunn shìoltachain ris a’ cheist againn: aon às deidh boolean achadh, aon ri dol a steach timestamp gach eadar-ama agus aon le jsonb.

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active is True
AND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' 
AND CURRENT_DATE - INTERVAL '6 month'
AND meta->>'source' = 'test';

Aggregate  (cost=577487.69..577487.70 rows=1 width=8) (actual time=27473.818..25473.819 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.00..577469.21 rows=7390 width=0) (actual time=31.369..25372.466 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: (("table".is_active IS TRUE) AND (("table".meta ->> 'source'::text) = 'test'::text) AND ("table".created_dt >= (('now'::cstring)::date - '7 mons'::interval)) AND ("table".created_dt <= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))
        Rows Removed by Filter: 5046843
        Remote SQL: SELECT created_dt, is_active, meta FROM fdw_schema.table
Planning time: 0.665 ms
Execution time: 27474.118 ms

Seo far a bheil an t-àm ann, air am feum thu aire a thoirt nuair a bhios tu a’ sgrìobhadh cheistean. Cha deach na sìoltachain a ghluasad chun t-seirbheisiche iomallach, a tha a’ ciallachadh, airson a chuir gu bàs, gun tarraing postgres a h-uile sreath 6 millean gus sìoladh gu h-ionadail (an loidhne Filter) agus cruinneachadh a dhèanamh nas fhaide air adhart. Is e an iuchair gu soirbheachas ceist a sgrìobhadh gus am bi na sìoltachain air an gluasad chun inneal iomallach, agus nach fhaigh sinn agus a chruinnicheas sinn ach na sreathan riatanach.

Sin beagan booleanshit

Le raointean boolean, tha a h-uile dad sìmplidh. Anns a 'cheist thùsail, bha an duilgheadas mar thoradh air a' ghnìomhaiche is. Ma chuireas sinn an àite e =, an uairsin gheibh sinn an toradh a leanas:

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table
WHERE is_active = True
AND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' 
AND CURRENT_DATE - INTERVAL '6 month'
AND meta->>'source' = 'test';

Aggregate  (cost=508010.14..508010.15 rows=1 width=8) (actual time=19064.314..19064.314 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.00..507988.44 rows=8679 width=0) (actual time=33.035..18951.278 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: ((("table".meta ->> 'source'::text) = 'test'::text) AND ("table".created_dt >= (('now'::cstring)::date - '7 mons'::interval)) AND ("table".created_dt <= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))
        Rows Removed by Filter: 3567989
        Remote SQL: SELECT created_dt, meta FROM fdw_schema.table WHERE (is_active)
Planning time: 0.834 ms
Execution time: 19064.534 ms

Mar a chì thu, chaidh an sìoltachan chun t-seirbheisiche iomallach, agus chaidh an ùine cur gu bàs a lughdachadh bho 27 gu 19 diogan.

Bu chòir a thoirt fa-near gu bheil an gnìomhaiche is eadar-dhealaichte bhon ghnìomhaiche = an tè as urrainn obrachadh leis an luach Null. Tha e a’ ciallachadh sin chan eil e fìor anns a’ chriathrag fàgaidh na luachan False and Null, fhad ‘s a tha !=Fìor fàgaidh sin dìreach luachan meallta. Mar sin, nuair a thèid an gnìomhaiche a chuir na àite chan eil bu chòir dhut dà chumha a thoirt don chriathrag leis a’ ghnìomhaiche OR, mar eisimpleir, WHERE (col! = fìor) NO (col is null).

Le boolean air obrachadh a-mach, a 'gluasad air adhart. Anns an eadar-ama, tillidh sinn an criathrag le luach boolean chun chruth tùsail aige gus beachdachadh gu neo-eisimeileach air buaidh atharrachaidhean eile.

stampa-ama? hz

San fharsaingeachd, gu tric feumaidh tu feuchainn air mar a sgrìobhas tu ceist gu ceart anns a bheil frithealaichean iomallach, agus dìreach an uairsin coimhead airson mìneachadh carson a tha seo a’ tachairt. Is e glè bheag de dh'fhiosrachadh mu dheidhinn seo a gheibhear air an eadar-lìon. Mar sin, ann an deuchainnean, lorg sinn gu bheil criathrag ceann-latha stèidhichte ag itealaich gu frithealaiche iomallach le brag, ach nuair a tha sinn airson an ceann-latha a shuidheachadh gu dinamach, mar eisimpleir, a-nis () no CURRENT_DATE, chan eil seo a’ tachairt. Anns an eisimpleir againn, tha sinn air criathrag a chuir ris gus am bi dàta anns a’ cholbh created_at airson dìreach 1 mìos san àm a dh’ fhalbh (Eadar CURRENT_DATE - INTERVAL ‘7 month’ AND CURRENT_DATE - INTERVAL '6 month'). Dè rinn sinn sa chùis seo?

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active is True
AND created_dt >= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 month') 
AND created_dt <(SELECT CURRENT_DATE::timestamptz - INTERVAL '6 month')
AND meta->>'source' = 'test';

Aggregate  (cost=306875.17..306875.18 rows=1 width=8) (actual time=4789.114..4789.115 rows=1 loops=1)
  Output: count(1)
  InitPlan 1 (returns $0)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.007..0.008 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '7 mons'::interval)
  InitPlan 2 (returns $1)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.002..0.002 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.02..306874.86 rows=105 width=0) (actual time=23.475..4681.419 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: (("table".is_active IS TRUE) AND (("table".meta ->> 'source'::text) = 'test'::text))
        Rows Removed by Filter: 76934
        Remote SQL: SELECT is_active, meta FROM fdw_schema.table WHERE ((created_dt >= $1::timestamp with time zone)) AND ((created_dt < $2::timestamp with time zone))
Planning time: 0.703 ms
Execution time: 4789.379 ms

Bhrosnaich sinn an dealbhaiche an ceann-latha obrachadh a-mach ro-làimh san fho-cheist agus an caochladair a chaidh ullachadh mar-thà a thoirt don chriathrag. Agus thug an sanas seo deagh thoradh dhuinn, dh’ fhàs a’ cheist cha mhòr 6 tursan nas luaithe!

A-rithist, tha e cudromach a bhith faiceallach an seo: feumaidh an seòrsa dàta san subquery a bhith co-ionann ris an raon leis am bi sinn a’ sìoladh, air neo bidh an dealbhaiche a’ co-dhùnadh leis gu bheil na seòrsaichean eadar-dhealaichte agus feumar an-toiseach a h-uile càil fhaighinn. dàta agus sìoladh e gu h-ionadail.

Tillidh sinn an criathrag a rèir ceann-latha chun luach tùsail aige.

Freddy vs. jsonb

San fharsaingeachd, tha raointean agus cinn-latha boolean air ar ceist a luathachadh gu leòr mar-thà, ach bha aon seòrsa dàta eile ann. Chan eil am blàr le sìoladh leis, a bhith onarach, fhathast seachad, ged a tha soirbheachaidhean an seo cuideachd. Mar sin, seo mar a chaidh againn air a dhol seachad air a’ chriathrag jsonb achadh gu frithealaiche iomallach.

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active is True
AND created_dt BETWEEN CURRENT_DATE - INTERVAL '7 month' 
AND CURRENT_DATE - INTERVAL '6 month'
AND meta @> '{"source":"test"}'::jsonb;

Aggregate  (cost=245463.60..245463.61 rows=1 width=8) (actual time=6727.589..6727.590 rows=1 loops=1)
  Output: count(1)
  ->  Foreign Scan on fdw_schema."table"  (cost=1100.00..245459.90 rows=1478 width=0) (actual time=16.213..6634.794 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Filter: (("table".is_active IS TRUE) AND ("table".created_dt >= (('now'::cstring)::date - '7 mons'::interval)) AND ("table".created_dt <= ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)))
        Rows Removed by Filter: 619961
        Remote SQL: SELECT created_dt, is_active FROM fdw_schema.table WHERE ((meta @> '{"source": "test"}'::jsonb))
Planning time: 0.747 ms
Execution time: 6727.815 ms

An àite a bhith a’ sìoladh oibrichean, feumaidh tu làthaireachd aon ghnìomhaiche a chleachdadh. jsonb ann an caochladh. 7 diogan an àite an 29 tùsail. Gu ruige seo, is e seo an aon roghainn shoirbheachail airson sìoltachain a ghluasad thairis jsonb gu frithealaiche iomallach, ach an seo tha e cudromach aire a thoirt do aon chuingealachadh: bidh sinn a’ cleachdadh dreach 9.6 den stòr-dàta, ach ro dheireadh a ’Ghiblein tha sinn an dùil na deuchainnean mu dheireadh a chrìochnachadh agus gluasad gu dreach 12. Cho luath ‘s a bheir sinn ùrachadh, sgrìobhaidh sinn mar a thug e buaidh, oir tha tòrr atharrachaidhean ann agus tha mòran dòchasan ann: json_path, giùlan CTE ùr, putadh sìos (ann bho dhreach 10). Tha mi dha-rìribh ag iarraidh feuchainn air a dh’ aithghearr.

Cuir crìoch air

Rinn sinn sgrùdadh air mar a bheir gach atharrachadh buaidh air astar na ceiste leotha fhèin. Chì sinn a-nis dè thachras nuair a thèid na trì sìoltachain a sgrìobhadh gu ceart.

explain analyze verbose
SELECT count(1)
FROM fdw_schema.table 
WHERE is_active = True
AND created_dt >= (SELECT CURRENT_DATE::timestamptz - INTERVAL '7 month') 
AND created_dt <(SELECT CURRENT_DATE::timestamptz - INTERVAL '6 month')
AND meta @> '{"source":"test"}'::jsonb;

Aggregate  (cost=322041.51..322041.52 rows=1 width=8) (actual time=2278.867..2278.867 rows=1 loops=1)
  Output: count(1)
  InitPlan 1 (returns $0)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.010..0.010 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '7 mons'::interval)
  InitPlan 2 (returns $1)
    ->  Result  (cost=0.00..0.02 rows=1 width=8) (actual time=0.003..0.003 rows=1 loops=1)
          Output: ((('now'::cstring)::date)::timestamp with time zone - '6 mons'::interval)
  ->  Foreign Scan on fdw_schema."table"  (cost=100.02..322041.41 rows=25 width=0) (actual time=8.597..2153.809 rows=1360025 loops=1)
        Output: "table".id, "table".is_active, "table".meta, "table".created_dt
        Remote SQL: SELECT NULL FROM fdw_schema.table WHERE (is_active) AND ((created_dt >= $1::timestamp with time zone)) AND ((created_dt < $2::timestamp with time zone)) AND ((meta @> '{"source": "test"}'::jsonb))
Planning time: 0.820 ms
Execution time: 2279.087 ms

Tha, tha a’ cheist a’ coimhead nas toinnte, is e prìs èiginneach a th’ ann, ach tha an astar cur gu bàs 2 dhiog, a tha còrr is 10 tursan nas luaithe! Agus tha sinn a 'bruidhinn mu dheidhinn ceist shìmplidh air seata dàta coimeasach beag. Air fìor iarrtasan, fhuair sinn àrdachadh suas ri grunn cheudan tursan.

Gus geàrr-chunntas a dhèanamh: ma tha thu a’ cleachdadh PostgreSQL le FDW, dèan cinnteach an-còmhnaidh a bheil na sìoltachain uile air an cur chun t-seirbheisiche iomallach agus bidh thu toilichte... Co-dhiù gus an tèid thu a-steach eadar bùird bho dhiofar luchd-frithealaidh. Ach sin sgeulachd airson artaigil eile.

Tapadh leibh airson an aire agad! Bu toigh leam ceistean, beachdan, agus sgeulachdan a chluinntinn mu na dh'fhiosraich thu anns na beachdan.

Source: www.habr.com

Cuir beachd ann