ปัจจุบัน เกือบทุกบริษัทในโลกรวบรวมสถิติเกี่ยวกับการกระทำของผู้ใช้บนทรัพยากรบนเว็บ แรงจูงใจนั้นชัดเจน บริษัทต่างๆ ต้องการทราบว่าผลิตภัณฑ์/เว็บไซต์ของตนถูกนำไปใช้อย่างไร และเข้าใจผู้ใช้ได้ดีขึ้น แน่นอนว่ามีเครื่องมือมากมายในตลาดที่จะแก้ไขปัญหานี้ - จากระบบการวิเคราะห์ที่ให้ข้อมูลในรูปแบบของแดชบอร์ดและกราฟ (เช่น
แต่เราพบปัญหาที่ยังไม่ได้รับการแก้ไข เกิดมาเลย
ทำไมเราจึงต้องพัฒนาบริการของเราเอง?
มันเป็นยุคเก้าสิบ เราเอาตัวรอดอย่างดีที่สุดเท่าที่จะทำได้ ในปี 2019 เราได้พัฒนา API แพลตฟอร์มข้อมูลลูกค้ารายแรก เคเซนส์ซึ่งอนุญาตให้รวบรวมข้อมูลจากแหล่งต่างๆ (โฆษณา Facebook, Stripe, Salesforce, Google play, Google Analytics ฯลฯ) เพื่อการวิเคราะห์ข้อมูลที่สะดวกยิ่งขึ้น การระบุการขึ้นต่อกัน ฯลฯ เราสังเกตเห็นว่าผู้ใช้จำนวนมากใช้แพลตฟอร์มการวิเคราะห์ข้อมูลของเรา โดยเฉพาะ Google Analytics (ต่อไปนี้จะเรียกว่า GA) เราได้พูดคุยกับผู้ใช้บางคนและพบว่าพวกเขาต้องการข้อมูลการวิเคราะห์ผลิตภัณฑ์ซึ่งพวกเขาได้รับโดยใช้ GA แต่
พวกเขาติดตั้งพิกเซลจาวาสคริปต์ของเซ็กเมนต์บนทรัพยากรบนเว็บ และข้อมูลพฤติกรรมผู้ใช้ถูกโหลดลงในฐานข้อมูลที่ระบุ (เช่น Postgres) แต่เซ็กเมนต์ก็มีราคาลบด้วย ตัวอย่างเช่น หากทรัพยากรบนเว็บมี 90,000 MTU (ผู้ใช้ที่ติดตามรายเดือน) คุณจะต้องจ่ายเงิน ~ $ 1,000 ต่อเดือนให้กับแคชเชียร์ นอกจากนี้ยังมีปัญหาที่สาม - ส่วนขยายเบราว์เซอร์บางตัว (เช่น AdBlock) บล็อกการรวบรวมการวิเคราะห์ คำขอ http จากเบราว์เซอร์ถูกส่งไปยังโดเมน GA และ Segment ตามความต้องการของลูกค้าของเรา เราได้สร้างบริการการวิเคราะห์ที่รวบรวมข้อมูลชุดเต็ม (โดยไม่ต้องสุ่มตัวอย่าง) โดยไม่เสียค่าใช้จ่ายและสามารถทำงานบนโครงสร้างพื้นฐานของเราเองได้
บริการทำงานอย่างไร
บริการประกอบด้วยสามส่วน: พิกเซลจาวาสคริปต์ (ซึ่งต่อมาเราเขียนใหม่เป็น typescript) ส่วนเซิร์ฟเวอร์ที่ใช้งานในภาษา GO และมีการวางแผนที่จะใช้ Redshift และ BigQuery เป็นฐานข้อมูลภายใน (ต่อมาได้เพิ่มการรองรับสำหรับ Postgres , ClickHouse และ Snowflake)
โครงสร้างของเหตุการณ์ GA และ Segment ตัดสินใจที่จะไม่เปลี่ยนแปลง สิ่งเดียวที่จำเป็นคือการทำซ้ำกิจกรรมทั้งหมดจากแหล่งข้อมูลบนเว็บที่ติดตั้งพิกเซลไว้ที่แบ็กเอนด์ของเรา ปรากฎว่านี่เป็นเรื่องง่ายที่จะทำ พิกเซล Javascript แทนที่วิธีไลบรารี GA ดั้งเดิมด้วยวิธีใหม่ที่ทำซ้ำเหตุการณ์ในระบบของเรา
//'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);
});
});
}
ด้วยพิกเซลของเซ็กเมนต์ ทุกอย่างจะง่ายขึ้น มีวิธีมิดเดิลแวร์ และเราใช้วิธีใดวิธีหนึ่ง
//'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.');
}
นอกเหนือจากการคัดลอกกิจกรรมแล้ว เรายังเพิ่มความสามารถในการส่ง json ตามอำเภอใจอีกด้วย:
//Отправка событий с произвольным 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'
});
ต่อไป เรามาพูดถึงฝั่งเซิร์ฟเวอร์กันดีกว่า แบ็กเอนด์ควรยอมรับคำขอ http โดยกรอกข้อมูลเพิ่มเติม เช่น ข้อมูลภูมิศาสตร์ (ขอบคุณ
//входящий 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"
}
อย่างไรก็ตาม ปัจจุบันอาร์เรย์ถูกแปลงเป็นสตริงเพียงอย่างเดียว ฐานข้อมูลเชิงสัมพันธ์บางฐานข้อมูลไม่รองรับฟิลด์ที่ซ้ำกัน นอกจากนี้ยังสามารถเปลี่ยนชื่อฟิลด์หรือลบออกได้โดยใช้กฎการแมปที่เป็นทางเลือก ช่วยให้คุณสามารถเปลี่ยนสคีมาข้อมูลได้ หากจำเป็น หรือแปลงข้อมูลประเภทหนึ่งไปยังอีกประเภทหนึ่ง ตัวอย่างเช่น หากฟิลด์ json มีสตริงที่มีการประทับเวลา (field_3_sub_field_1_sub_sub_field_1 จากตัวอย่างด้านบน) จากนั้น เพื่อสร้างฟิลด์ในฐานข้อมูลด้วยประเภทการประทับเวลา คุณจะต้องเขียนกฎการแมปในการกำหนดค่า กล่าวอีกนัยหนึ่ง ประเภทข้อมูลของฟิลด์จะถูกกำหนดโดยค่า json ก่อน จากนั้นจึงใช้กฎการคัดเลือกประเภท (หากกำหนดค่าไว้) เราได้ระบุประเภทข้อมูลหลัก 4 ประเภท: STRING, FLOAT64, INT64 และ TIMESTAMP กฎการแมปและการแคสต์มีลักษณะดังนี้:
rules:
- "/field_1/subfield_1 -> " #правило удаления поля
- "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа
อัลกอริทึมในการกำหนดประเภทข้อมูล:
- แปลงโครงสร้าง json เป็นโครงสร้างแบบเรียบ
- การกำหนดประเภทข้อมูลของฟิลด์ด้วยค่า
- การใช้กฎการแมปและประเภทการคัดเลือก
จากนั้นจากโครงสร้าง 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"
}
}
จะได้รับสคีมาข้อมูล:
"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
นอกจากนี้เรายังคิดว่าผู้ใช้ควรจะสามารถตั้งค่าการแบ่งพาร์ติชันหรือแยกข้อมูลในฐานข้อมูลตามเกณฑ์อื่น ๆ และใช้ความสามารถในการตั้งชื่อตารางเป็นค่าคงที่หรือ
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
อย่างไรก็ตาม โครงสร้างของเหตุการณ์ขาเข้าสามารถเปลี่ยนแปลงได้ในขณะรันไทม์ เราได้ใช้อัลกอริทึมสำหรับตรวจสอบความแตกต่างระหว่างโครงสร้างของตารางที่มีอยู่และโครงสร้างของเหตุการณ์ที่เข้ามา หากพบความแตกต่าง ตารางจะได้รับการอัปเดตด้วยฟิลด์ใหม่ เมื่อต้องการทำเช่นนี้ ให้ใช้แบบสอบถาม SQL โปรแกรมแก้ไข:
#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
สถาปัตยกรรม
เหตุใดคุณจึงต้องเขียนเหตุการณ์ลงในระบบไฟล์ และไม่ใช่แค่เขียนลงในฐานข้อมูลโดยตรง ฐานข้อมูลไม่ได้แสดงประสิทธิภาพสูงเสมอไปเมื่อมีการแทรกจำนวนมาก (
โอเพ่นซอร์สและแผนการในอนาคต
เมื่อถึงจุดหนึ่ง บริการนี้เริ่มดูเหมือนเป็นผลิตภัณฑ์ที่มีคุณสมบัติครบถ้วน และเราตัดสินใจที่จะเผยแพร่สู่ Open Source ปัจจุบันมีการผสานรวมกับ Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake การบูรณาการทั้งหมดรองรับการโหลดข้อมูลทั้งแบบแบตช์และแบบสตรีมมิ่ง เพิ่มการรองรับคำขอผ่าน API
รูปแบบการรวมปัจจุบันมีลักษณะดังนี้:
แม้ว่าจะสามารถใช้บริการได้อย่างอิสระ (เช่น การใช้ Docker) เราก็มีเช่นกัน
เรายินดีเป็นอย่างยิ่งหาก EventNative จะช่วยคุณแก้ไขปัญหาของคุณ!
เฉพาะผู้ใช้ที่ลงทะเบียนเท่านั้นที่สามารถเข้าร่วมในการสำรวจได้
บริษัทของคุณใช้ระบบการเก็บสถิติใด
-
ลด 48,0%Google Analytics12
-
ลด 4,0%ส่วนที่ 1
-
ลด 16,0%อื่นๆ (เขียนในความคิดเห็น) 4
-
ลด 32,0%ดำเนินการบริการของคุณ8
ผู้ใช้ 25 คนโหวต ผู้ใช้ 6 รายงดออกเสียง
ที่มา: will.com