gRPCda load balancing

gRPCda load balancing

gRPCda load balancing

Kubernetes muhitida mavjud bo’lgan load balancer gRPC requestlarni turli podlarga to’g’ridan to’g’ri bo’lib bera olmaydi

load — bosim
connection — bog’lanish

Hammasi Qwatt’ning foydalanuvchilari ko’paygani munosabati bilan boshlandi.

Katta load tushadigan bir microservice nodejs’da yozilgan edi. Oxirgi paytlar har kuni peak time(eng ko’p foydalanuvchi bo’ladigan payt)’da o’sha service’ga bosim ko’payib hamma so’rovlarni ham qabul qila olmay qoldi, va business shu tufayli juda ko’p pul yuqotdi. Serverlarni kuchaytirishimiz foyda bermadi va serverning bosimini kuzatganda ko’p load tushadigan microservice ko’pi bilan bir dona CPU core ishlatayabdi, sababi nodejs single thread‘da ishlaydi.

Biz yechim sifatida kubernetes pod’larni ko’paytirdik lekin u foyda bermadi. Chunki biz microservice’lar o’rtasidagi aloqalarni gRPC API orqali amalga oshiramiz.

Mana endi xaqiqiy mavzu boshlandi

Kubernetes qanday nagruzgani balance(load balance) qiladi?

Maqolaning davomini yaxshi tushunish uchun birinchi shuni qisqacha bildirib ketishni lozim topdim.

Load balancer Kubernetes Endpoints API yordamida pod mavjudligini kuzatib boradi. Muayyan Kubernetes service uchun so’rovni qabul qilganda, Kubernetes yuk balanslagichi(load balanceri) so’rovni service uchun tegishli Kubernetes pod’lari orasida bo’lib beradi.

Bu quydagi rasmda kubernetes service’ga kelgan request(so’rov) podlar o’rtasida teng taqsimlanadi. Va bu bosim taqsimlash har bir request uchun amalga oshiriladi va bu jarayon OSI modelning 4-qavat(layer)i da yani transport qatlamida amalga oshiriladi. Va bu load balancing REST api’lar bilan juda yaxshi ishlaydi, chunki har bir request transportation layer orqali serverga yetib boradi.

grpcda load balancing 665279c105991

Nega kubernetes gRPC so’rovlarni load balance qila olmaydi?

Bu savolga javob berishdan oldin gRPC’ning ishlash principle’ni ko’rib chiqsak. gRPC http 2.0 protocolidan foydlanadi va http 2.0 multiplexing(bir dona TCP connection orqali hamma request response’larni o’tkaza oladi). Savol berishingiz mumkin http 1.1 ham TCP connectionni uzoq vaqt saqlab qoladiku deb, ha shunday lekin http 1.1 bir dona TCP connection orqali bir vaqtda bir nechta request response almasha olmaydi.

Shuday qilib gRPC server’ga birinchi marta bog’langanda bir dona TCP bog’lanish ochadi (bu jarayon transportation layerda bo’ladi) va har doim shu bog’lanish orqali (xuddi bitta session orqali bo’lgandek) hamma ma’lumotlarni almashadi (bu jarayon OSI 5/6 layer’larda bo’ladi). Bir marta bog’lanish qilganimiz uchun bu faqat bir dona kubernetes pod bilan amalga oshiriladi va qolgan pod’lar bekor qolib ketadi. Natijada hamma bosim bir dona podga tushadi.

Muommoni topdik, endi buni qanday yechamiz?

Birinchi yechim proxy laod balancer ko’tarish keldi, lekin bu bizga qimmatga tushar ekan chunki har bir service uchun alohida proxy ko’tarishga to’g’ri keladi.

Ikkinchi yechim gRPC TCP connection’ning umrini qisqaritib qo’yish. Yani gRPC serverdan connection umrini 10 sekund qilib qo’ysak har 10s sekundda podlardagi bosim almashib turadi. Yani, 10 secunda gRPC server connection’ni tugatib yuboradi. Natijada client side(so’rov yuboradigan taraf) yangi connection ochishga majbur bo’ladi va bu kubernetes load balancer sharofati bilan boshqa podga ketadi.

Bu yechim gRPC server create qilayotganda quydagi sozlamani optionsga qo’yish orqali bajarilishi mumkin.

// go code misoli
  grpc.KeepaliveParams(keepalive.ServerParameters{
   MaxConnectionAge:      time.Second * 30, // THIS one does the trick
   MaxConnectionAgeGrace: time.Second * 10,
  }),

Ustunliklari:
— Faqat server tarafda sozlansa bo’ldi.
— Har bir request uchun alohida connection ochish shart emas.

Kamchiliklari:
— Bosimni to’liq to’g’ri taqsimlay olmaydi chunki ma’lum bir vaqtda connection qayta qilinadi.
— Bu xususiyatni hamma til ham support qilmaydi. Hozircha faqat Go, C, Java. Oxirgi yangilanish: 2017–01–27.

Biz, Udevs kompaniyasida bu yechimni qabul qilmadik chunki eng assosiy load balancer bizga aynanan NodeJs’da yozilgan servisimizga kerak edi. Afsuski bu xususiyatni Nodejs support qilmaydi.

Uchinchi va biz tanlagan yechim bu gRPC connection pool’dan foydalanish. Bu jarayon gRPC client tomonidan amalga oshiriladi va buni qisqacha tarifi ha bir request uchun pool’dan connection oladi va pool o’rnini yangi connection ochib to’ldirib qo’yadi. Har bir connection qayta ochilganligi uchun u birinchi marta OSI modelining 4-qavatidan o’tadi va kubernetes tomonidan load balancing amalga oshiriladi.

Ustunliklari:
— Har bir request nagruskasi boshqariladi.
— microservice’ning pod(replica)’lar soni o’zgarsa requestlar va load balancing shunga moslashib ketadi.

Kamchiliklari:
— Har bir request uchun alohida connection ochilishi.
— Client tarafning kodi sal qiyinroq bo’ladi.

Bu yechmni amalga oshirish bo’yicha detalni maqola -> Link

Albatta bundan ham yaxshiroq bor va bu gRPC’ning o’zining load balancer’i. Buni amalda ishlatib ko’rsam albatta maqola yozaman.

Oxirigacha o’qiganingiz uchun rahmat. Agar foydali bo’lgan bo’lsa men xursandman. O’zbek tilida shunaqa maqolalarni o’qish uchun follow qilib qo’yishni unutmang.

Tizimlash
gRPCda load balancing