Kaspi Жұма бір де бір даунсекундсыз: GKE және Cloud Spanner-ге көшу арқылы e-commerce-тегі х50 трафиктен қалай аман өттік
Қазақстандық сауда және цифрлық коммерция күнтізбесінде Жаңа жыл мен Наурыздан да маңыздырақ, аса жауапты кезең бар. Бұл — Kaspi Жұма: бейсенбіден жұмаға қараған түн ортасында еліміздің миллиондаған тұрғындары Алматы мен Астанадан бастап Шымкент пен Ақтауға дейін смартфондарын қолдарына алып, каталогтарды үздіксіз жаңарта бастайтын ұлттық шопинг мерекесі. Осы сәтте e-commerce нағыз қанды шайқас алаңына айналады: 0-0-24 бөліп төлеу науқаны кез келген тосқауылдарды бұзып өтеді, пайдаланушылар трафигі тура 180 секундтың ішінде 30–50 есеге шарықтайды, ал инженерлік бөлмелерде нағыз техногендік апат пен дағдарыс басталады.
Біздің клиентіміз — тұрмыстық техника, электроника және үй тауарларының ірі мультикатегориялық қазақстандық маркетплейсі үшін өткен жылғы жаппай жеңілдік нағыз сұмдыққа айналды. Сол түнгі оқиғалар ТЖМ жедел хабарламалары мен апаттық сводкалары сияқты өрбіді:
- 00:01:15 — Тұтынушыларға Kaspi қосымшасынан алғашқы пуш-хабарламалар жетті, API шлюздеріндегі трафик бір сәтте 2 000-нан 65 000 RPS-ке (секундына түскен сұраныс) дейін көтерілді.
- 00:02:40 — PgBouncer қосылымдар пулы максималды шегіне жетіп толып кетті, барлық микросервистер үшін қосылымдар тапшылығы (Connection Starvation) басталды.
- 00:04:10 — Танымал теледидарлар мен смартфондардың қалдықтары жазылған жолдардағы каскадты эксклюзивті құлыптаулар (Row-Level Locking) салдарынан негізгі PostgreSQL 14 дерекқоры мүлдем тұрып қалды.
- 00:07:30 — Веб-серверлер
504 Gateway Timeoutқателеріне батты, Ingress-контроллерлер 502 қателерін жаудырды, ал мобильді қосымша жүз мыңдаған сатып алушыларды өлі ақ экранмен қарсы алды. - 00:15:00 — Репликаларды қайта іске қосу және Redis кэшін күштеп тазалау әрекеті Thundering Herd (гүрілдеген табын эффектісі) апатына әкеліп, инфрақұрылымның қалған бөлігін біржола құлатты.
Сол түнгі шығын: 4.5 сағаттық толық тоқтап қалу (даунтайм), 180 миллион теңгеден астам жіберіп алған таза сауда түсімі, әлеуметтік желілердегі мыңдаған ашулы пікірлер және жүйкесі тозған инженерлер ұжымы. Сол кезде компания басшылығы OZAT зертханасына келіп, нақты әскери талап қойды: «Келесі науқанға дейін жүйе бір де бір миллисекундтық кідіріссіз, кезектерсіз және бір де бір төлемді жоғалтпай кез келген ең жоғары жүктемені көтере алатын болуы керек».
Бұл мақалада біз Google Cloud Platform-ға (GCP) мінсіз және сенімді миграцияны қалай жобалағанымызды, монолитті KEDA арқылы автоматты түрде кеңейетін Google Kubernetes Engine (GKE) Autopilot кластеріне қалай көшіргенімізді және х50 трафик кезінде ACID-транзакциялық есепке алудың жалғыз құтқарушысы неге Google Cloud Spanner болғанын барлық техникалық қыр-сырымен ашық айтып береміз.
Апаттың анатомиясы: Неліктен ескі жүйе сөзсіз өлімге сотталды?
Жаңа бұлттық архитектураны құрмас бұрын, бұрынғы дәстүрлі жүйенің неліктен сәтсіздікке ұшырағанын терең талдап алу қажет. Біздің араласуымызға дейін инфрақұрылым классикалық корпоративтік жүйе түрінде болатын:
- Есептеу қабаты: жергілікті деректер орталығында 16 қуатты виртуалды машинада (әрқайсысы 32 vCPU, 128 GB RAM) жұмыс істейтін PHP/Go монолиттік қосымшасы.
- Дерекқор қабаты: PgBouncer пулері арқылы басқарылатын PostgreSQL 14 Enterprise (Master + NVMe дискілеріндегі 2 синхронды реплика).
- Кезектер жүйесі: 3 нодалық RabbitMQ кластері.
- Кэш қабаты: Сессиялар мен тауарлар каталогына арналған 6 нодалық Redis Cluster.
Қалыпты жұмыс күндерінде бұл жүйе 2 500 – 3 000 RPS жүктемесін қиындықсыз көтеретін. Дерекқор процессорлары 30%-дан артық жүктелмейтін, ал жауап беру уақыты (Latency P95) 45 мс деңгейінде болатын. Бірақ ұлттық жеңілдіктер науқаны кезінде жүктеме біртіндеп емес, алғашқы үш минуттың ішінде 95 000 RPS-ке жететін алапат цунамимен келеді.
1. Ыстық жолды құлыптау трагедиясы (Hotspot Row Locking)
Сатылым кезінде сұраныс каталог бойынша біркелкі таралмайды. Алғашқы 20 минуттағы барлық тапсырыстардың 70%-ы ең үлкен жеңілдігі бар бар болғаны 15–20 тауарға (айфондар, теледидарлар, тоңазытқыштар) түседі. 6 000 тұтынушы бір мезетте бір ғана Samsung теледидарына «Сатып алу» түймесін басқанда, қосымша келесідей 6 000 параллель транзакция ашады:
BEGIN TRANSACTION;
SELECT available_stock FROM inventory WHERE sku_id = 'SAMSUNG-OLED-65' FOR UPDATE;
-- Қалдықты тексеру және азайту
UPDATE inventory
SET available_stock = available_stock - 1,
reserved_stock = reserved_stock + 1
WHERE sku_id = 'SAMSUNG-OLED-65';
COMMIT;PostgreSQL-де бұл жол лезде RowExclusiveLock арқылы құлыпталады. Бірінші транзакция орындалады, ал қалған 5 999 транзакция кезекке тұрады. Құлыптау уақыты геометриялық прогрессиямен өседі, PgBouncer қосылымдары санаулы секундта бітеді, жаңа HTTP-сұраныстар қабылданбайды және бүкіл жүйе тұрып қалады. Қалдықтарды Redis-ке салу тек тапсырысты мастер-базаға түпкілікті жазу кезеңіне дейін ғана көмектеседі.
2. Репликацияның кешігуі және фантомдық қалдықтар
Мастер-ноданы босату үшін каталогты қарау және іздеу сұраныстары Read-репликаларға бағытталды. Бірақ мастерге түскен алапат транзакциялар ағынынан WAL-журналы минутына гигабайттап өсе бастады. Репликация 25–45 секундқа кешікті. Қолданушы репликадан кір жуғыш машинаның бар екенін көріп, рәсімдеуге өтетін, ал соңғы қадамда «Тауар таусылды» деген қате алатын. Ызаланған клиенттер бетті қайта-қайта жаңартып, сатып алу түймесін баса бергендіктен, жойқын Retry Storm (қайталанатын сұраныстар дауылы) туындады.
3. Kubernetes-тегі стандартты HPA-ның соқырлығы
Kubernetes-тегі стандартты Horizontal Pod Autoscaler әдепкі бойынша CPU және RAM жүктемесіне қарайды. Сатылымдарда бұл сәтсіздікке кепілдік береді: CPU 80%-ға жеткенше, HPA әрекет еткенше (15–30 секунд) және бұлттық провайдер жаңа нодаларды қосқанша (2–4 минут), жүйе жүз мыңдаған 502/504 қателерін таратып үлгереді. Жүйе ресурстар қызып кеткеннен кейін емес, кіріс оқиғалары бойынша алдын ала реактивті түрде масштабталуы тиіс.
Біз өзіміздің Document AI арқылы бизнес-процестерді автоматтандыру туралы материалымызда атап өткеніміздей, ескі монолиттік әдістерді жаңа ауқымдарға бейімдеу мүмкін емес. Түбегейлі жаңа архитектуралық серпіліс қажет болды.
Архитектуралық серпіліс: GKE Autopilot + Cloud Spanner
Біз Google Cloud Platform-ның ең үздік үлестірілген шешімдеріне негізделген жаңа мақсатты жүйені жобаладық:
- Google Kubernetes Engine (GKE) Autopilot: Google нодаларды, қауіпсіздікті және eBPF желілік стекін толық басқаратын серверсіз басқарылатын Kubernetes кластері.
- Google Cloud Spanner: NoSQL-дің шексіз көлденең масштабталуын және классикалық SQL-дің қатаң ACID кепілдіктерін біріктіретін, уақытты TrueTime API арқылы синхрондайтын ғаламдық үлестірілген СУБД.
- KEDA (Kubernetes Event-driven Autoscaling) + Cloud Pub/Sub: хабарламалар кезектерінің тереңдігіне сүйене отырып, микросервистерді санаулы секундтарда предиктивті түрде масштабтау.
- Google Cloud Armor + Cloud CDN: боттарды сүзу, DDoS шабуылдарынан қорғану және Google-дың Қазақстандағы Edge PoP желілік түйіндерінде статиканы кэштеу.
Неліктен NoSQL немесе шардингтелген Postgres емес, Cloud Spanner?
Highload жүйелерді жобалау кезінде NoSQL дерекқорын (MongoDB, Cassandra, DynamoDB) таңдау азғыруы жиі кездеседі. Алайда ритейл және банктік бөліп төлеу жағдайында бұл қаржылық тұңғиыққа апарады. NoSQL масштаб үшін қатаң консистенттілікті құрбан етеді (CAP теоремасы / BASE моделі). Егер қоймада 1 ғана iPhone қалып, eventual consistency салдарынан оны екі адамға бірдей сатып жіберсеңіз, Kaspi Pay арқылы екеуінен де ақша алынып, үлкен дау туындайды.
Екінші жағынан, PostgreSQL-ді қолмен шардингтеу (Citus / Vitess) — өте күрделі инженерлік ауыртпалық: шардар арасындағы транзакциялардың жоғалуы, JOIN сұраныстарының мүмкін еместігі және сатылым кезінде жаңа шардтарды қосудың қиындығы.
Cloud Spanner ACID пен көлденең масштабтау арасындағы қайшылықты жойды. TrueTime API кешенінің (Google дата-орталықтарындағы атомдық сағаттар мен GPS қабылдағыштар) арқасында Spanner мыналарды қамтамасыз етеді:
- External Consistency (сыртқы қатаң сәйкестік): егер Т2 транзакциясы Т1 аяқталғаннан кейін басталса, Т2 ғаламдық ауқымда Т1-дің барлық өзгерістерін көреді.
- Таблеттерді автоматты түрде бөлу (Splits): Spanner кестелерді көлемі 4 GB болатын таблеттерге бөліп, трафик өскен кезде оларды ондаған физикалық серверлерге автоматты түрде таратады.
- Нөлдік үзіліспен өлшемін өзгерту: қуаттылықты 5-тен 100 SPU-ге (Spanner Processing Units) дейін арттыру дерекқорды бұғаттамай, бір ғана API шақыруымен 30 секундта орындалады.
Cloud Spanner схемасын жобалау: Hotspotting-тен құтылу
Spanner-ге көшу кезіндегі ең басты қателік — PostgreSQL схемасын сол күйінде көшіру. Spanner-де автоинкременттік ID (1, 2, 3...) немесе бастапқы кілттің басында реттік уақыт белгілерін пайдалануға қатаң тыйым салынады! Әйтпесе, барлық жазулар бір ғана шеткі таблетке түсіп, жүйені тоқтатып тастайды (Hotspotting).
Біз UUIDv4 генерациясын қолдандық және Spanner-дің ең мықты мүмкіндігі — Interleaved Tables (кірістірілген кестелер) тұжырымдамасын енгіздік. Кірістірілген кестелер тапсырыс позицияларын физикалық түрде дискіде тапсырыс және тұтынушы жолымен бір блокта сақтайды:
-- DDL Схема Cloud Spanner для e-commerce с защитой от Hotspotting (Interleaved таблицы)
CREATE TABLE Customers (
CustomerId STRING(36) NOT NULL,
FullName STRING(255) NOT NULL,
PhoneNumber STRING(32) NOT NULL,
CreatedAt TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
) PRIMARY KEY (CustomerId);
CREATE TABLE Orders (
CustomerId STRING(36) NOT NULL,
OrderId STRING(36) NOT NULL,
OrderStatus STRING(32) NOT NULL,
TotalAmount NUMERIC NOT NULL,
OrderTimestamp TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
) PRIMARY KEY (CustomerId, OrderId),
INTERLEAVE IN PARENT Customers ON DELETE CASCADE;
CREATE TABLE OrderItems (
CustomerId STRING(36) NOT NULL,
OrderId STRING(36) NOT NULL,
ItemId STRING(36) NOT NULL,
SkuId STRING(64) NOT NULL,
Quantity INT64 NOT NULL,
UnitPrice NUMERIC NOT NULL,
) PRIMARY KEY (CustomerId, OrderId, ItemId),
INTERLEAVE IN PARENT Orders ON DELETE CASCADE;
CREATE INDEX OrdersByStatusTimestamp ON Orders(OrderStatus, OrderTimestamp DESC);GitHub-тағы кодты көру (OZAT-kz)
Бұл схема толық тапсырысты (тұтынушы, тапсырыс деректері, 20 тауарлық позиция) желілік артық RPC-шақыруларсыз дигіден 1–3 миллисекундта оқуға кепілдік берді!
Реактивті чекаут: KEDA және Cloud Pub/Sub арқылы асинхронды архитектура
Жоғары жүктеме кезінде фронтенд ешқашан бұғатталмауы үшін біз тапсырыс беру процесін Event-Driven бағытына көшірдік:
- Сатып алушы мобильді қосымшада «Тапсырыс беру» түймесін басады.
- Сұранысты Cloud Run-дағы жеңіл API Gateway қабылдап, JWT токенін 8 мс ішінде тексереді.
- Тапсырыс оқиғасы лезде Google Cloud Pub/Sub кезегіне жіберіледі (секундына 1 000 000-нан астам хабарлама өткізу қабілеті бар).
- Клиент лезде тапсырыс нөмірі мен WebSocket арнасы бар HTTP
202 Acceptedжауабын алады. - GKE кластерінің ішіндегі
checkout-serviceподтары хабарламаларды оқып, Cloud Spanner-де транзакцияларды тіркейді.
Воркерлердің санын басқару үшін біз Pub/Sub кезек өлшемін бақылайтын KEDA конфигурациясын баптадық:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: checkout-service-scaler
namespace: ecommerce-prod
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: checkout-service
minReplicaCount: 20
maxReplicaCount: 400
cooldownPeriod: 60
pollingInterval: 5
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 10
- type: Pods
value: 50
periodSeconds: 10
selectPolicy: Max
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
triggers:
- type: gcp-pubsub
metadata:
subscriptionName: projects/ozat-ecommerce/subscriptions/orders-queue-sub
subscriptionSize: "50"GitHub-тағы кодты көру (OZAT-kz)
Түн ортасында кезекке 120 000 хабарлама түскен кезде, KEDA лезде деплоймент репликаларын 20-дан 400 подқа дейін көбейтті. Біздің микросервистік модульдеріміздегі оңтайландырулардың арқасында әрбір жаңа под жасалғаннан кейін тура 1.6 секундта транзакцияларды қабылдауға дайын болды.
Миграция стратегиясы: Dual-Write және Shadow Traffic
Жобаның ең жауапты кезеңі — сауданы тоқтатпай терабайттаған деректерді қалай көшіру керек? Біз 4 кезеңді стратегияны іске асырдық:
- Debezium арқылы CDC: PostgreSQL WAL-журналынан өзгерістерді ұстап, Cloud Spanner-ге нақты уақыт режимінде ағынды репликациялау үшін Kafka Connect орнаттық. Бұл жүйедегі деректердің үзіліссіз синхрондалуын қамтамасыз етті.
- Dual-Write (Қос жазу): сервистік деңгейде екі дерекқорға бір уақытта жазуды қостық. Ескі жүйе мен жаңа жүйе қатар жазылып, сәйкессіздіктер толығымен жойылды.
- Shadow Traffic (Көлеңкелі трафик): Envoy Ingress арқылы нақты сұраныстардың 100%-ын жаңа GKE + Spanner жүйесіне параллель бағыттап, жүктемені нақты шарттарда сынақтан өткіздік.
- Нөлдік үзіліспен ауысу (Zero-Downtime Cutover): сынақтар деректердің 100% дәлдігін көрсеткен соң, Cloud DNS арқылы бағытты жаңа жүйеге бұрдық. Қолданушылар ешқандай үзілісті байқамады.
Шайқас алдындағы стресс-тестілеу және Chaos Engineering
Біз сәттілікке ғана сеніп отыра алмадық. Жаппай сатылым басталғанға дейін екі апта бұрын біз k6 және Locust негізіндегі жүктеме жасау кластері арқылы инфрақұрылымға ауқымды стресс-сынақ өткіздік:
- Синтетикалық дауыл: біз каталогты үздіксіз қарайтын, тауарларды себетке салатын және тапсырыс жіберетін 120 000 виртуалды пайдаланушының әрекетін толық модельдедік.
- Chaos Mesh арқылы хаос сынағы: тура 100 000 RPS жүктеме кезінде біз
checkout-serviceподтарының 30%-ын күштеп өшірдік, желіге 500 мс жасанды кідіріс қостық және GCP-дің бір аймағын (zone) толығымен ажыраттық. - Нәтиже: GKE-нің автоматты өзін-өзі емдеуі және Cloud Spanner-дің мультиаймақтық төзімділігі арқасында бір де бір сұраныс 5xx қатесімен аяқталмады, ал подтардың қалпына келу уақыты 4 секундтан аспады.
Фронтендті қорғау: Cloud CDN және Cloud Armor
Медиа-контентті жүктеуге түсетін жүктемені азайту үшін біз мықты қорғаныс желісін құрдық:
- Google Cloud Storage + Cloud CDN: барлық статикалық мазмұн Cloud Storage бұлттық нысан қоймасына көшірілді. Cloud CDN суреттерді жүктеу уақытын 240 мс-тен фантастикалық 9 мс-ке дейін түсірді. Тұтынушылар сайттың ұшып тұрғанын сезінді.
- Google Cloud Armor (WAF & Rate Limiting): сатылым кезінде сайтты парсинг жасауға және қолдан құлатуға тырысқан боттардың 18 миллионнан астам зиянды сұранысын бұғаттады. GKE кластері тек таза трафикті қабылдады.
- Redis Memorystore: қалдықтарды кэштеу Spanner-ге түсетін оқу жүктемесін қосымша 75%-ға азайтты. Тек акциялық тауар қалдығы бар болған жағдайда ғана транзакция дерекқорға бағытталды.
Нәтижелер: Жаңа архитектураның толыққанды жеңісі
Белгіленген күні сағат 00:00-де жылдың басты сатылымы басталды. Алғашқы 10 минутта сайтқа 165 000 белсенді қолданушы кірді, ал ең жоғары RPS секундына 88 000 сұранысқа жетті.
GKE және Cloud Spanner инфрақұрылымы керемет тұрақтылық пен рекордтық жылдамдық көрсетті:
GKE + Cloud Spanner-ге дейінгі және кейінгі метрикаларды салыстыру
Жүйе тиімділігінің басты көрсеткіштері:
- Жауап беру уақыты (P99 Latency): бұрынғы 4 200 мс-тен (тайм-ауттармен) 65 мс (чекаутта) және 18 мс (каталогта) деңгейіне дейін қысқарды.
- Қателер деңгейі (5xx Error Rate): 28.5%-дан елеусіз 0.001%-ға дейін төмендеді.
- Транзакциялар өткізу сыйымдылығы: Cloud Spanner база нодаларының небәрі 52% жүктемесінде секундына 9 200 сәтті ACID-транзакцияны еркін өңдеді.
- Қаржылық нәтиже: маркетплейс өткен жылмен салыстырғанда 340%-ға көп тапсырыс қабылдап, рекордтық табысқа қол жеткізді. Ал FinOps шығындарын оңтайландырудың арқасында науқан аяқталған соң кластер автоматты түрде тарылып, қарапайым күндердегі шығынды 55%-ға үнемдеді.
E-commerce инженерлік көшбасшыларына арналған негізгі сабақтар
Ұлттық ауқымдағы жүктемелерден серверлердің қуатын жай ғана арттыру арқылы аман өту мүмкін емес. Цифрлық дәуірде икемді бұлттық инфрақұрылым құрған компаниялар ғана жеңіске жетеді.
Есте сақтайтын негізгі қағидалар:
- Тапсырыс қабылдауды асинхронды етіңіз: қолданушыны дерекқорға жазумен байланыстырмаңыз. Cloud Pub/Sub кезегі жүйеңізді құлаудан құтқарады.
- Транзакциялық базаға үнемдемеңіз: егер бизнес үшін қалдықтар мен төлемдердің дәлдігі маңызды болса, Cloud Spanner өзінің құнын сатылымның алғашқы 10 минутында-ақ ақтайды.
- Алдын ала масштабтаңыз (KEDA): хабарламалар кезегінің өлшемі бойынша масштабтау нақты жүктемеден озып отырады.
OZAT командасы жоғары жүктемелі жүйелерді жобалауда және Google Cloud-қа көшуде үлкен тәжірибеге ие. Біздің басқа да практикалық кейстерімізбен танысып, озық технологиялардың бизнесті қалай өзгертетінін көріңіз.
💡 ОЗАТ кеңесі: Енгізуге дайынсыз ба? Архитектура мен бюджетті Scope Builder арқылы есептеңіз немесе тегін ЖИ-аудиттен өтіңіз.

Рустам Шарафутдинов
Google Cloud архитектурасы саласындағы сарапшы және 15 жылдан астам тәжірибесі бар Senior Full-Stack әзірлеушісі. Ақауға төзімді архитектураларға, жоғары жүктемелі жобаларды оңтайландыруға және AI (Vertex AI) интеграциясына маманданған.