మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

ప్రామాణిక వంటకాలను ఎలా ఉపయోగించాలో ఇటీవల నేను మీకు చెప్పాను SQL రీడ్ క్వెరీల పనితీరును పెంచండి PostgreSQL డేటాబేస్ నుండి. ఈ రోజు మనం ఎలా మాట్లాడతాము రికార్డింగ్ మరింత సమర్థవంతంగా చేయవచ్చు కాన్ఫిగరేషన్‌లో ఎటువంటి “ట్విస్ట్‌లు” ఉపయోగించకుండా డేటాబేస్‌లో - డేటా ప్రవాహాలను సరిగ్గా నిర్వహించడం ద్వారా.

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

#1. విభజన

ఎలా మరియు ఎందుకు నిర్వహించడం విలువైనది అనే దాని గురించి ఒక కథనం అనువర్తిత విభజన "సిద్ధాంతంలో" ఇప్పటికే ఉంది, ఇక్కడ మేము మా లోపల కొన్ని విధానాలను వర్తించే అభ్యాసం గురించి మాట్లాడుతాము వందలాది PostgreSQL సర్వర్‌ల కోసం పర్యవేక్షణ సేవ.

"రోజుల సంగతులు..."

ప్రారంభంలో, ఏదైనా MVP లాగా, మా ప్రాజెక్ట్ చాలా తక్కువ లోడ్‌లో ప్రారంభమైంది - పర్యవేక్షణ పది అత్యంత క్లిష్టమైన సర్వర్‌ల కోసం మాత్రమే నిర్వహించబడింది, అన్ని టేబుల్‌లు సాపేక్షంగా కాంపాక్ట్‌గా ఉన్నాయి... కానీ సమయం గడిచేకొద్దీ, పర్యవేక్షించబడే హోస్ట్‌ల సంఖ్య మరింత పెరిగింది. , మరియు మరోసారి మేము ఒకదానితో ఏదైనా చేయడానికి ప్రయత్నించాము పట్టికలు 1.5TB పరిమాణంలో ఉన్నాయి, ఇలాగే జీవించడం సాధ్యమే అయినప్పటికీ, అది చాలా అసౌకర్యంగా ఉందని మేము గ్రహించాము.

సమయాలు దాదాపు పురాణ సమయాల మాదిరిగానే ఉన్నాయి, PostgreSQL 9.x యొక్క విభిన్న సంస్కరణలు సంబంధితంగా ఉన్నాయి, కాబట్టి అన్ని విభజనలు "మాన్యువల్‌గా" చేయాలి - ద్వారా పట్టిక వారసత్వం మరియు ట్రిగ్గర్స్ డైనమిక్‌తో రూటింగ్ EXECUTE.

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB
ఫలిత పరిష్కారం అన్ని పట్టికలకు అనువదించబడేంత సార్వత్రికమైనదిగా మారింది:

  • ఖాళీ "హెడర్" పేరెంట్ టేబుల్ ప్రకటించబడింది, ఇది అన్నింటినీ వివరించింది అవసరమైన సూచికలు మరియు ట్రిగ్గర్లు.
  • క్లయింట్ యొక్క దృక్కోణం నుండి రికార్డు "రూట్" పట్టికలో తయారు చేయబడింది మరియు అంతర్గతంగా ఉపయోగించబడింది రూటింగ్ ట్రిగ్గర్ BEFORE INSERT రికార్డు "భౌతికంగా" అవసరమైన విభాగంలోకి చొప్పించబడింది. ఇంకా అలాంటిదేమీ లేకుంటే, మేము మినహాయింపు పొందాము మరియు...
  • … ఉపయోగించడం ద్వార CREATE TABLE ... (LIKE ... INCLUDING ...) మాతృ పట్టిక యొక్క టెంప్లేట్ ఆధారంగా సృష్టించబడింది కోరుకున్న తేదీపై పరిమితి ఉన్న విభాగంతద్వారా డేటాను తిరిగి పొందినప్పుడు, దానిలో మాత్రమే చదవడం జరుగుతుంది.

PG10: మొదటి ప్రయత్నం

