Historia ya chanzo chetu huria: jinsi tulivyotengeneza huduma ya uchanganuzi katika Go na kuifanya ipatikane kwa umma

Hivi sasa, karibu kila kampuni duniani hukusanya takwimu kuhusu vitendo vya mtumiaji kwenye rasilimali ya mtandao. Motisha iko wazi - makampuni yanataka kujua jinsi bidhaa/tovuti yao inatumiwa na kuwaelewa vyema watumiaji wao. Bila shaka, kuna idadi kubwa ya zana kwenye soko ili kutatua tatizo hili - kutoka kwa mifumo ya uchambuzi ambayo hutoa data kwa namna ya dashibodi na grafu (kwa mfano. Google Analytics) kwa Jukwaa la Data ya Wateja, ambalo hukuruhusu kukusanya na kujumlisha data kutoka vyanzo tofauti katika ghala lolote (kwa mfano Sehemu).

Lakini tumepata tatizo ambalo bado halijatatuliwa. Hivyo ilizaliwa EventNative - huduma ya uchanganuzi wa chanzo huria. Soma kuhusu kwa nini tuliamua kuendeleza huduma yetu wenyewe, ilitupa nini, na matokeo ya mwisho yalikuwa nini (na vipande vya msimbo).

Historia ya chanzo chetu huria: jinsi tulivyotengeneza huduma ya uchanganuzi katika Go na kuifanya ipatikane kwa umma

Kwa nini tunapaswa kukuza huduma yetu wenyewe?

Ilikuwa miaka ya tisini, tulinusurika kadri tulivyoweza. 2019, tulitengeneza API First Customer Data Platform kSense, ambayo ilifanya iwezekane kujumlisha data kutoka vyanzo tofauti (matangazo ya Facebook, Stripe, Salesforce, Google play, Google Analytics, n.k.) kwa uchanganuzi wa data rahisi zaidi, kutambua utegemezi, n.k. Tumegundua kuwa watumiaji wengi hutumia mfumo wetu kwa uchanganuzi wa data haswa Google Analytics (GA hapa baadaye). Tulizungumza na baadhi ya watumiaji na tukagundua kuwa wanahitaji data ya uchanganuzi ya bidhaa zao ambayo wanapokea kwa kutumia GA, lakini Data ya sampuli za Google na kwa wengi, kiolesura cha Mtumiaji wa GA sio kiwango cha urahisi. Tulikuwa na mazungumzo ya kutosha na watumiaji wetu na tukagundua kuwa wengi walikuwa wakitumia jukwaa la Sehemu (ambalo, kwa njia, lilikuwa siku nyingine tu. kuuzwa kwa dola bilioni 3.2).

Walisakinisha pikseli ya javascript ya Sehemu kwenye nyenzo zao za wavuti na data kuhusu tabia ya watumiaji wao ilipakiwa kwenye hifadhidata iliyobainishwa (kwa mfano Postgres). Lakini Sehemu pia ina upande wake - bei. Kwa mfano, ikiwa rasilimali ya wavuti ina MTU 90,000 (watumiaji wanaofuatiliwa kila mwezi), basi unahitaji kulipa ~ $ 1,000 kwa mwezi kwa keshia. Kulikuwa pia na tatizo la tatu - viendelezi vingine vya kivinjari (kama vile AdBlock) vilizuia mkusanyiko wa uchanganuzi kwa sababu... Maombi ya http kutoka kwa kivinjari yalitumwa kwa vikoa vya GA na Sehemu. Kulingana na matakwa ya wateja wetu, tumeunda huduma ya uchanganuzi ambayo inakusanya seti kamili ya data (bila sampuli), bila malipo na inaweza kufanya kazi kwenye miundombinu yetu wenyewe.

Jinsi huduma inavyofanya kazi

Huduma hiyo ina sehemu tatu: saizi ya javascript (ambayo baadaye tuliandika upya kwa maandishi), sehemu ya seva inatekelezwa katika lugha ya GO, na ilipangwa kutumia Redshift na BigQuery kama hifadhidata ya ndani (baadaye waliongeza usaidizi kwa Postgres, ClickHouse na Snowflake).

Iliamuliwa kuacha muundo wa matukio ya GA na Sehemu bila kubadilika. Kilichohitajika tu ni kunakili matukio yote kutoka kwa rasilimali ya wavuti ambapo pikseli imesakinishwa kwenye mazingira yetu ya nyuma. Kama inageuka, hii sio ngumu kufanya. Pikseli ya Javascript ilibatilisha mbinu ya asili ya maktaba ya GA kwa njia mpya, ambayo ilinakili tukio kwenye mfumo wetu.

