பல வாரங்களாக, Elevare Digital-ல் ஒரு cron job திட்டமிட்டபடி விழித்து, அதன் queue-வைச் சரிபார்த்து, வெற்றிகரமாக முடிந்துவிட்டதாகப் பதிவு (log) செய்தது. அது சரியாக ஒரு வரைவு கூட (draft) அங்கீகரிக்கவில்லை. பத்தொன்பது உள்ளடக்கங்கள் காத்திருந்தன. அந்த அமைதியான இடைவெளி ஒரு விசித்திரத்திலிருந்து சிறிய நிலுவைப்பணியாக (backlog) மாறிய பின்னரே குழுவினர் அதைத் தெரிந்து கொண்டனர். எதுவும் செயலிழக்கவில்லை (crash). எந்த எச்சரிக்கை அறிவிப்புகளும் (paging alerts) வரவில்லை. தொழில்நுட்ப ரீதியாக சிஸ்டம் ஆரோக்கியமாக இருந்தது, ஆனால் செயல்பாட்டு ரீதியாக அது செயலிழந்து கிடந்தது.
இது தன்னாட்சிப் பாதைகளின் (autonomous pipelines) அமைதியான பயமுறுத்தும் நிலை. ஒரு செயல்பாட்டில் மனிதனை நீக்கும்போது, அங்கு எதுவும் நடக்கவில்லை என்பதைக் கவனிக்கும் நபரையும் நீக்கிவிடுகிறீர்கள்.
தானாகவே இயங்கிய அந்தப் பாதை
Elevare Digital ஒரு முழுமையான தானியங்கி உள்ளடக்கப் பணிப்பாய்வை (content workflow) இயக்குகிறது. மென்பொருள் ஏஜெண்டுகள் (Software agents) வரைவுகளை உருவாக்குகின்றன. ஒரு திட்டமிடப்பட்ட அங்கீகரிக்கும் cron, ஒரு காவலரைப் போலச் செயல்பட்டு, அந்த வரைவுகளை ஆய்வு செய்து, அங்கீகரிக்கப்பட்டவற்றை நேரடியாக வெளியிடுவதற்கு (publishing) அனுப்புகிறது. ஒவ்வொரு தொகுப்பையும் அங்கீகரிக்க மனிதர்கள் டேஷ்போர்டைத் திறப்பதில்லை. குழுவினர் மற்ற சிக்கல்களில் கவனம் செலுத்தும்போது, இயந்திரமே இந்தத் துயரமான வேலைகளைச் செய்துவிடும் என்பதே இதன் நோக்கம்.
இந்த மாதிரியில், நம்பிக்கையே உங்கள் முதன்மைத் தொடர்பாகும். ஷெட்யூலர் (scheduler) இயங்கும் என்று நம்புகிறீர்கள். வேலை நடக்கும் என்று நம்புகிறீர்கள். எக்சிட் கோட் (exit code) சரியாக இருக்கும் என்று நம்புகிறீர்கள். லாக்ஸில் (logs) தொடர்ச்சியான 200 OK பதில்கள் வரும்போது, வேலை நடப்பதாக நீங்கள் கருதுகிறீர்கள். பல வாரங்களாக, அந்தத் துடிப்பு சரியாக இருந்தது. cron ஒவ்வொரு முறையும் சரியான நேரத்தில் இயங்கியது. ஆனால் அது உண்மையான வேலையைச் செய்யவே இல்லை.
பத்தொன்பது வரைவுகள் மற்றும் எந்த எச்சரிக்கையும் இல்லை
இந்தக் கண்டுபிடிப்பு தற்செயலாக நடந்தது. வெளியீட்டு வரிசை (publishing queue) அமைதியாகிவிட்டதை யாரோ கவனித்தனர், அல்லது ஒரு கீழ்நிலை அளவீட்டை (downstream metric) சரிபார்த்தபோது அது எந்த மாற்றமும் இன்றி நிலையாக இருப்பதை உணர்ந்தனர். அவர்கள் கண்டது என்னவென்றால், பத்தொன்பது வரைவுகள் தொடப்படாமலேயே இருந்தன. அங்கீகரிக்கும் cron கடமையுடன் இயங்கி, ஒவ்வொரு நாளும் வெற்றிகரமாக முடிந்துவிட்டதாகப் பதிவு செய்து வந்தது, ஆனால் அவற்றில் எதையும் செயல்படுத்தவில்லை.
ஒரு கைமுறைப் பணிப்பாய்வில் (manual workflow), ஒரு மனித ஆய்வாளர் முதல் நாளிலேயே காலியான இன்பாக்ஸையோ அல்லது நிலுவையில் உள்ள பொருட்களின் குவியலையோ கவனித்திருப்பார். தானியங்கி முறையில், செயல்பாடுகள் இல்லாதது வேலையே இல்லாதது போலவே தோன்றியது. cron ஏமாற்ற வேண்டிய மேலாளர் யாரும் இல்லை. அது வேலையில் சேர்ந்துவிட்டு சீக்கிரமே கிளம்பிச் சென்றுவிட்டது.
இரண்டு பிழைகள், ஒரு வெற்று முடிவு
இந்தத் தோல்விக்கு இரண்டு காரணங்கள் இருந்தன. அவை syntax error, timeout அல்லது dependency outage ஆகியவற்றுள் எதுவும் இல்லை. இரண்டும் semantic பிழைகள், அவை query engine-ன் பார்வையில் பத்தொன்பது சரியான வரிசைகளை (rows) எதுவுமற்றதாக மாற்றின.
முதலாவதாக, ஒரு type mismatch. வரைவுகளை உருவாக்கும் ஏஜென்ட், article என்று குறிக்கப்பட்ட பதிவுகளை எழுதியது. ஆனால் அங்கீகரிக்கும் cron குறிப்பாக thread வகைகளைத் தேடியது. உற்பத்தியாளர்களும் (producers) நுகர்வோர்களும் (consumers) வெவ்வேறு பாதைகளில் வளரும்போது இத்தகைய மாற்றங்கள் (drift) நிகழும். ஒரு குழு அல்லது ஒரு ஏஜென்ட் வெளியீடு ஒரு article என்று முடிவு செய்தது. மற்றொரு குழு அது thread-களைப் பெறும் என்று கருதி நுகர்வோரை (consumer) உருவாக்கியது. இவை பெரும்பாலும் loose string tags, JSON fields அல்லது unenforced varchar மதிப்புகள் என்பதால், எந்த type system-உம் compile-time error-ஐத் தரவில்லை. டேட்டாபேஸ் எதையும் பொருத்தவில்லை என்பதைக் கண்டறிந்து ஒரு வெற்றுத் தொகுதியை (empty set) வழங்கியது. இது engine-க்கு ஒரு பிழை நிலை (error condition) அல்ல. இது ஒரு தவறான கேள்விக்குக் கிடைத்த சரியான பதில்.
இரண்டாவதாக, அங்கீகரிக்கும் query-ல் இருந்த ஒரு inner join, அந்த வரிசைகளை முழுமையாக விழுங்கியது. அந்த query, வரைவு அட்டவணையை (drafts table) மற்றொரு அட்டவணையுடன் (metadata, status flags அல்லது routing rules போன்றவற்றைத் தேட) இணைக்கும்போது, join condition தோல்வியடைந்தால், inner join வடிவமைக்கப்பட்டபடியே செயல்பட்டது. அது பொருந்தாத வரிசைகளைத் தவிர்த்தது. எந்தத் தனித்த வரிசைகளும் (orphan rows) முடிவில் வரவில்லை. எந்த null மதிப்புகளும் பிரச்சனையைச் சுட்டிக்காட்டவில்லை. அந்த பத்தொன்பது வரைவுகளும் ஒரு சல்லடையின் வழியாகத் தண்ணீர் செல்வது போல query-யைத் தாண்டிச் சென்றன, மேலும் application layer ஒரு சுத்தமான, வெற்றுப் பட்டியலைப் பெற்றது.
Query எந்த வரிசைகளையும் வழங்காததால், function சுத்தமாக முடிவடைந்தது. எந்த exceptions-உம் வரவில்லை. HTTP response 200 OK ஆக இருந்தது. cron வெற்றியைப் பதிவு செய்துவிட்டு மீண்டும் உறங்கச் சென்றது.
'Processed Zero' எனும் பொறி
இதுதான் பிரச்சனையின் முக்கிய அம்சம். ஒரு queue-அடிப்படையிலான அமைப்பில், ஒரு நுகர்வோர் (consumer) பெரும்பாலும் செயலாக்கத்திற்கு பூஜ்ஜிய வரிசைகளையே காண்பார். வரிசை காலியாகிவிடும். வேலை விரைவாக முடிந்துவிடும். லாக்ஸில் processed: 0 என்று வரும்போது, குழுவினர் அதை ஒரு நல்ல செய்தியாகக் கருதுகிறார்கள்: நாம் தேவையைச் சரியாகச் சமாளிக்கிறோம் என்று நினைக்கிறார்கள். அது ஒரு ஆரோக்கியமான நிலை.
ஆனால் processed: 0 என்பது முற்றிலும் மாறுபட்ட இரண்டு யதார்த்தங்களைக் குறிக்கிறது:
- ஆரோக்கியமான நிலை (Healthy state): நிலுவையில் எதுவும் இல்லாததால் பூஜ்ஜியம் செயலாக்கப்பட்டது. வரிசை காலியாக உள்ளது. சிஸ்டம் வடிவமைக்கப்பட்டபடியே ஓய்வில் உள்ளது.
- பாதிக்கப்பட்ட நிலை (Broken state): நுகர்வோரால் வேலையைக் காண முடியாததால் பூஜ்ஜியம் செயலாக்கப்பட்டது. வரிசையில் பத்தொன்பது வரிசைகள் உள்ளன. சிஸ்டம் பார்வையற்ற நிலையில் உள்ளது, ஓய்வில் இல்லை.
வரிசையின் ஆழத்தை (queue depth) ஒரு தனிச் சரிபார்ப்பு இல்லாமல், இந்த இரண்டு நிலைகளும் ஒரே மாதிரியான telemetry-யையே வெளியிடுகின்றன. அவை டேஷ்போர்டுகளில் ஒரே மாதிரியாகத் தெரியும், log aggregators-களில் ஒரே மாதிரியாகத் தோன்றும், மேலும் PagerDuty-யில் ஒரே மாதிரியான அமைதியையே ஏற்படுத்தும். நீங்கள் ஒரு கண்காணிப்பு உத்தியை (monitoring strategy) உருவாக்கியுள்ளீர்கள், அது வேலை செய்பவர் கத்தும்போது மட்டுமே கண்டறியும், ஒரு பெரிய வேலைக் குவியலைத் தாண்டி அவர் மெதுவாகச் செயல்படும்போது கண்டறியாது.
இடைவெளியைக் குறைத்தல்
Elevare Digital தாங்கள் கண்காணிக்கும் விஷயத்தை மாற்றுவதன் மூலம் இந்தப் பிரச்சனையைச் சரிசெய்தது. அவர்கள் பிழை விகிதங்கள் (error rates) மற்றும் வெற்றி நிலைகளை (success statuses) மட்டுமே நம்பியிருப்பதை நிறுத்திவிட்டார்கள். அதற்குப் பதிலாக, கிடைக்கக்கூடிய வேலைக்கும் (available work) முடிக்கப்பட்ட வேலைக்கும் (completed work) இடையிலான இடைவெளியை அடிப்படையாகக் கொண்டு எச்சரிக்கைகளை (alerts) வழங்கத் தொடங்கினார்கள்.
ஒவ்வொரு தொகுப்பிற்குப் (batch) பின்னரும், அவர்கள் இப்போது ஒரு எளிய மாறாச் சரிபார்ப்பை (invariant check) செய்கிறார்கள்:
processedஎன்பது 0 ஆக இருந்து மற்றும்pendingவரிசைகள் (rows) 0-வை விட அதிகமாக இருந்தால், ஒரு உயர் தீவிர எச்சரிக்கையை (high severity alert) முன்னெடுத்துச் செல்லவும்.
இந்த விதி வேண்டுமென்றே காரணத்தைப் பொருட்படுத்தாமல் உருவாக்கப்பட்டது. அந்தத் தவறு ஒரு தவறான வடிகட்டி (bad filter), ஒரு உடைந்த இணைப்பு (broken join) அல்லது தவறாகத் தட்டச்சு செய்யப்பட்ட enum string ஆகியவற்றால் ஏற்பட்டதா என்பதை இது கவலைப்படுவதில்லை. வேலை இருக்கிறது, ஆனால் எந்த வேலையும் செய்யப்படவில்லை என்பதை மட்டுமே இது கவனிக்கிறது. இது கண்காணிப்பின் நோக்கத்தை “செயல்முறை புகார் தெரிவித்தது?” என்பதிலிருந்து “வேலை நகர்ந்ததா?” என்பதற்கு மாற்றுகிறது.
இதை ஆதரிக்க, அவர்கள் வரிசை ஆழத்தை (queue depth) ஒரு முக்கியமான அளவீடாக (first-class metric) கருதுகிறார்கள்; அதை அவ்வப்போது சரிபார்ப்பதற்குப் பதிலாக, காலப்போக்கில் கண்காணிப்பார்கள். உற்பத்தியாளர் (producer) தொடர்ந்து வரிசைகளைச் சேர்த்துக் கொண்டே இருக்கும்போது, நுகர்வோர் (consumer) தொடர்ந்து வெற்றியைத் தெரிவித்துக் கொண்டிருந்தால், அந்த ஆழத்தின் போக்கு (depth trend) ஒரு தெளிவான ஆதாரமாக (smoking gun) மாறும். ஒரு நிலையானத் தகவல் (static snapshot) பொய் சொல்லலாம், ஆனால் வளர்ந்து வரும் நிலுவைப்பணி (creeping backlog) ஒருபோதும் பொய் சொல்லாது.
தன்னாட்சி அமைப்புகளுக்கான பாடங்கள்
Elevare சம்பவமானது, தானியங்கி வழித்தடங்களை (hands-off pipelines) இயக்கும் எவருக்கும் சில நடைமுறை விதிகளைக் கொண்டுள்ளது.
scanned rows-களை processed rows-லிருந்து தனித்தனியாகப் பதிவு செய்யவும். நுகர்வோர் (consumer) நாற்பது வரிசைகளைத் தொடும் ஒரு வினவலை (query) இயக்கலாம், தவறான அளவுகோல்களால் (criteria) அவை அனைத்தையும் வடிகட்டிவிட்டு, processed: 0 என்று தெரிவிக்கலாம். நீங்கள் இறுதி எண்ணிக்கையை மட்டும் பதிவு செய்தால், அந்த மறைமுகத் தொடர்பை (ghost interaction) நீங்கள் தவறவிடுவீர்கள். scanned-rows அளவீடு, பணியாளர் அங்கு வந்து, வேலையைப் பார்த்துவிட்டு, குழப்பத்துடன் சென்றதை வெளிச்சம் போட்டுக் காட்டும். scanned மற்றும் processed-க்கு இடையிலான அந்த இடைவெளியே பெரும்பாலும் உங்கள் ஆரம்பகாலத் தகவலாகும்.
வரிசை ஆழத்தை (queue depth) ஒரு காலவரிசையாக (time-series) கண்காணிக்கவும். ஒரு வரிசை தற்காலிகமாக காலியாக இருப்பது பரவாயில்லை. பணியாளர்கள் சரியாகச் செயல்படும்போது (green status), ஒரு வரிசைத் தொடர்ந்து வளர்ந்து கொண்டே இருப்பது சரியல்ல. நுகர்வோர் செயல்திறனுக்கு (consumer throughput) எதிராக ஆழத்தை வரைபடமாக்கவும். இவை இரண்டும் விலகிச் செல்லும்போது, அனைத்து ஆரோக்கியச் சரிபார்ப்புகளும் (health checks) வெற்றிகரமாக இருந்தாலும், உடனடியாகப் புலனாய்வு செய்யவும்.
நுகர்வோரை (consumers) வெறும் போலித் தரவுகளைக் (mocks) கொண்டு மட்டும் சோதிக்காமல், உண்மையான உற்பத்தியாளரின் (producer) வெளியீட்டைக் கொண்டு சோதிக்கவும். போலித் தரவுகளைக் கொண்ட யூனிட் சோதனைகள் (Unit tests), சோதனையாளரின் அனுமானங்களையே சுமந்து வரும். போலித் தொழிற்சாலை (mock factory) thread வகைகளைத் தயாரித்து, நுகர்வோர் thread வகைகளை எதிர்பார்த்தால், உங்கள் சோதனைகள் வெற்றி பெறும், ஆனால் நேரடிச் செயல்பாட்டில் (production) தோல்வியடையும். உற்பத்தியாளரின் வெளியீட்டிலிருந்து உண்மையான பதிவுகளைப் பெறும் ஒருங்கிணைப்புச் சோதனைகளை (integration tests) இயக்கவும். உற்பத்தியாளர் எழுதுவதை நுகர்வோர் உண்மையிலேயே பார்க்க முடிகிறதா என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள்.
தரவு வகைகளையும் (data types) enum மதிப்புகளையும் ஒப்பந்தங்களாகக் (contracts) கருதவும். JSON பிளாப்களில் உள்ள தளர்வான ஸ்ட்ரிங் டேக்లు (string tags) வசதியாக இருக்கலாம், ஆனால் அவை கண்ணுக்குத் தெரியாத தோல்விப் புள்ளிகளாக மாறும் வரை மட்டுமே. ஸ்கீமாக்களை (schemas) வெளிப்படையாக வரையறுக்கவும். மாறிலிகளைப் (constants) பகிரவும். உற்பத்தியாளர் மற்றும் நுகர்வோருக்கு இடையிலான இணைப்பில் பேலோடுகளை (payloads) சரிபார்க்கவும். ஒப்பந்தம் உடைந்தால், அமைப்பு ஒரு WHERE உட்பிரிவிற்குள் அமைதியாகத் தோல்வியடையாமல், அதன் எல்லையிலேயே சத்தமாகத் தோல்வியடைய வேண்டும்.
உண்மையான பாடம்
தன்னாட்சி அமைப்புகள் மனிதர்களைப் போலத் தோல்வியடைவதில்லை. அவை உடல்நிலை சரியில்லை என்று விடுமுறை எடுக்காது, ஒவ்வொரு முறையும் விதிவிலக்குகளை (exceptions) வீசாது அல்லது தெளிவான கிராஷ் டம்புகளை (crash dumps) விட்டுச் செல்லாது. அவை 200 OK-வை வழங்கிவிட்டு, இருப்புகளை (inventory) அழுக let செய்யும். உங்கள் எச்சரிக்கைகள் அலறல்களை மட்டுமே கேட்டால், மிகவும் விலையுயர்ந்த தோல்விகளை நீங்கள் தவறவிடுவீர்கள்—அவை அனைத்தும் சரியாகத் தோன்றும் ஆனால் எந்த வேலையும் செய்யப்படாத தருணங்கள்.
இடைவெளியைக் கண்காணிக்க உங்கள் அவதானிப்புத் திறனை (observability) வடிவமைக்கவும். உள்ளே நுழையும் வேலையை வெளியேறும் வேலையோடு ஒப்பிட்டு அளவிடவும். இவை இரண்டும் பொருந்தாதபோது, இயந்திரம் உங்களிடம் பொய் சொல்கிறது என்று கருதுங்கள். ஏனெனில் சில நேரங்களில், ஒரு சரியான வெற்றிப் பதிவு (success log) என்பது முற்றிலும் பார்வையற்ற ஒரு அமைப்பின் ஒரே அறிகுறியாக இருக்கலாம்.