కానీ వారసత్వం ద్వారా విభజన చేయడం అనేది యాక్టివ్ రైట్ స్ట్రీమ్ లేదా పెద్ద సంఖ్యలో చైల్డ్ విభజనలతో వ్యవహరించడానికి చారిత్రాత్మకంగా సరిగ్గా సరిపోదు. ఉదాహరణకు, అవసరమైన విభాగాన్ని ఎంచుకోవడానికి అల్గోరిథం ఉందని మీరు గుర్తు చేసుకోవచ్చు చతుర్భుజ సంక్లిష్టత, ఇది 100+ విభాగాలతో పనిచేస్తుందని, ఎలాగో మీరే అర్థం చేసుకుంటారు...

PG10లో ఈ పరిస్థితి మద్దతును అమలు చేయడం ద్వారా బాగా ఆప్టిమైజ్ చేయబడింది స్థానిక విభజన. అందువల్ల, మేము నిల్వను తరలించిన వెంటనే దాన్ని వర్తింపజేయడానికి ప్రయత్నించాము, కానీ...

మాన్యువల్ ద్వారా త్రవ్విన తర్వాత తేలింది, ఈ సంస్కరణలో స్థానికంగా విభజించబడిన పట్టిక:

  • సూచిక వివరణలకు మద్దతు ఇవ్వదు
  • దానిపై ట్రిగ్గర్‌లకు మద్దతు ఇవ్వదు
  • ఎవరి "వారసుడు" కాలేడు
  • మద్దతు ఇవ్వరు INSERT ... ON CONFLICT
  • స్వయంచాలకంగా విభాగాన్ని రూపొందించలేరు

రేక్‌తో నుదిటిపై బాధాకరమైన దెబ్బ తగిలినందున, అప్లికేషన్‌ను సవరించకుండా చేయడం అసాధ్యమని మేము గ్రహించాము మరియు తదుపరి పరిశోధనను ఆరు నెలల పాటు వాయిదా వేసాము.

PG10: రెండవ అవకాశం

కాబట్టి, మేము తలెత్తిన సమస్యలను ఒక్కొక్కటిగా పరిష్కరించడం ప్రారంభించాము:

  1. ఎందుకంటే ట్రిగ్గర్స్ మరియు ON CONFLICT మాకు ఇప్పటికీ అవి ఇక్కడ మరియు అక్కడ అవసరమని మేము కనుగొన్నాము, కాబట్టి మేము వాటిని పని చేయడానికి ఇంటర్మీడియట్ దశను చేసాము ప్రాక్సీ పట్టిక.
  2. "రూటింగ్" నుండి బయటపడింది ట్రిగ్గర్లలో - అంటే, నుండి EXECUTE.
  3. వారు దానిని విడిగా బయటకు తీశారు అన్ని సూచికలతో టెంప్లేట్ పట్టికతద్వారా అవి ప్రాక్సీ టేబుల్‌లో కూడా ఉండవు.

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB
చివరగా, ఇవన్నీ తరువాత, మేము ప్రధాన పట్టికను స్థానికంగా విభజించాము. కొత్త విభాగం యొక్క సృష్టి ఇప్పటికీ అప్లికేషన్ యొక్క మనస్సాక్షికి మిగిలి ఉంది.

"సావింగ్" నిఘంటువులు

ఏదైనా విశ్లేషణాత్మక వ్యవస్థలో వలె, మేము కూడా కలిగి ఉన్నాము "వాస్తవాలు" మరియు "కోతలు" (నిఘంటువులు). మా విషయంలో, ఈ సామర్థ్యంలో వారు పనిచేశారు, ఉదాహరణకు, టెంప్లేట్ శరీరం ఇలాంటి స్లో ప్రశ్నలు లేదా ప్రశ్న యొక్క వచనం.

“వాస్తవాలు” ఇప్పటికే చాలా కాలంగా రోజువారీగా విభజించబడ్డాయి, కాబట్టి మేము పాత విభాగాలను ప్రశాంతంగా తొలగించాము మరియు అవి మమ్మల్ని ఇబ్బంది పెట్టలేదు (లాగ్‌లు!). కానీ నిఘంటువులతో సమస్య ఉంది...

వాటిలో చాలా ఉన్నాయి అని చెప్పలేము, కానీ సుమారుగా 100TB "వాస్తవాలు" ఫలితంగా 2.5TB నిఘంటువు వచ్చింది. అటువంటి పట్టిక నుండి మీరు సౌకర్యవంతంగా ఏదైనా తొలగించలేరు, మీరు దానిని తగిన సమయంలో కుదించలేరు మరియు దానికి వ్రాయడం క్రమంగా నెమ్మదిగా మారింది.

