Açıq mənbəmizin tarixi: Go-da necə analitik xidmət yaratdıq və onu ictimaiyyətə təqdim etdik

Hazırda dünyada demək olar ki, hər bir şirkət veb resursda istifadəçi hərəkətləri haqqında statistik məlumat toplayır. Motivasiya aydındır - şirkətlər məhsullarının/veb-saytlarının necə istifadə olunduğunu bilmək və istifadəçilərini daha yaxşı başa düşmək istəyirlər. Əlbəttə ki, bazarda bu problemi həll etmək üçün çoxlu sayda alətlər var - tablolar və qrafiklər şəklində məlumatları təmin edən analitik sistemlərdən (məsələn, Google Analytics) istənilən anbarda müxtəlif mənbələrdən məlumatları toplamaq və toplamaq imkanı verən Müştəri Məlumat Platformasına (məsələn, Seqment).

Ancaq hələ də həllini tapmayan bir problem tapdıq. Beləcə doğuldu EventNative — açıq mənbəli analitik xidmət. Öz xidmətimizi niyə inkişaf etdirmək qərarına gəldiyimizi, bizə nə verdiyini və son nəticənin nə olduğunu (kod parçaları ilə) oxuyun.

Açıq mənbəmizin tarixi: Go-da necə analitik xidmət yaratdıq və onu ictimaiyyətə təqdim etdik

Niyə biz öz xidmətimizi inkişaf etdirməliyik?

2019-cı illər idi, bacardıqca sağ qaldıq. XNUMX, biz API İlk Müştəri Məlumat Platformasını inkişaf etdirdik kSense, bu, müxtəlif mənbələrdən (Facebook reklamları, Stripe, Salesforce, Google play, Google Analytics və s.) məlumatların daha rahat təhlili, asılılıqların müəyyən edilməsi və s. Bir çox istifadəçinin məlumatların təhlili üçün platformamızdan xüsusilə Google Analytics (bundan sonra GA) istifadə etdiyini müşahidə etdik. Bəzi istifadəçilərlə danışdıq və öyrəndik ki, onlar GA istifadə edərək aldıqları məhsul üçün analitik məlumatlara ehtiyac duyurlar, lakin Google məlumatları nümunələri və çoxları üçün GA İstifadəçi interfeysi rahatlıq standartı deyil. İstifadəçilərimizlə kifayət qədər söhbət etdik və başa düşdük ki, bir çoxları Seqment platformasından da istifadə edir (yeri gəlmişkən, bu ötən gün idi) 3.2 milyard dollara satılıb).

Onlar veb resursunda Seqment javascript pikselini quraşdırdılar və istifadəçilərinin davranışı haqqında məlumatlar müəyyən edilmiş verilənlər bazasına (məsələn, Postgres) yükləndi. Lakin Seqmentin mənfi tərəfi də var - qiymət. Məsələn, bir veb resursda 90,000 MTU (aylıq izlənən istifadəçilər) varsa, o zaman kassirə ayda ~ 1,000 dollar ödəməlisiniz. Üçüncü problem də var idi - bəzi brauzer genişləndirmələri (məsələn, AdBlock) analitiklərin toplanmasına mane oldu, çünki... Brauzerdən http sorğuları GA və Seqment domenlərinə göndərildi. Müştərilərimizin istəklərinə əsasən, biz tam məlumat toplusunu (nümunə götürmədən) toplayan, pulsuz olan və öz infrastrukturumuzda işləyə bilən analitik xidmət yaratdıq.

Xidmət necə işləyir

Xidmət üç hissədən ibarətdir: javascript pikseli (biz onu sonradan şriftlə yenidən yazdıq), server hissəsi GO dilində həyata keçirilir və daxili verilənlər bazası kimi Redshift və BigQuery-dən istifadə edilməsi planlaşdırılırdı (sonralar onlar üçün dəstək əlavə etdilər. Postgres, ClickHouse və Snowflake).

GA və Seqment hadisələrinin strukturunun dəyişməz qalması qərara alınıb. Lazım olan tək şey, pikselin quraşdırıldığı veb resursdakı bütün hadisələri backendimizə təkrarlamaq idi. Göründüyü kimi, bunu etmək çətin deyil. Javascript pikseli orijinal GA kitabxana metodunu yenisi ilə ləğv etdi, bu da sistemimizdəki hadisəni təkrarladı.

//'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);
        });
    });
}

Seqment pikseli ilə hər şey daha sadədir, ara proqram metodlarına malikdir, onlardan birini istifadə edirik.


//'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.');
}

Hadisələri kopyalamaqdan əlavə, biz ixtiyari json göndərmək imkanı əlavə etdik:


//Отправка событий с произвольным 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'
});

Sonra server hissəsi haqqında danışaq. Backend http sorğularını qəbul etməli, onları əlavə məlumatla doldurmalıdır, məsələn, geo data (təşəkkürlər maksimum ağıl bunun üçün) və məlumat bazasına qeyd edin. Biz xidməti mümkün qədər rahat etmək istədik ki, minimal konfiqurasiya ilə istifadə olunsun. Biz daxil olan json hadisəsinin strukturuna əsaslanaraq məlumat sxeminin müəyyən edilməsi funksiyasını həyata keçirmişik. Məlumat növləri dəyərlərlə müəyyən edilir. Yuvalanmış obyektlər parçalanır və düz bir quruluşa çevrilir:

//входящий 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"
}

