Серверүүдийг царцаасан дутуу swap файл
9-р сарын 24-нд үйлдвэрлэлийн нэг сервер хариулахаа больсон. Load balancer түүнийг эрүүл бус гэж тэмдэглэсэн, мөн бидний алсын командын хэрэгсэл түүнд хүрч чадаагүй — гэхдээ юу ч унаагүй, санах ой хэт их ашигласны улмаас ямар ч процесс устгагдаагүй. Сервер thrashing хийж байсан: swap орон зайгүй, контейнерүүдэд машины байгаа санахаас илүү санах ой ашиглахыг зөвшөөрсөн тул Linux ажиллахад хэрэгтэй файлуудаа хуудас кэшээс хасаж, дахин уншиж байв, бараг ямар ч ахиц гаргахгүйгээр. Сервер бүр дээр 2 ГБ swap файл нэмснээр асуудал засагдсан. Илүү сонирхолтой сургамж нь эрүүл байдлын шалгалтын тухай байсан.
«Царцсан» гэдэг нь ямар харагддаг вэ
- Load balancer-ийн эрүүл байдлын шалгалт тэр серверт хугацаа дууссан.
- AWS Systems Manager-ээр явуулсан командууд «Pending» хэвээр байж, хэзээ ч ажилласангүй.
- Логт out-of-memory устгал байхгүй. Ямар ч процесс үхээгүй.
Нэг долоо хоногийн өмнө бид үйлдвэрлэлийг 2 ГБ санахтай жижиг ARM серверүүд рүү шилжүүлсэн байсан. Staging сервер — бүр жижиг — deploy-ийн үед контейнерийн image задлах явцад ижил байдлаар царцсан байв.
Яагаад санахын алдаа гараагүй юм бэ?
Linux процессыг зөвхөн нөхөж чадах санах ой нь дууссан үед л устгадаг. Тэр цэгээс өмнө тэр санахыг хуудас кэш-ээс авдаг — файлуудын RAM дэх хуулбарууд, ажиллаж буй програм бүрийн код орно.
Бидний серверүүд дээр контейнерүүдийн санахын хязгаарууд нийлбэрээрээ ойролцоогоор 3.3 ГБ, харин машин ойролцоогоор 1.8 ГБ ашиглах боломжтой байв. Ихэвчлэн тэд бүгд хязгаараа нэг зэрэг ашигладаггүй. Ашиглах үед kernel ажиллаж буй кодыг кэшээс гаргаж байгаад, тэр код дахин ажиллах мөчид дискнээс буцааж уншдаг байсан. Тэр мөчлөг — thrashing — машиныг бараг бүрэн хариулахгүй болгож болно, гэхдээ техникийн утгаар санах ой дуусдаггүй. Тиймээс юу ч устгагдахгүй, юу ч сэргэхгүй.
Swap-гүй үед kernel хэрэглэгдээгүй санахаа хаашаа байрлуулахаа мэддэггүй, тиймээс санахыг кэшээс авахаас өөр аргагүй.
Засвар
Серверийн bootstrap скрипт одоо сервер асах эсвэл засагдах бүрт 2 ГБ swap файл үүсгэж, бага swappiness (10) тохируулдаг. Бага swappiness гэдэг нь kernel ажлын санахыг RAM-д байлгахыг хүсдэг хэвээр, харин бараг хэрэглэгддэггүй хуудсууд дискэнд шилжиж болно, ингэснээр програмын кодыг кэшээс хөөхгүй. Бид үүнийг үйлдвэрлэлийн хоёр сервер болон staging дээр шууд хэрэгжүүлсэн, мөн deploy pipeline үйлдвэрлэлийн deploy бүрт bootstrap скриптийг дахин нийтэлдэг тул солигдсон сервер ч авна.
Илүү их түгшээсэн зүйл: эрүүл бус сервер үлдсэн
Бидний серверийн бүлэг EC2 эрүүл байдлын шалгалт ашигладаг байсан — «машин ажиллаж байна уу?» — load balancer-ийн эрүүл байдлын шалгалт биш — «хүсэлтэд хариулж байна уу?». Тиймээс load balancer хаясан сервер бүлгийн хувьд эрүүл байв. Түүнийг хэзээ ч солихгүй. Үйлдвэрлэл нөгөө сервер нь хэн нэгэн анзаарч, дахин эхлүүлэх хүртэл нэг сервер дээр чимээгүйхэн ажиллана.
Бүлгийг load balancer-ийн эрүүл байдлын шалгалт руу шилжүүлэх нь тодорхой засвар мэт боловч бидний хувьд амар биш: deploy-ийн үед серверүүд санаатайгаар эрүүл байдлын endpoint-доо алдаа буцаадаг, ингэснээр balancer тэднийг хөдөлгөөнөөс гаргана (бид deploy-уудыг нуля 502 болгосон нь гэж үзнэ үү). Тэр дохиогоор сервер солидог бүлэг deploy-ийн дундуур бүх серверийг солих байсан.
Тиймээс одоохондоо deploy-ийн шалгах хуудсандаа алхам нэмсэн: deploy бүрийн дараа deploy job-ийн амжилтыг шалгахаас гадна load balancer дээр бүх target-ийн эрүүл байдлыг шалга. Серверт командууд «Pending» хэвээр байвал тэр thrashing хийж байна — дахин эхлүүл; тэр аль хэдийн эргэлтээс гарсан байна.
Бидний авсан дүгнэлт
- «Унахгүй байгаа» нь «эрүүл» биш. Thrashing нь ямар ч алдаа үүсгэдэггүй, зөвхөн машин хариулахаа больтол хэт удаашралтай болгодог.
- Жижиг сервер swap хэрэгтэй. Бага ч гэсэн, бага swappiness-тай бол kernel хүйтэн санахаа байрлуулах газартай болно.
- Санахын хязгаарууд машинаас их нийлбэртэй бол — энэ бол бооцоо. Заримдаа та хожихгүй. Хэзээ бооцоо тавьснаа мэдэж бай.
- Автомат масштабчлал аль эрүүл байдлын шалгалтыг итгэдгээ мэд. Зөвхөн «VM асаалттай юу?» гэж асуудаг шалгалт үйл ажиллагаагүй болсон серверийг солихгүй.