డిక్షనరీ లాగా... అందులో ఒక్కో ఎంట్రీని కచ్చితంగా ఒక్కసారి ప్రెజెంట్ చేయాలి... ఇది కరెక్టే కానీ!.. ఎవరూ అడ్డుకోవడం లేదు. ప్రతి రోజు ప్రత్యేక నిఘంటువు! అవును, ఇది ఒక నిర్దిష్ట రిడెండెన్సీని తెస్తుంది, కానీ ఇది అనుమతిస్తుంది:

  • వేగంగా వ్రాయండి/చదవండి చిన్న విభాగం పరిమాణం కారణంగా
  • తక్కువ జ్ఞాపకశక్తిని వినియోగిస్తుంది మరింత కాంపాక్ట్ ఇండెక్స్‌లతో పని చేయడం ద్వారా
  • తక్కువ డేటాను నిల్వ చేయండి కాలం చెల్లిన వాటిని త్వరగా తొలగించగల సామర్థ్యం కారణంగా

చర్యల మొత్తం సంక్లిష్టత ఫలితంగా CPU లోడ్ ~30% తగ్గింది, డిస్క్ లోడ్ ~50% తగ్గింది:

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB
అదే సమయంలో, మేము తక్కువ లోడ్‌తో డేటాబేస్‌లో సరిగ్గా అదే విషయాన్ని వ్రాయడం కొనసాగించాము.

#2. డేటాబేస్ పరిణామం మరియు రీఫ్యాక్టరింగ్

కాబట్టి మేము మా వద్ద ఉన్నదానిపై స్థిరపడ్డాము ప్రతి రోజు దాని స్వంత విభాగం ఉంటుంది డేటాతో. నిజానికి, CHECK (dt = '2018-10-12'::date) — మరియు విభజన కీ మరియు రికార్డ్ నిర్దిష్ట విభాగంలోకి రావడానికి షరతు ఉంది.

మా సేవలోని అన్ని నివేదికలు నిర్దిష్ట తేదీ సందర్భంలో రూపొందించబడినందున, "విభజన చేయని సమయాలు" నుండి వాటి కోసం సూచికలు అన్ని రకాలుగా ఉన్నాయి (సర్వర్, తేదీ, ప్రణాళిక మూస), (సర్వర్, తేదీ, ప్లాన్ నోడ్), (తేదీ, ఎర్రర్ క్లాస్, సర్వర్)...

కానీ ఇప్పుడు వారు ప్రతి విభాగంలో నివసిస్తున్నారు మీ కాపీలు అటువంటి ప్రతి సూచిక... మరియు ప్రతి విభాగంలో తేదీ స్థిరంగా ఉంటుంది... ఇప్పుడు మనం అలాంటి ప్రతి ఇండెక్స్‌లో ఉన్నామని తేలింది కేవలం స్థిరాంకాన్ని నమోదు చేయండి ఫీల్డ్‌లలో ఒకటిగా, దాని వాల్యూమ్ మరియు దాని కోసం శోధన సమయం రెండింటినీ పెంచుతుంది, కానీ ఏ ఫలితాన్ని తీసుకురాదు. వారు రేక్‌ను తమకే వదిలేశారు, అయ్యో...

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB
ఆప్టిమైజేషన్ యొక్క దిశ స్పష్టంగా ఉంది - సులభం అన్ని సూచికల నుండి తేదీ ఫీల్డ్‌ను తీసివేయండి విభజించబడిన పట్టికలలో. మా వాల్యూమ్‌లను బట్టి, లాభం దాదాపుగా ఉంటుంది 1TB/వారం!

ఈ టెరాబైట్ ఇప్పటికీ ఏదో ఒకవిధంగా రికార్డ్ చేయబడిందని ఇప్పుడు గమనించండి. అంటే మనం కూడా డిస్క్ ఇప్పుడు తక్కువగా లోడ్ అవుతుంది! ఈ చిత్రం శుభ్రపరచడం నుండి పొందిన ప్రభావాన్ని స్పష్టంగా చూపిస్తుంది, దీనికి మేము ఒక వారం కేటాయించాము:

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

#3. పీక్ లోడ్‌ను "విస్తరిస్తోంది"

