સવારે ત્રણ વાગ્યે તમારું ડેટાબેઝ CPU 100% પર પહોંચી જાય છે. ટ્રાફિક સામાન્ય લાગે છે. વિનંતીઓ (requests) ની સંખ્યા અસામાન્ય રીતે વધારે નથી. તેમ છતાં તમારું પ્રાઇમરી સ્ટોર તૂટી રહ્યું છે કારણ કે તેમાંથી દરેક વિનંતી બરાબર એક જ સમયે બરાબર એક જ વસ્તુ માંગી રહી છે.

આ 'થન્ડરિંગ હર્ડ' (thundering herd) સમસ્યા છે.

કોન્સર્ટ પછીના સ્ટેડિયમ વિશે વિચારો. એક કલાક દરમિયાન, એ જ બહાર નીકળવાનો દરવાજો દરેકને આરામથી બહાર જવા દેઈ શકે છે. પરંતુ જો આખું ટોળું તે જ દસ સેકન્ડના સમયગાળામાં તે એક જ દરવાજામાંથી બહાર નીકળવાનું નક્કી કરે, તો દરવાજો તૂટતો નથી. તે ફક્ત તે એકસાથે થતી ભીડ (concurrency) ને સંભાળી શકતો નથી. સમસ્યા ભીડમાં છે, દરવાજામાં નહીં.

ટોળું ક્યાં રચાય છે

જ્યારે ઘણી પ્રક્રિયાઓ (processes) એક જ ઘટના પર સિંક્રનાઇઝ થાય છે ત્યારે આ પેટર્ન જોવા મળે છે. આ માટે તમારે કોઈ નુકસાનકારક (malicious) ટ્રાફિકની જરૂર નથી. સામાન્ય સિસ્ટમો પણ પોતાની સાથે આવું કરે છે.

Cache expiration. એક હોટ કેશ કી (hot cache key) એક્સપાયર થાય છે. તે પ્રોડક્ટ કેટલોગ, ફીચર ફ્લેગ અથવા યુઝરની પરમિશન લિસ્ટ હોઈ શકે છે. હજારો એપ્લિકેશન સર્વર્સ એકસાથે ખાલી સ્લોટની નોંધ લે છે. દરેક સર્વર, સારા ઈરાદાથી, પોતાનું ડેટાબેઝ કનેક્શન ખોલે છે અને વેલ્યુ ફરીથી બનાવવા માટે સમાન ભારે ક્વેરી (heavy query) ચલાવે છે. ડેટાબેઝને ક્યારેય સમાંતર રીતે (in parallel) એક જ મોંઘી પ્રશ્નનો બે હજાર વખત જવાબ આપવા માટે કોન્ફિગર કરવામાં આવ્યો ન હતો. એક એક્સપાયર્ડ કી આખા ક્લસ્ટરને ઠપ કરી દે છે.

Connection pool wakeups. અમુક આર્કિટેક્ચરમાં, ઘણા વર્કર પ્રોસેસ કામ આવવાની રાહ જોતા એક જ કન્ડિશન પર બ્લોક થઈ જાય છે. જ્યારે તે કન્ડિશન સક્રિય થાય છે, ત્યારે ઓપરેટિંગ સિસ્ટમ દરેક સૂતેલા વર્કરને જગાડે છે. વાસ્તવમાં માત્ર એક જ વર્કર કનેક્શન અથવા કાર્ય મેળવે છે. બાકીના જાગી જાય છે, તેમને ખબર પડે છે કે તેઓ રેસ હારી ગયા છે, અને ફરીથી સૂઈ જાય છે. આ ચક્ર context switches માં CPU વાપરે છે અને વાસ્તવિક ઉત્પાદક કાર્યને અવરોધિત કરી શકે છે.

Retry storms. કોઈ ડાઉનસ્ટ્રીમ સર્વિસમાં ખામી આવે છે. દરેક ક્લાયન્ટ ટાઈમઆઉટને પકડે છે અને ફરીથી પ્રયાસ કરતા પહેલા એક નિશ્ચિત સમયગાળો, ધારો કે બરાબર એક સેકન્ડ, રાહ જુએ છે. જ્યારે સર્વિસ રિકવર થાય છે અને ફરીથી ટ્રાફિક સ્વીકારે છે, ત્યારે દરેક ક્લાયન્ટ તે જ ક્ષણે તેના પર હુમલો કરે છે. સર્વિસ, જે હજુ પણ ઠંડી (cold) અને રિકવર થઈ રહી હોય છે, તે ફરીથી ડાઉન થઈ જાય છે. આ ચક્ર પુનરાવર્તિત થાય છે.