//'ga' - стандартноС Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Google Analytics
if (window.ga) {
    ga(tracker => {
        var originalSendHitTask = tracker.get('sendHitTask');
        tracker.set('sendHitTask', (model) => {
            var payLoad = model.get('hitPayload');
            //ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ события Π² GA
            originalSendHitTask(model);
            let jsonPayload = this.parseQuery(payLoad);
            //ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° события Π² наш сСрвис
            this.send3p('ga', jsonPayload);
        });
    });
}

Ukiwa na saizi ya Sehemu kila kitu ni rahisi zaidi; ina njia za vifaa vya kati, moja ambayo tulitumia.


//'analytics' - стандартноС Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Segment
if (window.analytics) {
    if (window.analytics.addSourceMiddleware) {
        window.analytics.addSourceMiddleware(chain => {
            try {
		//Π΄ΡƒΠ±Π»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ события Π² наш сСрвис
                this.send3p('ajs', chain.payload);
            } catch (e) {
                LOG.warn('Failed to send an event', e)
            }
	    //ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ события Π² Segment
            chain.next(chain.payload);
        });
    } else {
        LOG.warn("Invalid interceptor state. Analytics js initialized, but not completely");
    }
} else {
    LOG.warn('Analytics.js listener is not set.');
}

Mbali na kunakili matukio, tumeongeza uwezo wa kutuma json kiholela:


//ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° событий с ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΌ json ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ
eventN.track('product_page_view', {
    product_id: '1e48fb70-ef12-4ea9-ab10-fd0b910c49ce',
    product_price: 399.99,
    price_currency: 'USD'
    product_release_start: '2020-09-25T12:38:27.763000Z'
});

Ifuatayo, wacha tuzungumze juu ya sehemu ya seva. Njia ya nyuma inapaswa kukubali ombi la http, lijaze na habari ya ziada, kwa mfano, data ya jiografia (asante maxmind kwa hili) na uirekodi kwenye hifadhidata. Tulitaka kufanya huduma iwe rahisi iwezekanavyo ili iweze kutumika kwa usanidi mdogo. Tumetekeleza utendakazi wa kubainisha taratibu za data kulingana na muundo wa tukio la json linaloingia. Aina za data zinafafanuliwa na maadili. Vitu vilivyowekwa kiota hutenganishwa na kupunguzwa kuwa muundo wa gorofa:

//входящий json
{
  "field_1":  {
    "sub_field_1": "text1",
    "sub_field_2": 100
  },
  "field_2": "text2",
  "field_3": {
    "sub_field_1": {
      "sub_sub_field_1": "2020-09-25T12:38:27.763000Z"
    }
  }
}

//Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚
{
  "field_1_sub_field_1":  "text1",
  "field_1_sub_field_2":  100,
  "field_2": "text2",
  "field_3_sub_field_1_sub_sub_field_1": "2020-09-25T12:38:27.763000Z"
}

Walakini, safu kwa sasa zinabadilishwa kuwa tungo kwa sababu Sio hifadhidata zote za uhusiano zinazotumia sehemu zinazorudiwa. Inawezekana pia kubadilisha majina ya sehemu au kuyafuta kwa kutumia sheria za hiari za kupanga ramani. Wanakuruhusu kubadilisha schema ya data ikiwa ni lazima au kubadilisha aina moja ya data hadi nyingine. Kwa mfano, ikiwa uwanja wa json una kamba iliyo na muhuri wa wakati (sehemu_3_sehemu_ndogo_1_sehemu_ndogo_1 kutoka kwa mfano hapo juu), basi ili kuunda uwanja katika hifadhidata na aina ya muhuri wa wakati, unahitaji kuandika sheria ya ramani katika usanidi. Kwa maneno mengine, aina ya data ya shamba imedhamiriwa kwanza na thamani ya json, na kisha kanuni ya aina ya utupaji (ikiwa imesanidiwa) inatumika. Tumetambua aina 4 kuu za data: STRING, FLOAT64, INT64 na TIMESTAMP. Sheria za uchoraji wa ramani na aina zinaonekana kama hii:

rules:
  - "/field_1/subfield_1 -> " #ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ удалСния поля
  - "/field_2/subfield_1 -> /field_10/subfield_1" #ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ пСрСноса поля
  - "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ пСрСноса поля ΠΈ привСдСния Ρ‚ΠΈΠΏΠ°

Algorithm ya kuamua aina ya data:

  • badilisha muundo wa json kuwa muundo wa gorofa
  • kuamua aina ya data ya sehemu kwa maadili
  • kutumia sheria za uchoraji ramani na chapa

Kisha kutoka kwa muundo unaoingia wa json:

