సెర్చ్ సర్వీస్ ఆర్కిటెక్చర్: వాల్కీతో స్టాండలోన్ ఫ్లాస్క్ అప్లికేషన్
ఈ వ్యాసం మా సెర్చ్ సర్వీస్ ఎలా ఒక ప్రత్యేక సర్వర్లో స్టాండలోన్ ఫ్లాస్క్ అప్లికేషన్గా నడుస్తుందో వివరిస్తుంది, ఇందులో వాల్కీ (రెడిస్ ఫోర్క్) అధిక-పనితీరు వెక్టర్ సెర్చ్, క్యాచింగ్ మరియు ఆటోకంప్లీట్ కోసం ఉపయోగించబడుతుంది.
సమస్య: సెర్చ్ పనితీరు మరియు స్కేలబిలిటీ
సెర్చ్ ఆపరేషన్లు గణనపరంగా ఖరీదైనవి:
-
ఫిల్టర్ ఎక్స్ట్రాక్షన్: ప్రతి ప్రశ్నకు వ్యతిరేకంగా 2,500+ పదబంధాలను సరిపోల్చండి
-
సంబంధిత శోధనలు: 65K ప్రశ్నల అంతటా సారూప్యతను లెక్కించండి
-
ఆటోకంప్లీట్: 65K ప్రశ్నలపై ప్రిఫిక్స్ మ్యాచింగ్
-
ప్రోడక్ట్ ఫిల్టరింగ్: 5K+ ఉత్పత్తులను బహుళ ప్రమాణాల ద్వారా ఫిల్టర్ చేయండి
ఈ ఆపరేషన్లను ప్రధాన వెబ్ సర్వర్లో నడపడం వలన:
-
నెమ్మదిగా పేజీ లోడ్లు: సెర్చ్ ఇతర అభ్యర్థనలను నిరోధిస్తుంది
-
మెమరీ ఒత్తిడి: ఎంబెడింగ్లు భారీ మెమరీ ఫుట్ప్రింట్కు కారణమవుతాయి
-
CPU పోటీ: సారూప్యత గణన CPU-ఇంటెన్సివ్గా ఉంటుంది
-
స్కేలింగ్ కష్టం: సెర్చ్ను స్వతంత్రంగా స్కేల్ చేయలేము
మనకు స్వతంత్రంగా స్కేల్ చేయగల ప్రత్యేక సెర్చ్ సర్వీస్ అవసరం.
పరిష్కారం: స్టాండలోన్ సెర్చ్ సర్వీస్
మేము ప్రత్యేక సర్వర్లో ఒక ప్రత్యేక ఫ్లాస్క్ అప్లికేషన్ను నడుపుతాము:
ప్రధాన వెబ్ సర్వర్
↓ HTTP API కాల్లు
సెర్చ్ సర్వీస్
↓ వాల్కీ ప్రశ్నలు
వాల్కీ సర్వర్
ఈ ఆర్కిటెక్చర్ అందిస్తుంది:
-
స్వతంత్ర స్కేలింగ్: ప్రధాన వెబ్ సర్వర్ను ప్రభావితం చేయకుండా సెర్చ్ సర్వీస్ను స్కేల్ చేయండి
-
రిసోర్స్ ఐసోలేషన్: సెర్చ్ ఆపరేషన్లు ప్రధాన వెబ్ సర్వర్పై ప్రభావం చూపవు
-
క్యాచింగ్: వాల్కీ పునరావృత ప్రశ్నల కోసం ఫలితాలను వేగంగా క్యాచ్ చేస్తుంది
-
హై అవెలబిలిటీ: ప్రధాన వెబ్ సర్వర్ను ప్రభావితం చేయకుండా సెర్చ్ సర్వీస్ రీస్టార్ట్ చేయవచ్చు
సెర్చ్ సర్వీస్ భాగాలు
1. ఫిల్టర్ ఎక్స్ట్రాక్షన్ API
-
ఎండ్పాయింట్:
/api/extract_filters -
ప్రయోజనం: సహజ భాషా ప్రశ్నల నుండి నిర్మాణాత్మక ఫిల్టర్లను వెలికితీయండి
-
ఉదాహరణ:
GET /api/extract_filters?q=mini+pc+16gb+ram
ప్రతిస్పందన:
{
"Form Factor": "Mini PC",
"Main Memory": "16"
}
అమలు:
-
పదబంధ-నుండి-ఫిల్టర్ మ్యాపింగ్లను వాల్కీ లేదా JSON నుండి లోడ్ చేయండి
-
వర్డ్ బౌండరీ రెగెక్స్ ఉపయోగించి పదబంధాలను సరిపోల్చండి
-
నిర్మాణాత్మక ఫిల్టర్లను తిరిగి ఇవ్వండి
క్యాచింగ్: పదబంధ మ్యాపింగ్లు వాల్కీలో క్యాచ్ చేయబడతాయి (30-రోజుల TTL)
2. సంబంధిత శోధనల API
-
ఎండ్పాయింట్:
/api/related -
ప్రయోజనం: వెక్టర్ సెర్చ్ ఉపయోగించి అర్థపూర్వకంగా సారూప్యమైన ప్రశ్నలను కనుగొనండి
-
ఉదాహరణ:
POST /api/related
{
"query": "mini pc",
"limit": 10
}
ప్రతిస్పందన:
{
"related": [
{"query": "small computer", "similarity": 0.92},
{"query": "compact desktop", "similarity": 0.89},
{"query": "mini pc 8gb", "similarity": 0.87}
]
}
అమలు:
-
all-mpnet-base-v2 ఉపయోగించి ప్రశ్నను ఎంబెడ్ చేయండి
-
సమీప పొరుగువారి కోసం వాల్కీ రెడిసెర్చ్ను ప్రశ్నించండి
-
సారూప్యత ప్రకారం క్రమబద్ధీకరించబడిన టాప్ N ఫలితాలను తిరిగి ఇవ్వండి
క్యాచింగ్: ఫలితాలు వాల్కీలో క్యాచ్ చేయబడతాయి (7-రోజుల TTL)
3. ఆటోకంప్లీట్ API
-
ఎండ్పాయింట్:
/api/autocomplete -
ప్రయోజనం: యూజర్ టైప్ చేస్తున్నప్పుడు ప్రశ్నలను సూచించండి
-
ఉదాహరణ:
GET /api/autocomplete?q=mini+p&limit=5
ప్రతిస్పందన:
{
"suggestions": [
"mini pc",
"mini pc 16gb",
"mini pc 8gb ram",
"mini pc fanless",
"mini pc windows 11"
]
}
అమలు:
-
ప్రిఫిక్స్ మ్యాచింగ్తో వాల్కీ రెడిసెర్చ్ను ప్రశ్నించండి
-
ప్రజాదరణ (ఇంప్రెషన్ + క్లిక్ స్కోర్) ద్వారా ర్యాంక్ చేయండి
-
టాప్ N సూచనలను తిరిగి ఇవ్వండి
క్యాచింగ్: ఆటోకంప్లీట్ ఇండెక్స్ వాల్కీలో ఉంటుంది (రోజూ నవీకరించబడుతుంది)
4. ప్రసిద్ధ ప్రశ్నల API
-
ఎండ్పాయింట్:
/api/popular -
ప్రయోజనం: చాలా ప్రసిద్ధ ప్రశ్నలను పొందండి
-
ఉదాహరణ:
GET /api/popular?limit=10
ప్రతిస్పందన:
{
"queries": [
"mini pc",
"thin client",
"industrial pc",
"all in one pc"
]
}
అమలు:
-
ప్రశ్నలను వాల్కీ లేదా JSON నుండి లోడ్ చేయండి
-
ట్రాఫిక్ స్కోర్ (ఇంప్రెషన్లు + క్లిక్లు) ప్రకారం క్రమబద్ధీకరించండి
-
టాప్ N ప్రశ్నలను తిరిగి ఇవ్వండి
క్యాచింగ్: ప్రసిద్ధ ప్రశ్నలు వాల్కీలో క్యాచ్ చేయబడతాయి (30-రోజుల TTL)
వాల్కీ ఇంటిగ్రేషన్
వాల్కీ ఒక రెడిస్ ఫోర్క్, ఇది అందిస్తుంది:
-
వెక్టర్ సెర్చ్: సారూప్యత సెర్చ్ కోసం రెడిసెర్చ్ మాడ్యూల్
-
క్యాచింగ్: ఫాస్ట్ ఇన్-మెమరీ కీ-వాల్యూ స్టోర్
-
ఆటోకంప్లీట్: సార్టెడ్ సెట్లతో ప్రిఫిక్స్ మ్యాచింగ్
-
పెర్సిస్టెన్స్: స్థిరత్వం కోసం AOF (అపెండ్-ఓన్లీ ఫైల్)
రెడిసెర్చ్తో వెక్టర్ సెర్చ్
మేము వెక్టర్ సారూప్యత సెర్చ్ కోసం వాల్కీ యొక్క రెడిసెర్చ్ మాడ్యూల్ను ఉపయోగిస్తాము:
ఇండెక్స్ క్రియేషన్:
client.ft("queries_idx").create_index([
VectorField("embedding", "FLAT", {
"TYPE": "FLOAT32",
"DIM": 768,
"DISTANCE_METRIC": "COSINE"
}),
TextField("query"),
NumericField("score")
])
వెక్టర్ సెర్చ్:
query_embedding = model.encode(query)
results = client.ft("queries_idx").search(
Query("*=>[KNN 10 @embedding $vec AS score]")
.sort_by("score")
.return_fields("query", "score")
.dialect(2),
query_params={"vec": query_embedding.tobytes()}
)
ఇది కొసైన్ సారూప్యత ద్వారా 10 సమీప పొరుగువారిని తిరిగి ఇస్తుంది.
క్యాచింగ్ వ్యూహం
మేము వాల్కీలో బహుళ డేటా రకాలను క్యాచ్ చేస్తాము:
పదబంధ మ్యాపింగ్లు (30-రోజుల TTL):
client.setex(
"seo:phrase_mappings",
30 * 24 * 3600,
json.dumps(phrase_mappings)
)
సంబంధిత శోధనలు (7-రోజుల TTL):
cache_key = f"related:{query_hash}"
client.setex(cache_key, 7 * 24 * 3600, json.dumps(results))
ప్రసిద్ధ ప్రశ్నలు (30-రోజుల TTL):
client.setex(
"seo:popular_queries",
30 * 24 * 3600,
json.dumps(popular_queries)
)
ఆటోకంప్లీట్ ఇండెక్స్ (రోజూ నవీకరించబడుతుంది):
for query, score in queries:
client.zadd("autocomplete:mini", {query: score})
సార్టెడ్ సెట్లతో ఆటోకంప్లీట్
మేము ఆటోకంప్లీట్ కోసం వాల్కీ సార్టెడ్ సెట్లను ఉపయోగిస్తాము:
ఇండెక్స్ నిర్మాణం:
autocomplete:m → ["mini pc": 5000, "mini computer": 3000]
autocomplete:mi → ["mini pc": 5000, "mini computer": 3000]
autocomplete:min → ["mini pc": 5000, "mini computer": 3000]
autocomplete:mini → ["mini pc": 5000, "mini computer": 3000]
ప్రిఫిక్స్ లుకప్:
prefix = "mini"
results = client.zrevrange(f"autocomplete:{prefix}", 0, 9, withscores=True)
ఇది "mini"తో మొదలయ్యే, స్కోర్ ప్రకారం క్రమబద్ధీకరించబడిన టాప్ 10 ప్రశ్నలను తిరిగి ఇస్తుంది.
API కమ్యూనికేషన్
ప్రధాన వెబ్ సర్వర్ HTTP ద్వారా సెర్చ్ సర్వీస్ను కాల్ చేస్తుంది:
ఫిల్టర్ ఎక్స్ట్రాక్షన్
from app.shared.filter_service import extract_filters_from_query
filters = extract_filters_from_query("mini pc 16gb ram")
# అంతర్గతంగా కాల్ చేస్తుంది: GET SEARCH_SERVICE_URL/api/extract_filters?q=...
సంబంధిత శోధనలు
import requests
response = requests.post(
"SEARCH_SERVICE_URL/api/related",
json={"query": "mini pc", "limit": 10},
timeout=2
)
related = response.json()["related"]
ఆటోకంప్లీట్
```python response = requests.get(