એલર્ટ્સ જે દરેક સર્વર દીઠ નહીં, એક વાર ફાયર થાય
અમારા ઓપરેશનલ એલર્ટોમાંથી એક — બિલ્ડરની પબ્લિશ થયેલી એપ માટે “ઓછા ક્રેડિટ” — અમારા સુધી વધુમાં વધુ દિવસમાં એક વાર પહોંચવાનું હતું. એક બપોરે તે પાંચ વાર આવ્યું. કારણ: અમારા API ની દરેક નકલ પોતાની મેમરીમાં યાદ રાખતી હતી કે કયા એલર્ટ પહેલેથી મોકલાયા છે, એટલે બે સર્વર તેને બે વાર મોકલતા, અને દરેક ડિપ્લોય તે મેમરી સાફ કરીને તેમને ફરી મોકલવાની છૂટ આપી દેતો. એ જ પેટર્નથી એક બેકગ્રાઉન્ડ જોબ પણ તેનું કામ બે વાર કરતી હતી. હવે બંને એક શેર્ડ સ્ટોર દ્વારા સંકલન કરે છે, અને સ્ટોર ઉપલબ્ધ ન હોય તો બંને સલામત બાજુએ નિષ્ફળ જાય છે.
લક્ષણ
Mythex કંઈક ધ્યાન માગે ત્યારે અમારી ટીમને એલર્ટ મોકલે છે: સર્વિસ ડાઉન હોય, જોબ અટકી જાય, અથવા બિલ્ડરની પબ્લિશ થયેલી એપ ચાલુ હોય ત્યારે તેનું ક્રેડિટ બેલેન્સ ઓછું થઈ રહ્યું હોય. દરેક એલર્ટની એક ડિડુપ વિન્ડો હોય છે — એક સમયગાળો જેમાં એ જ એલર્ટ ફક્ત એક વાર મોકલાય. ઓછા-ક્રેડિટ એલર્ટ માટે તે વિન્ડો 24 કલાકની છે.
એક બપોરે એ જ એલર્ટની પાંચ નકલો એનો અર્થ હતો કે વિન્ડો ટકતી નહોતી. તેથી પણ ખરાબ, તે જોડીમાં આવતી, લગભગ 11 મિનિટના અંતરે.
તે કેમ થયું
અમારા alerts પેકેજે તેની ડિડુપ મેમરીમાં રાખી હતી: એક ટેબલ “એલર્ટ કી → તે છેલ્લે ક્યારે મોકલાયું” ચાલતી પ્રક્રિયાની અંદર. એ ત્યારે કામ કરે જ્યારે એક પ્રક્રિયા હોય જે ક્યારેય રીસ્ટાર્ટ ન થાય. પ્રોડક્શનમાં ન તો એક છે, ન એ રીસ્ટાર્ટ નથી થતી:
- બે API રેપ્લિકા. પ્રોડક્શન API ની બે નકલો ચલાવે છે. દરેક પાસે પોતાનું ટેબલ હતું, એટલે દરેકે એલર્ટ એક વાર મોકલ્યું. એ જોડીઓ.
- ડિપ્લોય. દરેક ડિપ્લોય બંને રેપ્લિકાને તાજી પ્રક્રિયાઓ અને ખાલી ટેબલો સાથે બદલે છે. ડિપ્લોય પછી, એલર્ટ જાણે ક્યારેય મોકલાયું ન હોય તેમ ફરી ગયું.
દરેક જોડીના બે એલર્ટ વચ્ચેનો લગભગ 11 મિનિટનો ગેપ, એ એલર્ટ ઊભું કરતી જોબમાંથી આવ્યો. તે બંને રેપ્લિકા પર ચાલે છે અને એક લોક લે છે, એટલે રેપ્લિકાઓ વારાફરતી જીતે છે, અને દરેક પોતાનો વારો આવે ત્યારે એલર્ટ ઊભું કરતી.
એ જ કોડમાં એક બીજો, વધુ શાંત બગ હતો. ટેબલ અનિશ્ચિત રીતે વધતું ન રહે તે માટે, 500 કી થાય ત્યારે તે પોતાને પ્રુન કરતું — દરેક એન્ટ્રી જે 15 મિનિટથી જૂની હોય તેને કાઢી નાખતું, તેની વિન્ડો ગમે તે હોય. ભારે લોડ હેઠળ, 24-કલાકની ડિડુપ કાળના એક ચતુર્થાંશ કલાક સુધી જ ટકતી.
ફિક્સ
દરેક એલર્ટ માટે એક શેર્ડ રેકોર્ડ
API હવે એલર્ટ મોકલતા પહેલાં, Redis માં તે એલર્ટની ડિડુપ કી ક્લેઇમ કરે છે — એક શેર્ડ ઇન-મેમરી સ્ટોર જેની સાથે બંને રેપ્લિકા વાત કરે છે અને જે API રીસ્ટાર્ટ થાય ત્યારે રીસ્ટાર્ટ નથી થતો. ક્લેઇમ એક જ ઓપરેશન છે: “આ કી ત્યારે જ સેટ કરો જો તે અસ્તિત્વમાં ન હોય, અને વિન્ડો પછી તેની મુદત પૂરી કરો.” જે રેપ્લિકા પહેલાં ક્લેઇમ કરે તે એલર્ટ મોકલે; બીજી કી લીધેલી જુએ અને શાંત રહે. ડિપ્લોય પછીની નવી પ્રક્રિયાને કી હજી ત્યાં મળે છે.
કી અને વિન્ડો એ જ નિયમમાંથી આવે છે જેનો alerts પેકેજ ઉપયોગ કરે છે, હવે બંને વચ્ચે વહેંચાયેલો, જેથી બે લેયર “એક જ એલર્ટ” શું ગણાય તે અંગે અસંમત ન થઈ શકે.
નિષ્ફળ થાય ત્યારે ખુલ્લું, બંધ નહીં
સૌથી મહત્ત્વનો નિર્ણય એ હતો કે Redis સુધી પહોંચી ન શકાય ત્યારે શું કરવું. અમે એલર્ટ છતાં મોકલવાનું પસંદ કર્યું. જો Redis ડાઉન હોય, અથવા 1.5 સેકન્ડમાં જવાબ ન આપે, તો એલર્ટ જાય છે. ડુપ્લિકેટ એલર્ટ એ ઘોંઘાટ છે. ડ્રોપ થયેલું એલર્ટ એ એ છે કે કોઈને જાણ ન થઈ.
સૌથી ગંભીર એલર્ટ, P0, ડિડુપ દ્વારા ક્યારેય રોકાતાં નથી.
દરેક એન્ટ્રી પોતાની વિન્ડો રાખે છે
alerts પેકેજની પોતાની ઇન-મેમરી ડિડુપમાં, હવે દરેક એન્ટ્રી સંગ્રહે છે કે તેની વિન્ડો ક્યારે પૂરી થાય છે, અને પ્રુનિંગ ફક્ત એવી એન્ટ્રીઓ કાઢે છે જેની વિન્ડો પૂરી થઈ ગઈ હોય. 24-કલાકની કી 24 કલાક સુધી રહે છે, ભલે બીજા કેટલાય એલર્ટ આવે.
એ જ બગ, બીજે ક્યાંક
એ જ પેટર્નથી એક બેકગ્રાઉન્ડ કામ પણ બમણું થતું હતું: એક રિકન્સિલિએશન જોબ જે દરેક વર્કસ્પેસનું સ્ટેટસ અમારા સેન્ડબોક્સ પ્રોવાઇડરના સ્ટેટસ સાથે સરખું રાખે છે. દરેક પાસ એકાઉન્ટની દરેક સેન્ડબોક્સની યાદી લે છે — પ્રોડક્શનમાં હજારો, લગભગ પાંચ સેકન્ડ — ઉપરાંત દરેક ચાલુ કે પોઝ થયેલ પ્રોજેક્ટ. બંને રેપ્લિકા તેને દર બે મિનિટે ચલાવતી.
તેના લખાણો આઇડેમ્પોટન્ટ છે — તેને બે વાર ચલાવવાથી એક વાર ચલાવવા જેવું જ પરિણામ મળે છે — એટલે કંઈ તૂટ્યું નહોતું. બસ કામ બમણું હતું. હવે દરેક બે-મિનિટની વિન્ડો Redis માં એ જ રીતે ક્લેઇમ થાય છે જે રીતે અમારા યુઝેજ મીટર્સ પહેલેથી ક્લેઇમ કરતા હતા, અને ફક્ત જે રેપ્લિકા ક્લેઇમ કરે તે જ પાસ ચલાવે છે. જો Redis સુધી પહોંચી ન શકાય, તો પાસ છતાં ચાલે છે: કામ બે વાર કરવું હાનિકારક નથી, ન કરવું એ હાનિકારક છે.
અમે તેનું પરીક્ષણ કેવી રીતે કર્યું
ટેસ્ટ વાસ્તવિક સેટઅપનું મોડેલ કરે છે. તેઓ alert મોડ્યુલને બે વાર લોડ કરે છે, જાણે બે અલગ “રેપ્લિકા” હોય, બંનેને એક શેર્ડ સ્ટોર પર પોઇન્ટ કરે છે, દરેકમાંથી એ જ એલર્ટ ઊભું કરે છે, પછી “ડિપ્લોય પછી” માટે ત્રીજી તાજી નકલ લોડ કરીને ફરી ઊભું કરે છે. બરાબર એક એલર્ટ મોકલાય છે. અન્ય ટેસ્ટ તપાસે છે કે બીજા બિલ્ડરનું એલર્ટ હજી જાય છે, કે P0 બંને રેપ્લિકામાંથી મોકલાય છે, અને સ્ટોર ડાઉન હોય કે ટાઇમઆઉટ કરતાં વધુ સમય લે ત્યારે પણ એલર્ટ મોકલાય છે. પ્રુન ફિક્સની પોતાની ટેસ્ટ છે: 24-કલાકની કી 20 મિનિટ પછી આવેલા 600 બીજા એલર્ટ પછી પણ ટકે છે.
રિકન્સિલિએશન જોબ માટે, બે રેપ્લિકા એક સાથે ટિક કરે, વત્તા એ જ વિન્ડોમાં ત્રીજી ટિક, તો એક જ લિસ્ટિંગ થાય છે.
અમે શું શીખ્યા
- ઇન-મેમરી સ્ટેટ પ્રક્રિયા દીઠ હોય છે. જે સર્વરો વચ્ચે સાચું હોવું જોઈએ — “એક વાર મોકલ્યું”, “એક વાર ચાલ્યું” — તેને એવી જગ્યાએ રહેવું પડે જ્યાં તેઓ શેર કરે.
- ડિપ્લોય એટલે રીસ્ટાર્ટ. જે સ્ટેટ ફક્ત આગલા રીસ્ટાર્ટ સુધી ટકે છે, તે સામાન્ય કામના એક દિવસ સુધી પણ ટકતું નથી.
- કઈ રીતે નિષ્ફળ થવું તે નક્કી કરો. એલર્ટ માટે, શેર્ડ સ્ટોર ડાઉન હોય એનો અર્થ વધુ એલર્ટ થવો જોઈએ, ઓછા નહીં.
- ફક્ત ઉદાહરણ નહીં, પેટર્ન શોધો. એલર્ટ એ ઘોંઘાટવાળો કેસ હતો; બમણી થતી રિકન્સિલિએશન જોબ એ જ બગ હતો, શાંતિથી સમય વેડફતો.
આમાંથી કંઈ Mythex ની અંદરથી દેખાતું નથી. પ્લેટફોર્મ કેવી રીતે સ્થિર રાખીએ છીએ તે વિશે વધુ માટે, અમે ડિપ્લોય 502 એરર શૂન્ય સુધી કેવી રીતે લાવ્યા અને ગુમ થયેલી સ્વેપ ફાઇલ જુઓ. જો સર્વિસની એક કરતાં વધુ નકલ ચલાવવાના વિચારમાં તમે નવા છો, તો અમારી ગાઇડ સર્વર એટલે શું મૂળભૂત બાબતો આવરી લે છે.