{
    "product_id":  "1e48fb70-ef12-4ea9-ab10-fd0b910c49ce",
    "product_price": 399.99,
    "price_currency": "USD",
    "product_type": "supplies",
    "product_release_start": "2020-09-25T12:38:27.763000Z",
    "images": {
      "main": "picture1",
      "sub":  "picture2"
    }
}

schema ya data itapatikana:

"product_id" character varying,
"product_price" numeric (38,18),
"price_currency" character varying,
"product_type" character varying,
"product_release_start" timestamp,
"images_main" character varying,
"images_sub" character varying

Pia tulifikiri kuwa mtumiaji anafaa kuwa na uwezo wa kusanidi ugawaji au kugawanya data katika hifadhidata kulingana na vigezo vingine na kutekeleza uwezo wa kuweka jina la jedwali kwa njia isiyobadilika au isiyobadilika. kujieleza katika usanidi. Katika mfano ulio hapa chini, tukio litahifadhiwa kwenye jedwali lenye jina lililokokotwa kulingana na thamani za bidhaa_aina na sehemu _muhuri wa saa (kwa mfano. vifaa_2020_10):

tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'

Hata hivyo, muundo wa matukio yanayoingia unaweza kubadilika wakati wa utekelezaji. Tumetekeleza algoriti ili kuangalia tofauti kati ya muundo wa jedwali lililopo na muundo wa tukio linaloingia. Ikiwa tofauti inapatikana, jedwali litasasishwa na sehemu mpya. Ili kufanya hivyo, tumia swala la kiraka la SQL:

#ΠŸΡ€ΠΈΠΌΠ΅Ρ€ для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying

usanifu

Historia ya chanzo chetu huria: jinsi tulivyotengeneza huduma ya uchanganuzi katika Go na kuifanya ipatikane kwa umma

Kwa nini unahitaji kuandika matukio kwenye mfumo wa faili, na si tu kuandika moja kwa moja kwenye hifadhidata? Hifadhidata haifanyi vizuri kila wakati wakati wa kushughulika na idadi kubwa ya viingilio (Mapendekezo ya Postgres) Ili kufanya hivyo, Logger anaandika matukio yanayoingia kwenye faili na katika goroutine tofauti (thread) Msomaji wa faili anasoma faili, kisha data inabadilishwa na kuamua. Baada ya msimamizi wa Jedwali kuhakikisha kuwa schema ya jedwali ni ya kisasa, data itaandikwa kwenye hifadhidata katika kundi moja. Baadaye, tuliongeza uwezo wa kuandika data moja kwa moja kwenye hifadhidata, lakini tunatumia hali hii kwa matukio ambayo sio mengi - kwa mfano, ubadilishaji.

Chanzo Huria na mipango ya siku zijazo

Wakati fulani, huduma ilianza kuonekana kama bidhaa kamili na tuliamua kuifungua kwa Open Source. Hivi sasa, ushirikiano na Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake imetekelezwa. Miunganisho yote inasaidia njia za bechi na za utiririshaji za upakiaji wa data. Usaidizi ulioongezwa kwa maombi kupitia API.

Mpango wa sasa wa ujumuishaji unaonekana kama hii:

Historia ya chanzo chetu huria: jinsi tulivyotengeneza huduma ya uchanganuzi katika Go na kuifanya ipatikane kwa umma

Ingawa huduma inaweza kutumika kwa kujitegemea (kwa mfano kutumia Docker), tunayo pia toleo la mwenyeji, ambamo unaweza kusanidi ujumuishaji na ghala la data, ongeza CNAME kwenye kikoa chako na uangalie takwimu za idadi ya matukio. Mipango yetu ya haraka ni kuongeza uwezo wa kujumlisha sio tu takwimu kutoka kwa rasilimali ya wavuti, lakini pia data kutoka kwa vyanzo vya data vya nje na kuzihifadhi kwenye hifadhi yoyote unayopenda!

β†’ GitHub
β†’ Nyaraka
β†’ Slack

Tutafurahi ikiwa EventNative itasaidia kutatua matatizo yako!

Watumiaji waliojiandikisha pekee ndio wanaweza kushiriki katika utafiti. Weka sahihitafadhali.

Je, ni mfumo gani wa kukusanya takwimu unatumika katika kampuni yako?

  • 48,0%Google Analytics12

  • 4,0%Sehemu ya 1

  • 16,0%Mwingine (andika kwenye maoni)4

  • 32,0%Umetekeleza huduma yako8

Watumiaji 25 walipiga kura. Watumiaji 6 walijizuia.

Chanzo: mapenzi.com

Kuongeza maoni