Redis-ը VPN-ի միջոցով դանդաղ է թվում. կրճատենք շրջապտույտները մեկ հարցումով
VPN-ը հեռավոր Redis կանչը տեղական չի դարձնում. Պլանավորեք շրջապտույտները մեկ հարցումով, վերաօգտագործեք միացումները և պահեք խողովակաշարերը հեռու գործարքներից։
Էջը, որը տեղական Redis-ի դեմ պատասխանում է 200 ms-ում, չորս վայրկյան է պահանջում, հենց որ հաճախորդը հայտնվում է VPN-ի հետևում, մինչդեռ սերվերի հաշվիչները մնում են անգործ։ Դանդաղ մատյանը ոչինչ չի ցուցադրում մեկ միլիվայրկյանից բարձր, CPU-ի գրաֆիկը հարթ է, և ինստանսը առանց բողոքների սպասարկում է այլ հաճախորդների։ Փոխվել է հեռավորությունը, և հեռավորությունը բազմապատկում է այն, թե քանի անգամ ձեր կոդը կանգ է առնում ու սպասում։ Անցեք հարցման ուղին հաճախորդից դուրս, և լուծումը գրեթե միշտ ավելի քիչ հաջորդական սպասումներ են, այլ ոչ ավելի արագ սերվեր։
Սկսեք հաճախորդից, ոչ թե սերվերի ցուցիչներից
Դիտեք հաճախորդի գործընթացը առաջին հրամանից մինչև վերջինը։ Եթե հետքը ցույց է տալիս պատասխան, դադար, ապա հաջորդ հրաման, դուք վճարում եք ամբողջական շրջապտույտ յուրաքանչյուր հրամանի համար, և սերվերի կարգաբերման ոչ մի չափաբաժին դա չի փոխի։ Դանդաղ մատյանը այստեղ սխալ գործիք է, որովհետև այն արձանագրում է կատարման ժամանակը և դիտավորյալ բացառում հաղորդակցության I/O-ն։ Մաքուր դանդաղ մատյանը դանդաղ վերջնակետի կողքին շրջապտույտի խնդրի ստորագրությունն է։
Չափեք ուղին ինքնին, նախքան կոդին դիպչելը։ redis-cli -h redis.example.internal --latency-ը ուղարկում է կրկնվող PING-ներ և տպում միջին հարցման և պատասխանի ժամանակը, որը ձեր արժեքն է մեկ փոխանակման համար։ Բազմապատկեք այն մեկ օգտվողի գործողության մեջ հաջորդական հրամանների քանակով և կստանաք վերջնակետի ստորին սահմանը։
Հաշվեք, թե իրականում քանի շրջապտույտ է պետք մեկ օգտվողի գործողությանը
Վերցրեք մեկ վերջնակետ և հերթով գրեք յուրաքանչյուր Redis կանչը, ներառյալ նրանք, որոնք թաքնված են ORM-ի, սեանսի միջնաշերտի կամ ֆունկցիայի դրոշի որոնման ներսում։ Մեծ մասը դանդաղ վերջնակետերի պարզվում է, որ քսան կամ երեսուն կանչ են անում այնտեղ, որտեղ երեքը կբավականացներ, և թաքնվածներն սովորաբար մեծամասնությունն են կազմում։
Կախվածությունների շղթան հնարավոր չէ ծալել. եթե երկրորդ հրամանին պետք է առաջինի վերադարձրած բանալին, սպասումն իրական է, և միակ տարբերակները տվյալների այլ մոդելն ու սերվերի կողմի գործողությունն են, որն ամբողջ քայլն արտահայտում է միաժամանակ։ Անկախ ընթերցումները այլ դեպք են, որովհետև ոչինչ չի ստիպում սպասել առաջին պատասխանին նախքան երկրորդը ուղարկելը։ Նշեք յուրաքանչյուր կանչը որպես կախյալ կամ անկախ նախքան որևէ բան փոխելը, և լուծման ձևը կդառնա ակնհայտ։
Կարևոր թիվը հաջորդական սպասումներն են, ոչ թե ընդհանուր հրամանները։ Մեկ խմբաքանակում երեսուն հրամանը դեռ արժե մեկ սպասում։
Խմբավորեք միայն այն հրամանները, որոնք միմյանցից կախված չեն
Խողովակաշարը հերթագրում է անկախ հրամանները և հավաքում պատասխանները ըստ հերթականության՝ N սպասումը դարձնելով մեկ։ Հաճախորդների մեծ մասը դա առաջարկում է որպես բլոկ, հետկանչ կամ համատեքստի կառավարիչ, այլ ոչ առանձին միացման եղանակ, ուստի ստուգեք ձեր տեղադրված տարբերակի API-ն։ Շահույթը մեծանում է շրջապտույտի ժամանակի հետ, և հենց դա է պատճառը, որ այն կարևոր է VPN-ում և գրեթե չի նկատվում localhost-ում։
import redis
r = redis.Redis(host="redis.example.internal", port=6379, socket_timeout=2)
pipe = r.pipeline(transaction=False)
for key in ("user:1001", "user:1002", "user:1003"):
pipe.get(key)
print(pipe.execute())
Փոխանցեք transaction=False, երբ ուզում եք միայն խմբավորում։ Լռելյայն դեպքում հաճախորդը խմբաքանակը փաթաթում է MULTI և EXEC-ի մեջ, ինչը դարձնում է այն ատոմային և փոխում է, թե ինչ կարող են տեսնել այլ հաճախորդներ ընթացքի մեջ։ Ատոմայնությունը ճշտության որոշում է, ոչ թե արտադրողականության կոճակ, և խողովակաշարը գործարք չէ միայն այն պատճառով, որ երկուսն էլ նվազեցնում են շրջապտույտները։
Կարդացեք յուրաքանչյուր պատասխան, ոչ միայն խմբաքանակի ուղարկումը։ Հերթագրված հրամանը կարող է սխալ վերադարձնել, մինչ խմբաքանակն ամբողջությամբ ավարտվում է, և պատասխանների ցանկը դեն նետող հաճախորդը ձախողված գրառումը դարձնում է լուռ։ Համեմատեք պատասխանների ցանկի երկարությունը հերթագրած հրամանների քանակի հետ։
Պահեք միացումը կենդանի գործողությունների միջև
Յուրաքանչյուր նոր միացում վճարում է անվան լուծման, TCP ձեռքսեղմման, TLS ձեռքսեղմման և AUTH-ի համար, և VPN-ի վրայով դրանցից յուրաքանչյուրը շրջապտույտ է, որը չեք կարող խմբավորել։ Ստեղծեք հաճախորդը մեկ անգամ յուրաքանչյուր գործընթացի համար և վերաօգտագործեք, կամ օգտագործեք ձեր գրադարանի տրամադրած սահմանափակ չափի լողավազանը։ Յուրաքանչյուր հարցման համար վերամիացումը այս ախտանշի երկրորդ ամենատարածված պատճառն է հրամանի համար սպասումներից հետո։
Պահեք մասնավոր հոսթի անունը կոնֆիգուրացիայում, այլ ոչ բառացի հասցե։ Սերտիֆիկատի վավերացումը և ծառայության ինքնությունը դեռ գործում են մասնավոր ցանցում, և IP-ի ամրագրումը կոտրվում է այն պահին, երբ մատակարարը վերահամարակալում է ենթացանցը։ Եթե լուծումը դանդաղ մասն է, ուղղեք լուծիչի ուղին, այլ ոչ միացման տողը։
Սահմանեք բացահայտ socket-ի ժամանակի սահման, որպեսզի խցանված թունելը արագ ձախողվի՝ աշխատողին կախելու փոխարեն։ Այնուհետև հաստատեք, որ լողավազանն իսկապես վերաօգտագործվում է՝ հաճախորդում միացումների ստեղծումը գրանցելով։
Չափեք խմբաքանակի չափը նախքան այն հիշողության խնդիր դառնալը
Redis-ը պահում է հերթագրված պատասխանները խմբաքանակի ողջ ընթացքում, իսկ հաճախորդը դրանից հետո պահում է վերլուծված արդյունքը։ Տասը հազար մեծ արժեքներից բաղկացած խողովակաշարը ցանցային սպասումները փոխանակում է հիշողության թռիչքների և երկու ծայրերում երկար դադարների հետ։
Ընտրեք խմբաքանակի չափը ըստ պատասխանի ծավալի, այլ ոչ հրամանների քանակի։ Մեկ խմբաքանակում մի քանի հարյուր փոքր հրաման սովորաբար հարմարավետ է, մինչդեռ հարյուր բազմակիլոբայթանոց բեռը՝ ոչ։ Բաժանեք ըստ բայթերի և ըստ քանակի, և պահեք յուրաքանչյուր խմբաքանակ վերջնակետի իրական ուշացման բյուջեի սահմաններում։
Փոփոխությունից հետո չափեք ծայրից ծայր. redis-cli -h redis.example.internal --latency-history-ը ցույց է տալիս՝ արդյոք ուղին ինքնին կայուն է, իսկ ձեր սեփական հարցումների ժամանակաչափը՝ արդյոք վերջնակետը բարելավվել է։ Եթե վերջնակետը դեռ դանդաղ է, մինչ ուշացումների պատմությունը հարթ է, մնացած արժեքը սերվերի կողմի աշխատանքն է կամ ձեր սեփական սերիալիզացիան, և հաջորդ քայլը մշակողի պրոֆիլն է, այլ ոչ ևս մեկ խմբավորման փոփոխություն։