Cron collisions. જો તમે ઇન્સ્ટન્સના સમૂહમાં મેન્ટેનન્સ, રિપોર્ટ જનરેશન અથવા કેશ વોર્મિંગ બરાબર 00:00 UTC પર ચલાવવા માટે શેડ્યૂલ કરો છો, તો તમે ચોકસાઈ સાથે ટ્રાફિક સ્પાઇક (traffic spike) પેદા કરો છો. લોડ અનુમાનિત છે, પરંતુ તેનું કેન્દ્રીકરણ જીવલેણ છે.

Request Coalescing

કેશ સ્ટેમ્પિડ્સ (cache stampedes) માટે સૌથી અસરકારક ઉપાય એ છે કે એક જ પ્રશ્નનો એકથી વધુ વખત જવાબ આપવાનું બંધ કરવું. જ્યારે કેશ મિસ (cache miss) થાય છે, ત્યારે તમે ઈચ્છતા નથી કે 2,500 થ્રેડ્સ દરેક ડેટાબેઝ ક્વેરી ચલાવે. તમે ઈચ્છો છો કે એક થ્રેડ ક્વેરી ચલાવે જ્યારે અન્ય 2,499 તે પરિણામ માટે રાહ જુએ.

આ પેટર્નને ઘણીવાર request coalescing કહેવામાં આવે છે. Go માં, golang.org/x/sync માં singleflight પેકેજ એક પ્રમાણભૂત અમલીકરણ (canonical implementation) પૂરું પાડે છે. આપેલ કી માટે Do ને કોલ કરનાર પ્રથમ goroutine કામ શરૂ કરે છે. તે જ કી ધરાવતા પછીના કોલર્સ તે જ Do કોલ પર બ્લોક થાય છે. જ્યારે કામ પૂરું થાય છે, ત્યારે તમામ રાહ જોનારાઓને એકસાથે પરિણામ મળે છે. તમે એક ક્વેરી ચલાવી છે અને 2,500 વિનંતીઓ પૂરી કરી છે.

તમે પ્રોમિસિસ (promises), ફ્યુચર્સ (futures) અથવા ચેનલ્સ (channels) ના ઇન-મેમરી કન્કરન્ટ મેપ સાથે સમાન વર્તણૂક બનાવી શકો છો. યુક્તિ એ છે કે ઇન-ફ્લાઇટ વિનંતીને એટમિકલી (atomically) તપાસવી અને રજિસ્ટર કરવી. જો વિનંતી નિષ્ફળ જાય છે, તો દરેકને ભૂલ (error) મળે છે, જે સામાન્ય રીતે સાચું વર્તન છે. જો તે સફળ થાય છે, તો દરેકને કેશ કરેલી વેલ્યુ મળે છે, અને ત્યારબાદની વિનંતીઓ સીધી કેશ પર જાય છે. ડેટાબેઝ લોડ વર્ટિકલ સ્પાઇકમાંથી સીધી રેખામાં આવી જાય છે.

Probabilistic Early Expiration

ક્યારેક તમે સ્ટેમ્પિડને મેનેજ કરવાને બદલે તેને સંપૂર્ણપણે ટાળવા માંગો છો. અહીં probabilistic early expiration આવે છે, જે XFetch જેવા અલ્ગોરિધમ્સ દ્વારા અમલમાં મૂકવામાં આવે છે.

હાર્ડ એક્સપાયરેશન સમયને બદલે, દરેક કેશ કરેલી વેલ્યુ સોફ્ટ એક્સપાયરેશન વિન્ડો ધરાવે છે. જ્યારે વિનંતી આવે છે, ત્યારે એપ્લિકેશન એક રેન્ડમ નંબર જનરેટ કરે છે અને એક સાદો પ્રોબેબિલિટી ચેક લાગુ કરે છે. જો ડાઇસ રોલ (dice roll) 'હા' કહે છે, તો તે એક જ વિનંતી કેશને વહેલી રિફ્રેશ કરે છે. જો નહીં, તો વિનંતી થોડી જૂની (stale) વેલ્યુ આપે છે.

કારણ કે દરેક વિનંતી પોતાનો ડાઇસ રોલ કરે છે, રિફ્રેશ સોફ્ટ વિન્ડોમાં ફેલાઈ જાય છે. એક ક્લાયન્ટ હાર્ડ એક્સપાયરેશનના ચાલીસ સેકન્ડ પહેલા રિફ્રેશ કરી શકે છે, બીજો બાર સેકન્ડમાં, અને મોટાભાગના અન્ય લોકો બિલકુલ નહીં. કામ એક સિંક્રનાઇઝ્ડ સ્પાઇકમાંથી હળવા...