Bununla belə, massivlər hazırda sadəcə olaraq sətirlərə çevrilir, çünki Bütün əlaqəli verilənlər bazaları təkrarlanan sahələri dəstəkləmir. Sahə adlarını dəyişdirmək və ya əlavə xəritəçəkmə qaydalarından istifadə edərək silmək də mümkündür. Onlar sizə lazım olduqda məlumat sxemini dəyişməyə və ya bir məlumat növünü digərinə çevirməyə imkan verir. Məsələn, json sahəsində zaman damğası olan sətir (sahə_3_alt_sahə_1_alt_alt_sahə_1 yuxarıdakı nümunədən), sonra verilənlər bazasında vaxt damğası növü ilə bir sahə yaratmaq üçün konfiqurasiyada xəritəçəkmə qaydası yazmalısınız. Başqa sözlə, sahənin məlumat tipi ilk olaraq json dəyəri ilə müəyyən edilir, sonra isə tip tökmə qaydası (konfiqurasiya olunubsa) tətbiq edilir. Biz 4 əsas məlumat növünü müəyyən etdik: STRING, FLOAT64, INT64 və TIMESTAMP. Xəritəçəkmə və tip tökmə qaydaları belə görünür:

rules:
  - "/field_1/subfield_1 -> " #правило удаления поля
  - "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
  - "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа

Verilənlərin növünü təyin etmək üçün alqoritm:

  • json strukturunu düz quruluşa çevirin
  • dəyərlərlə sahələrin məlumat növünün müəyyən edilməsi
  • Xəritəçəkmə və tip tökmə qaydalarının tətbiqi

Sonra gələn json strukturundan:

{
    "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"
    }
}

məlumat sxemi əldə ediləcək:

"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

Biz həmçinin hesab etdik ki, istifadəçi digər meyarlara uyğun olaraq verilənlər bazasında məlumatların bölmələrini və ya bölmələrini konfiqurasiya edə bilməlidir və cədvəlin adını sabit və ya ifadə konfiqurasiyada. Aşağıdakı nümunədə hadisə məhsul_növü və _zaman damgası sahələrinin dəyərlərinə əsasən hesablanmış adla cədvəldə saxlanılacaq (məsələn, təchizat_2020_10):

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

Bununla belə, daxil olan hadisələrin strukturu icra zamanı dəyişə bilər. Mövcud cədvəlin strukturu ilə daxil olan hadisənin strukturu arasındakı fərqi yoxlamaq üçün alqoritm tətbiq etdik. Fərq aşkar edilərsə, cədvəl yeni sahələrlə yenilənəcək. Bunu etmək üçün patch SQL sorğusundan istifadə edin:

#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying

memarlıq

Açıq mənbəmizin tarixi: Go-da necə analitik xidmət yaratdıq və onu ictimaiyyətə təqdim etdik

Nə üçün hadisələri birbaşa verilənlər bazasına yazmaq yox, fayl sisteminə yazmaq lazımdır? Verilənlər bazaları çoxlu sayda əlavələrlə işləyərkən həmişə yaxşı işləmir (Postgres tövsiyələri). Bunun üçün Logger daxil olan hadisələri fayla yazır və ayrıca goroutine (mövzu) Fayl oxuyucusu faylı oxuyur, sonra məlumatlar çevrilir və müəyyən edilir. Cədvəl meneceri cədvəlin sxeminin aktual olduğundan əmin olduqdan sonra verilənlər bazaya bir partiyada yazılacaq. Sonradan biz verilənlər bazasına birbaşa məlumat yazmaq imkanı əlavə etdik, lakin biz bu rejimi çox olmayan hadisələr üçün istifadə edirik - məsələn, dönüşümlər.

Açıq Mənbə və gələcək üçün planlar

Bir anda xidmət tam hüquqlu bir məhsul kimi görünməyə başladı və biz onu Open Source-a buraxmaq qərarına gəldik. Hazırda Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake ilə inteqrasiyalar həyata keçirilib. Bütün inteqrasiyalar verilənlərin yüklənməsinin həm toplu, həm də axın rejimlərini dəstəkləyir. API vasitəsilə sorğular üçün əlavə dəstək.

Mövcud inteqrasiya sxemi belə görünür:

Açıq mənbəmizin tarixi: Go-da necə analitik xidmət yaratdıq və onu ictimaiyyətə təqdim etdik

Baxmayaraq ki, xidmət müstəqil olaraq istifadə edilə bilər (məsələn, Docker istifadə edərək), bizdə də var host versiyası, burada məlumat anbarı ilə inteqrasiya qura, domeninizə CNAME əlavə edə və hadisələrin sayına dair statistikaya baxa bilərsiniz. Bizim yaxın planlarımız təkcə veb-resursdan olan statistik məlumatları deyil, həm də xarici məlumat mənbələrindən məlumatları toplamaq və onları seçdiyiniz istənilən yaddaşa saxlamaq imkanı əlavə etməkdir!

→ Github
→ Documentation
→ Süstlük

EventNative problemlərinizi həll etməyə kömək etsə, şad olarıq!

Sorğuda yalnız qeydiyyatdan keçmiş istifadəçilər iştirak edə bilər. Daxil olunxahiş edirəm.

Şirkətinizdə hansı statistika toplama sistemindən istifadə olunur?

  • 48,0%Google Analytics12

  • 4,0%Seqment 1

  • 16,0%Digəri (şərhlərdə yazın)4

  • 32,0%Xidmətinizi həyata keçirdiniz8

25 istifadəçi səs verib. 6 istifadəçi bitərəf qalıb.

Mənbə: www.habr.com

Добавить комментарий