Pricerunner Tech Talk: Sök med Elasticsearch och serverrenderad React

By Kristofer Palmvik ·

Referat från Pricerunners meetup “Pricerunner Tech talks” 10 oktober 2018 som jag besökte, skrivet för mina kollegor som inte var där.

Det är alltid intressant att ta reda på hur andra företag löser ungefär samma problem.

Ikväll hälsade jag på hos Pricerunner, som hade "Tech talks", med fyra presentationer om Nomad (klusterhantering och schemaläggning), Prometheus (metrics), Elastic (sökmotor) och React (komponentbaserad serverrendering av webbappar).

För den som inte känner till är Pricerunner en prisjämförelsesajt som var vanlig att använda innan Prisjakt dök upp. Sedan såldes sajten till amerikanska investerare som lade ut utvecklingen till ett kinesiskt bolag vilket, för att citera nuvarande VD:n, byggde en "skitprodukt". Sedan två år har nya ägare tagit över bolaget och flyttat all utveckling till Stockholm för att komma närmare användare och bygga en helt ny produkt som kan ta över prisjämförelsemarknaden igen.

För knappt två år sedan började de alltså från noll med att bygga plattformen från grunden och att gradvis ersätta den befintliga men undermåliga produkten. Nu börjar funktionaliteten matcha vad som fanns tidigare, men med den skillnaden att plattformen kan skalas och byggas vidare mycket enklare.

Teknikstacken är, lite luddigt beskriven, Java med Spring som backend i en tjänstearkitektur med ett 20‑tal olika tjänster, JSON‑REST API:er för varje tjänst och ett gemensamt parallelliserat "Edge" JSON‑API vilket används av frontend, vilket i sin tur utgörs av serverrenderad React med Redux.

Nästan hela systemet körs på egna servrar i Bahnhofs datahall, primärt av prisskäl då de använder stora mängder RAM och det blir för dyrt med en molntjänst. Tredjepartstjänsten Gigaspaces används för att lagra data, och något CDN för att leverera bilder etc. I bakgrunden används Nomad för att schemalägga processer (i dagsläget 30 nomad workers/clients, 180 CPUs, 600 GB RAM, 236 aktiva jobb) och Consul för service discovery.

Det märktes att hela företaget har ett stort teknikfokus just nu, med en mycket tydlig teknisk vision från CTO och utvecklingschefer att bygga upp en långsiktigt hållbar och modern plattform. Ett starkt varumärke finns redan, och genom att bygga en snabb och lättanvänd tjänst planerar de att locka tillbaka massorna av användare.

Totalt jobbar drygt 110 personer på Pricerunner. Av dessa är 23 backend‑utvecklare och 18 frontend‑utvecklare, indelade i 5 team som jag tror var Sök (sökupplevelsen), Produktpresentation (produktsidor etc), Matchning (inflöde av priser/produkter), User (inloggade användareI och Traffic (intrafik/SEO/prestanda). Utöver dessa finns ett "sysadmin/devops"‑team som driftar och bygger interna verktyg.

Sajten har runt 300 000 unika besökare per dag. De var glada för den stora trafiken vid A/B‑testning och att de exv kunde få 30 000 användare från 10 % av trafiken.

Varje team består enbart av frontend + backend + produktägare, inga testare, designers, UX eller liknande om jag förstod rätt. De var väldigt tydliga med att det var en tydlig uppdelning mellan backend och frontend, främst eftersom frontendutvecklingen med React och Redux var så specialiserad att det i princip var omöjligt att vara bra på något annat samtidigt.

Sök med Elasticsearch

För sökmotorn skiljer de mellan instant search och enter‑sök, där det första är vad som visas när användaren skriver in i sökrutan och det senare är vad som visas efter enter‑tryck.

Ett ElasticSearch‑kluster med 10 noder och 20 primary shards (med 1 replika av varje). Total indexerad mängd är 1,8 miljoner strukturerade produkter med mycket data, och runt 80 miljoner ostrukturerade produkter som i princip bara är namn och pris. Deras största utmaning är att indexera snabbt samt att returnera vettigt rankade resultat snabbt nog.

Källan för indexeringen är Gigaspaces med en Kafka‑ström som via en "Search ingester" föder ElasticSearch med reaktiva Akka‑strömmar.

Det mest intressanta här (utöver deras exakta tekniska setup) var kanske att deras Sök‑team fokuserar extremt mycket på hela flödet: från indexeringen till presentationen.

Serverrenderad React

Pricerunner använder React, men av prestandaskäl och i förlängningen SEO‑skäl har de konstaterat att det inte räcker med att enbart ha en klient‑app. Det krävs att alla sidor serverrenderas, vilket de löser genom en klassisk synkron datahämtning med engångs‑rendering och databehovet specificerat per route.

En alternativ lösning skulle vara att låta varje komponent begära data asynkront och då vara tvungen att rendera om DOM‑trädet (åtminstone) två gånger. Det har fördelar, som den uppenbara att parallell datahämtning är möjlig, men också ett antal nackdelar, exempelvis mer komplex tillståndshantering, att överföringen av tillståndet måste hanteras utanför React och en allmänt hackig lösning.

Framtiden som de såg fram emot mycket var React Suspense, vilket den senaste React 16 bäddar för, med möjlighet att nå fördelarna med båda dessa alternativ samtidigt. Facebook kommer enligt presentationen att börja använda serverrendering själva, vilket framöver borde leda till kraftigt ökade investeringar i teknik och infrastruktur för att göra detta enklare.