ஒவ்வொரு சர்வருக்கும் ஒருமுறை அல்ல, ஒருமுறை மட்டுமே ஒலிக்கும் எச்சரிக்கைகள்
நாங்கள் அனுப்பும் செயல்பாட்டு எச்சரிக்கைகளில் ஒன்று — ஒரு builder-இன் வெளியிடப்பட்ட ஆப்பின் “குறைந்த கிரெடிட்கள்” — எங்களுக்கு அதிகபட்சம் ஒரு நாளுக்கு ஒருமுறை மட்டுமே வர வேண்டும். ஒரு மதியம் அது ஐந்து முறை வந்தது. காரணம்: எங்கள் API-இன் ஒவ்வொரு நகலும் தான் ஏற்கனவே அனுப்பிய எச்சரிக்கைகளை தன் சொந்த நினைவகத்தில் நினைவில் வைத்திருந்தது; இரண்டு சர்வர்கள் அதை இரண்டு முறை அனுப்பின, ஒவ்வொரு deploy-உம் அந்த நினைவகத்தைத் துடைத்து அவை மீண்டும் அனுப்ப வழி வகுத்தது. அதே வடிவம் ஒரு பின்னணி வேலையையும் இரண்டு முறை செய்ய வைத்தது. இப்போது இரண்டும் ஒரு பகிரப்பட்ட store மூலம் ஒருங்கிணைகின்றன; அந்த store கிடைக்காதபோது இரண்டும் பாதுகாப்பான பக்கமே தோல்வியடைகின்றன.
அறிகுறி
ஏதாவது கவனம் தேவைப்படும்போது Mythex தனது குழு எச்சரிக்கைகளை அனுப்புகிறது: ஒரு சேவை கீழே இருக்கும்போது, ஒரு வேலை தேங்கும்போது, ஒரு builder-இன் கிரெடிட் இருப்பு குறைந்து அவர்களின் ஆப் வெளியிடப்பட்டிருக்கும்போது. ஒவ்வொரு எச்சரிக்கைக்கும் ஒரு dedupe சாளரம் உண்டு — அந்தக் காலத்தில் அதே எச்சரிக்கை ஒருமுறை மட்டுமே அனுப்பப்படும். குறைந்த கிரெடிட்கள் எச்சரிக்கைக்கு அந்தச் சாளரம் 24 மணி நேரம்.
ஒரே மதியத்தில் ஐந்து நகல் எச்சரிக்கைகள் என்பது அந்தச் சாளரம் நிலைக்கவில்லை என்று பொருள். இன்னும் மோசமானது, அவை இரண்டிரண்டாக, ஏறத்தாழ 11 நிமிட இடைவெளியில் வந்தன.
ஏன் அது நடந்தது
எங்கள் alerts தொகுப்பு dedupe-ஐ நினைவகத்திலேயே வைத்திருந்தது: இயங்கும் செயல்முறைக்குள் “எச்சரிக்கை விசை → கடைசியாக எப்போது அனுப்பப்பட்டது” என்ற அட்டவணை. ஒரே ஒரு செயல்முறை எப்போதும் மறுதொடங்காமல் இருக்கும்போது அது வேலை செய்கிறது. உற்பத்தியில் இவை இரண்டுமே இல்லை:
- இரண்டு API பிரதிகள். உற்பத்தியில் API-இன் இரண்டு நகல்கள் இயங்குகின்றன. ஒவ்வொன்றுக்கும் தனித்தனி அட்டவணை இருந்ததால், ஒவ்வொன்றும் எச்சரிக்கையை ஒருமுறை அனுப்பின. அதுதான் ஜோடிகள்.
- Deploy-கள். ஒவ்வொரு deploy-உம் இரண்டு பிரதிகளையும் புதிய செயல்முறைகளால் மாற்றுகிறது, காலியான அட்டவணைகளுடன். Deploy-க்குப் பிறகு, எச்சரிக்கை ஒருபோதும் அனுப்பப்படாதது போல மீண்டும் வந்தது.
ஒவ்வொரு ஜோடியிலும் இரண்டு எச்சரிக்கைகளுக்கு இடையே இருந்த ~11 நிமிட இடைவெளி, இந்த எச்சரிக்கையை எழுப்பும் வேலையிலிருந்து வந்தது. அது இரண்டு பிரதிகளிலும் இயங்குகிறது, ஒரு lock எடுக்கிறது, அதனால் பிரதிகள் முறை மாறி வெற்றி பெறுகின்றன; ஒவ்வொன்றும் தன் முறை வந்தபோது எச்சரிக்கையை எழுப்பியது.
அதே குறியீட்டில் இன்னொரு, அமைதியான பிழையும் இருந்தது. அட்டவணை எல்லையில்லாமல் வளராமல் இருக்க, அது 500 விசைகளைக் கொண்டபோது தன்னைத்தானே சுத்தம் செய்தது — 15 நிமிடத்திற்கு பழைய ஒவ்வொரு உள்ளீட்டையும், அதன் சாளரம் எதுவாக இருந்தாலும், நீக்கியது. அதிக சுமையில், 24 மணி நேர dedupe கால் மணி நேரம் மட்டுமே நீடித்தது.
திருத்தம்
ஒவ்வொரு எச்சரிக்கைக்கும் ஒரு பகிரப்பட்ட பதிவு
இப்போது API ஒரு எச்சரிக்கையை அனுப்புவதற்கு முன், அந்த எச்சரிக்கையின் dedupe விசையை Redis-இல் உரிமை கோருகிறது — இரண்டு பிரதிகளும் பேசும், API மறுதொடங்கும்போதும் நிற்காத ஒரு பகிரப்பட்ட நினைவக store. அந்த உரிமைக் கோரிக்கை ஒரே செயல்பாடு: “இந்த விசை இல்லையென்றால் மட்டும் அமை, சாளரம் முடிந்ததும் காலாவதியாக்கு”. முதலில் உரிமை கோரும் பிரதி எச்சரிக்கையை அனுப்பும்; மற்றது விசை எடுக்கப்பட்டிருப்பதைக் கண்டு அமைதியாக இருக்கும். Deploy-க்குப் பிறகு வரும் ஒரு புதிய செயல்முறை விசை இன்னும் அங்கே இருப்பதைக் காணும்.
விசையும் சாளரமும் alerts தொகுப்பு பயன்படுத்தும் அதே விதியிலிருந்து வருகின்றன; இப்போது இரண்டுக்கும் இடையே பகிரப்பட்டவை, அதனால் “ஒரே எச்சரிக்கை” எது என்பதில் இரண்டு அடுக்குகளும் முரண்படாது.
தோல்வியடைவது திறந்த பக்கமாக, மூடிய பக்கமாக அல்ல
இதில் மிக முக்கியமான முடிவு, Redis-ஐ அடைய முடியாதபோது என்ன செய்வது என்பதுதான். எச்சரிக்கையை எப்படியும் அனுப்புவது என்று தேர்ந்தெடுத்தோம். Redis கீழே இருந்தாலோ 1.5 வினாடிக்குள் பதில் சொல்லாவிட்டாலோ, எச்சரிக்கை போய்விடும். நகல் எச்சரிக்கை என்பது சத்தம்தான். விடுபட்ட எச்சரிக்கை என்பது யாரோ ஒருவருக்குத் தெரிவிக்கப்படாமல் போவது.
மிக முக்கியமான எச்சரிக்கைகளான P0 ஒருபோதும் dedupe-ஆல் நிறுத்தி வைக்கப்படுவதே இல்லை.
ஒவ்வொரு உள்ளீடும் தனது சொந்த சாளரத்தை வைத்திருக்கிறது
alerts தொகுப்பின் சொந்த நினைவக dedupe-இல், ஒவ்வொரு உள்ளீடும் இப்போது அதன் சாளரம் எப்போது முடிகிறது என்பதைச் சேமிக்கிறது; சுத்தம் செய்வது சாளரம் முடிந்த உள்ளீடுகளை மட்டுமே நீக்குகிறது. 24 மணி நேர விசை வேறு எத்தனை எச்சரிக்கைகள் வந்தாலும் 24 மணி நேரம் நிலைக்கும்.
அதே பிழை, வேறு இடத்தில்
அதே வடிவம் ஒரு பின்னணி வேலையையும் இரட்டிப்பாக்கியிருந்தது: ஒவ்வொரு பணியிடத்தின் நிலையையும் எங்கள் sandbox வழங்குநரின் நிலையுடன் ஒத்திசைவாக வைக்கும் ஒரு reconciliation வேலை. ஒவ்வொரு பாஸும் கணக்கில் உள்ள ஒவ்வொரு sandbox-ஐயும் பட்டியலிடுகிறது — உற்பத்தியில் ஆயிரக்கணக்கானவை, சுமார் ஐந்து வினாடிகள் — மேலும் இயங்கும் அல்லது இடைநிறுத்தப்பட்ட ஒவ்வொரு திட்டத்தையும். இரண்டு பிரதிகளும் அதை ஒவ்வொரு இரண்டு நிமிடத்துக்கும் இயக்கின.
அதன் எழுத்துகள் idempotent — அதாவது இரண்டு முறை இயக்கினால் ஒருமுறை இயக்கியதற்குச் சமமான முடிவு வரும் — அதனால் எதுவும் உடையவில்லை. இருமடங்கு வேலைதான். இப்போது ஒவ்வொரு இரண்டு நிமிட சாளரமும் Redis-இல் உரிமை கோரப்படுகிறது, எங்கள் பயன்பாட்டு meter-கள் ஏற்கனவே தங்களுடையதை உரிமை கோருவதுபோல; அந்த சாளரத்தை உரிமை கோரும் பிரதி மட்டுமே பாஸை இயக்குகிறது. Redis-ஐ அடைய முடியாவிட்டால், பாஸ் எப்படியும் இயங்கும்: வேலையை இருமுறை செய்வது தீங்கற்றது; செய்யாமல் விடுவதுதான் தீங்கானது.
நாங்கள் அதைச் சோதித்தது எப்படி
சோதனைகள் உண்மையான அமைப்பை மாதிரியாகக் கொள்கின்றன. அவை alert தொகுப்பை இரண்டு முறை ஏற்றி, இரண்டு தனித்தனி “பிரதிகளாக” அவற்றை ஒரே பகிரப்பட்ட store-ஐ நோக்கி வைக்கின்றன, இரண்டிலிருந்தும் ஒரே எச்சரிக்கையை எழுப்புகின்றன; பின்னர் “deploy-க்குப் பின்” நிலையாக ஒரு புதிய நகலை ஏற்றி மீண்டும் எழுப்புகின்றன. சரியாக ஒரு எச்சரிக்கை அனுப்பப்படுகிறது. வேறு builder-இன் எச்சரிக்கை இன்னும் போகிறதா, P0 இரண்டு பிரதிகளிலிருந்தும் அனுப்பப்படுகிறதா, store கீழே இருந்தாலோ நேரம் முடிந்தாலோ எச்சரிக்கை இன்னும் அனுப்பப்படுகிறதா என்பதையும் மற்ற சோதனைகள் பார்க்கின்றன. சுத்தம் செய்யும் திருத்தத்துக்கு அதன் சொந்த சோதனை உண்டு: 20 நிமிடம் கழித்து வந்த 600 மற்ற எச்சரிக்கைகளுக்குப் பின்னும் 24 மணி நேர விசை தப்பிப் பிழைக்கிறது.
reconciliation வேலைக்கு, ஒரே நேரத்தில் இயங்கும் இரண்டு பிரதிகள், அதே சாளரத்தில் மூன்றாவது tick ஆகியவை ஒரே ஒரு பட்டியலையே உருவாக்குகின்றன.
இதிலிருந்து நாங்கள் கற்றது
- நினைவகத்தில் உள்ள நிலை செயல்முறைக்கு மட்டுமே உரியது. சர்வர்களுக்கு இடையே உண்மையாக இருக்க வேண்டியவை — “ஒருமுறை அனுப்பப்பட்டது”, “ஒருமுறை இயங்கியது” — அவை பகிர்ந்துகொள்ளும் ஓர் இடத்தில் வாழ வேண்டும்.
- Deploy-கள் என்பவை மறுதொடக்கங்கள். அடுத்த மறுதொடக்கம் வரை மட்டுமே நிலைக்கும் நிலை, ஒரு சாதாரண வேலை நாளைக்கூட தாண்டாது.
- எந்த வழியில் தோல்வியடைவது என்பதை முடிவு செய்யுங்கள். எச்சரிக்கைகளுக்கு, பகிரப்பட்ட store கீழே இருப்பது குறைவான எச்சரிக்கைகள் அல்ல, அதிகமான எச்சரிக்கைகளைக் குறிக்க வேண்டும்.
- நிகழ்வை மட்டுமல்ல, வடிவத்தையும் தேடுங்கள். எச்சரிக்கை சத்தமான உதாரணம்; இரட்டிப்பான reconciliation வேலை அதே பிழை, அமைதியாக வேலையைச் செலவழித்தது.
இதில் எதுவும் Mythex-இன் உள்ளிருந்து தெரியாது. தளத்தை எப்படி நிலையாக வைத்திருக்கிறோம் என்பதற்கு, deploy-களில் 502 பிழைகளை பூஜ்யமாகக் குறைத்த விதம் மற்றும் காணாமல் போன swap கோப்பு பார்க்கவும். ஒரு சேவையின் ஒன்றுக்கு மேற்பட்ட நகல்களை இயக்கும் கருத்துக்கு நீங்கள் புதியவர் என்றால், சர்வர் என்றால் என்ன என்ற எங்கள் வழிகாட்டி அடிப்படைகளை விளக்குகிறது.