లోడ్ చేయబడిన వ్యవస్థల యొక్క పెద్ద సమస్యలలో ఒకటి అనవసరమైన సమకాలీకరణ అవసరం లేని కొన్ని ఆపరేషన్లు. కొన్నిసార్లు "వారు గమనించనందున", కొన్నిసార్లు "అది సులభం", కానీ ముందుగానే లేదా తరువాత మీరు దాన్ని వదిలించుకోవాలి.

మునుపటి చిత్రాన్ని జూమ్ చేసి, మనకు డిస్క్ ఉందని చూద్దాం డబుల్ వ్యాప్తితో లోడ్ కింద "పంపులు" ప్రక్కనే ఉన్న నమూనాల మధ్య, ఇది స్పష్టంగా "గణాంకంగా" అటువంటి అనేక కార్యకలాపాలతో జరగకూడదు:

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

ఇది సాధించడం చాలా సులభం. ఇప్పటికే పర్యవేక్షణ ప్రారంభించాం దాదాపు 1000 సర్వర్లు, ప్రతి ఒక్కటి ప్రత్యేక లాజికల్ థ్రెడ్ ద్వారా ప్రాసెస్ చేయబడుతుంది మరియు ప్రతి థ్రెడ్ ఒక నిర్దిష్ట ఫ్రీక్వెన్సీలో డేటాబేస్కు పంపబడే సేకరించిన సమాచారాన్ని రీసెట్ చేస్తుంది, ఇలాంటిదే:

setInterval(sendToDB, interval)

ఇక్కడ సమస్య ఖచ్చితంగా వాస్తవంలో ఉంది అన్ని థ్రెడ్‌లు దాదాపు ఒకే సమయంలో ప్రారంభమవుతాయి, కాబట్టి వారి పంపే సమయాలు దాదాపు ఎల్లప్పుడూ "పాయింట్‌కి" సమానంగా ఉంటాయి. అయ్యో #2...

అదృష్టవశాత్తూ, దీన్ని పరిష్కరించడం చాలా సులభం, "యాదృచ్ఛిక" రన్-అప్‌ని జోడిస్తోంది సమయానికి:

setInterval(sendToDB, interval * (1 + 0.1 * (Math.random() - 0.5)))

#4. మనకు కావాల్సినవి కాష్ చేసుకుంటాము

మూడవ సాంప్రదాయ హైలోడ్ సమస్య కాష్ లేదు అతను ఎక్కడ ఉన్నాడు కాలేదు ఉండాలి.

ఉదాహరణకు, మేము ప్లాన్ నోడ్‌ల పరంగా విశ్లేషించడాన్ని సాధ్యం చేసాము (ఇవన్నీ Seq Scan on users), కానీ వెంటనే వారు చాలా భాగం, అదే అని అనుకుంటున్నాను - వారు మర్చిపోయారు.

లేదు, వాస్తవానికి, డేటాబేస్‌కు మళ్లీ ఏమీ వ్రాయబడలేదు, ఇది ట్రిగ్గర్‌ను తగ్గిస్తుంది INSERT ... ON CONFLICT DO NOTHING. కానీ ఈ డేటా ఇప్పటికీ డేటాబేస్కు చేరుకుంటుంది మరియు ఇది అనవసరం వివాదాన్ని తనిఖీ చేయడానికి చదవడం తప్పకుండా చేయాలి. అయ్యో #3...

కాషింగ్ ప్రారంభించబడటానికి ముందు/తర్వాత డేటాబేస్కు పంపబడిన రికార్డుల సంఖ్యలో తేడా స్పష్టంగా ఉంది:

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

నిల్వ లోడ్‌లో తగ్గుదల ఇది:

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

మొత్తం

"Terabyte-per-day" కేవలం భయానకంగా అనిపిస్తుంది. మీరు ప్రతిదీ సరిగ్గా చేస్తే, ఇది కేవలం 2^40 బైట్లు / 86400 సెకన్లు = ~12.5MB/sడెస్క్‌టాప్ IDE స్క్రూలు కూడా ఉంచబడ్డాయి. 🙂

కానీ తీవ్రంగా, రోజులో లోడ్ యొక్క పదిరెట్లు "వక్రత" తో కూడా, మీరు ఆధునిక SSD ల సామర్థ్యాలను సులభంగా కలుసుకోవచ్చు.

మేము సబ్‌లైట్‌లో PostgreSQLలో వ్రాస్తాము: 1 హోస్ట్, 1 రోజు, 1TB

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి