Osnovy Proektirovaniya Sistem, Kotoryye Dolzhen Znat Kazhdyy Razrabotchik
Balansirovka nagruzki, keshiruvaniye, sharding, CDN, ocheredi soobshcheniy, teorema CAP, ogranicheniye skorosti — demistifitsirovany s realnymi primerami i konfigami, kotoryye vy mozhete realno ispolzovat.
Kazhdyy backend-razrabotchik v konechnom itoge uthknetsya v stenu. Prilozheniye otlichno rabotayet na vashem noutbuke. Ono otlichno rabotayet v steydzhine s tremya odnovremennymi polzovatelyami. Zatem vy razvertyvayete v produktsiyu, tysyacha chelovek prikhodit odnovremenno, i baza dannykh padayet. API nachinayet vozvrashchat oshibki 5xx, frontend zavisayet, i gde-to v Slack kto-to publikuet skrinshot, ot kotorogo vash telefon vizhit v 2 chasa nochi.
Proektirovaniye sistem — eto to, chto nakhoditsya po druguyu storonu etoy steny. Eto nabor shablonov, kompromissov i infrastrukturnykh resheniy, kotoryye otdelyayut igrushechnoye prilozheniye ot produktsionnoy sistemy, kotoraya mozhet obrabatyvat realnyy trafik bez kollapsa. Khoroshaya novost v tom, chto vam ne nuzhno byt starshim inzhenerom infrastruktury, chtoby ponimayat osnovy. Vam nuzhno znat okolo vosmi kontseptsiy, to, kak oni vzaimodeystvuyut, i kogda obrashchatsya k kazhdoy iz nikh.
Eta statya okhvatyvayet shablony proektirovaniya system, kotoryye naiboleye vazhny dlya rabotayushchikh backend-razrabotchikov. Kazhdyy razdel obyasnyayet kontseptsiyu, pokazyvayet prakticheskiy primer i opisyvayet kompromissy, kotoryye vam nuzhno otsenit pered vnedreniyem. Eto ne abstraktnyye akademicheskiye kontseptsii — eto instrumenty, k kotorym vy budete obrashchatsya kazhdyy raz, kogda stroitie chto-to, chto dolzhno masshtabirovatsya.
Balansirovka nagruzki — derzhim kazhdyy server zanyatym, no ne slishkom
Balansirovka nagruzki — eto samyy prostoy i effektivnyy shablon proektirovaniya system, kotoryy vy mozhete realizovat. Ideya prosta: vmesto togo, chtoby napravlyat ves trafik na odin server, vy raspredelyayete vkhodyashchiye zaprosy po pulu serverov. Eto dayet vam dve veshchi odnovremenno: boleye vysokuyu dostupnost (yesli odin server umirayet, drugiye prodolzhayut obsluzhivat) i boleye vysokuyu propusknuyu sposobnost (neskolko serverov razdelyayut rabotu).
Naiboleye rasprostranennyye algoritmy balansirovki nagruzki — eto round-robin, naimensheye kolichestvo soyedineniy i IP-khesh. Round-robin tsiklicheski prokhodit po spisku serverov po poryadku — prosto, predskazuyemo, no ne uchityvayet, naskolko kazhdyy server na samom dele zanyat. Naimensheye kolichestvo soyedineniy otpravlyayet kazhdyy zapros na server s naimenshim kolichestvom aktivnykh soyedineniy, chto luchshe obrabatyvayet neravnomernuyu nagruzku zaprosov. IP-khesh ispolzuyet IP-adres klienta dlya determinirovannogo vybora servera, chto vazhno, kogda vam nuzhny lipkiye sessii — garantiruyushchiye, chto odin i tot zhe klient vsegda popadayet na tot zhe server.
Na praktike bolshinstvo produktsionnykh nastroyek ispolzuyut kombinatsiyu. Balansirovshchik urovnya 4 (rabotayushchiy na urovne TCP) raspredelyayet syryye soyedineniya po pulu obratnykh proksi ili API-gatewayev, kotoryye zatem vypolnyayut balansirovku urovnya 7 (rabotayushchuyu na urovne HTTP) dlya marshrutizatsii zaprosov k konkretnym instansam prilozheniya. Etot mnogourovnevyy podkhod derzhit ploskost dannykh bystroy, a logiku marshrutizatsii gibkoy.
# nginx.conf — prostaya round-robin balansirovka nagruzki po trem serveram prilozheniya
upstream app_cluster {
round-robin;
server app1.internal:3000 max_fails=3 fail_timeout=30s;
server app2.internal:3000 max_fails=3 fail_timeout=30s;
server app3.internal:3000 max_fails=3 fail_timeout=30s;
}
server {
listen 443 ssl;
location / {
proxy_pass http://app_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Kriticheskaya detal, kotoruyu bolshinstvo razrabotchikov upuskayet, — eto proverka zdorovya. Balansirovshchik nagruzki polezen tolko yesli on znayet, kakiye servery zdorovy. Yesli app2 padayet, no balansirovshchik prodolzhayet otpravlyat na nego trafik, vash pokazatel oshibok vozrastayet primerno na tret. Vsegda nastraivayte aktivnyye proverki zdorovya — balansirovshchik periodicheski pinguyet kazhdyy server i avtomaticheski udalyayet neotvechayushchiye iz pula.
Keshiruvaniye — skorost, no kakoy tsenoy?
Keshiruvaniye — eto yedinstvennaya optimizatsiya proizvoditelnosti s samym vysokim rychagom, dostupnaya lyubomu razrabotchiku. Odin popadaniye v kesh mozhet prevratit zapros k baze dannykh za 200 millisekund v poisk v pamyati za 2 millisekundy. Dva poryadka velichiny. V masshtabe millionov zaprosov eta raznitsa — eto raznitsa mezhdu schetom za bazu dannykh v $10,000 v mesyats i $500.
Kanonicheskiy stek keshiruvaniya imeyet tri urovnya, kazhdyy s raznymi kharakteristikami. Keshiruvaniye na urovne prilozheniya (keshi v pamyati, takie kak Redis ili Memcached) khranit rezultaty dorogikh vychisleniy ili zaprosov k baze dannykh. Keshiruvaniye CDN khranit staticheskiye i polustaticheskiye activy na periferiynykh uzblakh, blizkikh k polzovatelyam. Keshiruvaniye HTTP ispolzuyet zagolovki Cache-Control i ETag, chtoby pozvolit brauzeram i proksi keshirovat otvety bez uchastiya vashikh serverov.
Samaya trudnaya chast keshiruvaniya — eto ne yego nastroika, a invalidadtsiya kesha, kogda osnovnyye dannyye izmenyayutsya. Industriya ostanovilas na neskolkikh nadezhnykh shablonakh. Kesh-aside (takzhe nazyvayemyy lenivoy zagruzkoy) oznachayet, chto prilozheniye snachala proveryayet kesh, pri promahe obrashchayetsya k baze dannykh i zapolnyayet kesh rezultatom. Write-through kesh oznachayet, chto kazhdaya zapis idet odnovremenno i v kesh, i v bazu dannykh. Write-behind kesh oznachayet, chto zapisi snachala idut v kesh i asinkhronno sbrosayutsya v bazu dannykh.
V informatike yest tolko dve slozhnyye veshchi: invalidadtsiya kesha i imenovaniye veshchey. Invalidadtsiya kesha slozhneye, potomu chto vy ne mozhete prosto pereimenovat yeye i nadeyatsya, chto ona ischeznet.
Dlya bolshinstva prilozheniy kesh-aside s korotkim vremenem zhizni yavlyayetsya pravilnym vyborom po umolchaniyu. Ustanovite TTL, kotoryy sootvetstvuyet vashey tolerantnosti k ustarevshim dannym — 60 sekund dlya profiley polzovateley, 5 minut dlya spiskov produktov, 24 chasa dlya spravochnykh dannykh. Kogda vam nuzhna boleye silnaya soglasovannost, ispolzuyte write-through kesh, no primite boleye vysokuyu zaderzhku zapisi. Kogda vam nuzhna maksimalnaya propusknaya sposobnost chteniya i vy mozhete terpet konechnuyu soglasovannost, ispolzuyte kesh-aside s shchedrym TTL.
import redis.asyncio as aioredis
import json
cache = aioredis.Redis.from_url("redis://cache:6379")
CACHE_TTL = 300 # 5 minut
async def get_user_profile(user_id: str) -> dict:
key = f"profile:{user_id}"
cached = await cache.get(key)
if cached:
return json.loads(cached)
profile = await db.fetch_user(user_id)
if profile:
await cache.setex(key, CACHE_TTL, json.dumps(profile))
return profileSlovo preduprezhdeniya: keshiruvaniye mozhet maskirovat problemy, a ne reshat ikh. Yesli vashi zaprosy k baze dannykh medlennyye, potomu chto vam ne khvatayet indeksa, dobavleniye kesha skryvayet simptom, no osnovnoy zapros vse yeshche medlennyy. Kesh ochishchayetsya, medlennyy zapros vypolnyayetsya, polzovatel zhdyot. Vsegda profiruyte i optimiziruyte svoi medlennyye puti snachala, zatem dobavlyayte keshiruvaniye poverkh optimizirovannoy versii.
Sharding bazy dannykh — razdeleniye raboty, chtoby ni odna baza dannykh ne zatonula
Sharding (gorizontalnoye sektsionirovaniye) — eto to, k chemu vy obrashchayetes, kogda yedinyy ekzemplyar bazy dannykh ne mozhet spravitsya s vashim obyomom zapisi ili razmerom nabora dannykh. Ideya v tom, chtoby razdelit vashi dannyye po neskolkim ekzemplyaram bazy dannykh, gde kazhdyy ekzemplyar (shard) soderzhit podnabor dannykh. Prilozheniye opredelyayet, k kakomu shardu obrashchatsya na osnove shardovogo klyucha — obytno khesha ID polzovatelya, geograficheskogo regiona ili diapazona vremeni.
Shardovyy klyuch — eto yedinstvennoye naiboleye vazhnoye resheniye v lyuboy sharidirovannoy sisteme. Khoroshiy shardovyy klyuch raspredelyayet dannyye ravnomerno po shardam i sootvetstvuyet vashim shablonam zaprosov. Plokhoy shardovyy klyuch sozdayet goryachiye shardy — neskolko shardov, kotoryye obrabatyvayut bolshuyu chast trafika, poka ostalnyye prostaivayut. Naprimer, sharding po metke vremeni sozdaniya zvuchit razumno, poka vy ne osoznayete, chto segodnyashniy shard obrabatyvayet vse zapisi, a shardy proshedshikh let ne obrabatyvayut nichego.
Konsistentnoye kheshirovaniye reshayet problemu perebalansirovki, kotoraya muchayet naivnyy sharding. V prostoy skheme na osnove modulya (shard = hash(key) % N) dobavleniye novogo sharda trebuyet peremeshcheniya pochti vsekh dannykh. Konsistentnoye kheshirovaniye otobrazhayet i klyuchi, i shardy na khesh-koltso; kogda vy dobavlyayete shard, peremeshchayutsya tolko klyuchi v neposredstvennoy blizosti novogo sharda. Eto delayet masshtabirovaniye vverkh i vniz gorazdo meneye boleznennym.
- Sharding na osnove khesha — raspredeleniye putem kheshirovaniya shardovogo klyucha; prosto i ravnomerno, no resharding dorog
- Sharding na osnove diapazona — razdeleniye po diapazonam znacheniy (naprimer, polzovateli s ID 1–10000 na shard A, 10001–20000 na shard B); effektivno dlya zaprosov diapazona, no sklonno k goryachim tochkam
- Sharding na osnove kataloga — podderzhaniye tablitsy poiska, sopostavlyayushchey klyuchi s shardami; gibko, no dobavlyayet shag poiska i yedinuyu tochku otkaza, yesli katalog padayet
- Geograficheskiy sharding — razdeleniye po regionam polzovateley; otlichno dlya zaderzhki, no neudobno, yesli polzovateli puteshestvuyut ili yesli dannyye dolzhny byt globalnymi
Kompromiss, kotoryy vy prinimayete s shardingom, zaklyuchayetsya v tom, chto mezhshardovyye zaprosy stanovyatsya dorogimi ili nevozmozhnymi. Yesli vy shariruyete tablitsu polzovateley po user_id i tablitsu zakazov po user_id, zapros vsekh zakazov za posledniye 30 dney dolzhen udarit po kazhdomu shardu. Prilozheniya, kotorym nuzhna globalnaya analitika ili mezhshardovyye soyedineniya, chasto ispolzuyut vtorichnuyu repliku dlya chteniya (ili spetsializirovannuyu analiticheskuyu bazu dannykh), kotoraya agregiruyet dannyye iz vsekh shardov asinkhronno.
Teorema CAP — vy mozhete vybrat tolko dva
Teorema CAP utverzhdayet, chto raspredelennoye khranilishche dannykh ne mozhet odnovremenno obespechivat boleye dvukh iz trekh garantiy: Soglasovannost (kazhdoye chteniye poluchayet samuyu poslednyuyu zapis), Dostupnost (kazhdyy zapros poluchayet otvet, dazhe yesli eto ne samyye posledniye dannyye) i Ustoychivost k razdelenniyu (sistema prodolzhayet rabotat, nesmotrya na otkazy seti mezhdu uzlami).
Na praktike ustoychivost k razdelenniyu ne yavlyayetsya neobyazatelnoy. Seti dayut sboi. Pakety teryayutsya, soyedineniya vykhodyat po taym-autu, tsentry obrabotki dannykh teryayut pitaniye. Tak chto realnyy vybor — mezhdu CP (soglasovannost + ustoychivost k razdelenniyu) i AP (dostupnost + ustoychivost k razdelenniyu). Sistema CP, takaya kak etcd ili Zookeeper, budet otkazyvat v obsluzhivanii chteniy, yesli ne mozhet garantiruyet soglasovannost mezhdu uzlami. Sistema AP, takaya kak Cassandra ili DynamoDB, budet obsluzhivat chteniya s lyubogo dostupnogo uzla, dazhe yesli na etom uzlestarevshiye dannyye.
Eto ne akademicheskoye razlichiye. Kogda vy proyektiruyete sistemu, kotoraya okhvatyvayet neskolko tsentrov obrabotki dannykh, vy dolzhny reshit, chto proizoydyot, kogda setevoye soyedineniye mezhdu nimi razryvayetsya. Prodolzhayete li vy obsluzhivat zaprosy s potentsialno ustarevshimi dannymi (AP)? Ili vy ostanavlivayete obsluzhivaniye, poka set ne vosstanovitsya (CP)? Otvet zavisit ot vashego prilozheniya. Set dostavki kontenta dolzhna byt AP — ustarevshiy kontent luchshe, chem yego otsutstviye. Sistema obrabotki platezhey dolzhna byt CP — vy nikogda ne khotite dvazhdy spisat denezhnyye sredstva s klienta, potomu chto dva uzla prinyali odin i tot zhe platezh, buduchi razdelennymi.
Ocheredi soobshcheniy — prevrashcheniye sinkhronnoy boli v asinkhronnuyu graciyu
Ocheredi soobshcheniy — eto pozvonochnik asinkhronnoy obrabotki v raspredelennykh sistemakh. Oni pozvolyayut odnomu servisu (producer) otpravlyat soobshcheniye v ochered, ne ozhidaya, poka potrebitel obrabotayet yego. Potrebitel zabirayet soobshcheniye, kogda gotov, obrabatyvayet yego i podtverzhdayet zaversheniye. Eto otdelyayet prodyusera ot potrebitelya kak vo vremeni, tak i v prostranstve — im ne nuzhno rabotat s odinakovoy skorostyu ili dazhe v odno i to zhe vremya.
Kazhdaya netrivialnaya backend-sistema dolzhna gde-to ispolzovat ochered soobshcheniy. Kanonicheskiy primer — otpravka emailov. Kogda polzovatel registriruyetsya na vashey platforme, vy ne khotite, chtoby HTTP-otvet zhdal, poka sluzhba dostavki emailov otredaktiruyet shablon, podklyuchitsya k SendGrid i dostavit soobshcheniye. Vmesto etogo vash API pomeshchayet sobytiye send_email v ochered i nemedlenno vozvrashchayet otvet 201 Created. Otdelnyy worker zabirayet sobytiye, otpravlyayet email i otmechayet zadachu kak vypolnennuyu.
Dve dominantnyye modeli ocheredey soobshcheniy — eto publish-subscribe (pub/sub) i rabochiye ocheredi. V pub/sub kazhdoye soobshcheniye transliroyetsya vsem podpischikam. Eto polezno dlya sobytiyno-oriventirovannykh arkhitektur, gde neskolkim servisam nuzhno reagirovat na odno i to zhe sobytiye — novaya registratsiya polzovatelya mozhet zapustit privetstvennoye pismo, obnovleniye CRM i analiticheskoye sobytiye odnovremenno. V rabochey ocheredi kazhdoye soobshcheniye dostavlyayetsya rovno odnomu potrebitelyu. Eto polezno dlya raspredeleniya raboty po pulu rabotnikov — kazhdaya zagruzka izobrazheniya idet rovno k odnomu generatoru miniatyur.
# docker-compose.yml — minimalnaya nastroyka RabbitMQ dlya lokalnoy razrabotki
version: "3.8"
services:
rabbitmq:
image: rabbitmq:3-management-alpine
ports:
- "5672:5672" # AMQP port dlya prodyuserov/potrebitelyay
- "15672:15672" # UI upravleniya
environment:
RABBITMQ_DEFAULT_USER: app
RABBITMQ_DEFAULT_PASS: dev-only-password
volumes:
- rabbitmq_data:/var/lib/rabbitmq
volumes:
rabbitmq_data:Khitraya chast ocheredey soobshcheniy — eto korrektnaya obrabotka otkazov. Chto proizoydyot, yesli potrebitel vykhodit iz stroya na polputi obrabotki soobshcheniya? RabbitMQ i Amazon SQS obrabatyvayut eto s pomoshchyu podtverzhdeniy dostavki — potrebitel dolzhen yavno podtverdit, chto soobshcheniye bylo obrabotano uspeshno. Yesli potrebitel otklyuchayetsya bez podtverzhdeniya, soobshcheniye povtorno pomeshchayetsya v ochered i dostavlyayetsya drugomu potrebitelyu. Eta garantiya dostavki kak minimum odin raz oznachayet, chto vashi potrebiteli dolzhny byt idempotentnymi: obrabotka odnogo i togo zhe soobshcheniya dvazhdy dolzhna proizvodit tot zhe rezultat, chto i obrabotka odin raz.
Ocheredi mertvykh pisem — eto yeshche odin sushchestvennyy shablon. Kogda soobshcheniye ne mozhet byt obrabotano posle neskolkikh povtornykh popytok (nizhestoyashchiy servis nedostupen, dannyye povrezhdeny, biznes-pravilo izmenilos), soobshcheniye peremeshchayetsya v ochered mertvykh pisem vmesto togo, chtoby probovat beskonachno. Operator otslezhivayet ochered mertvykh pisem, issleduyet kornevuyu prichinu i libo ispravlyayet soobshcheniye i povtorno pomeshchayet yego v ochered, libo otbrasyvayet yego posle podtverzhdeniya, chto yego mozhno bezopasno ignorirovat.
CDN i ogranicheniye skorosti — perednyaya liniya zashchity
Seti dostavki kontenta i ogranichiteli skorosti sluzhat raznym tselyam, no u nikh yest obshchaya cherta: oni yavlyayutsya pervoy liniyey oborony mezhdu vashimi polzovatelyami i vashimi serverami. CDN derzhit staticheskiye activy i keshirovannyye otvety blizko k polzovatelyam, snizhaya zaderzhku i razgruzhaya vashi iskhodnyye servery. Ogranichitel skorosti predotvrashchayet peregruzku vashey sistemy zaprosami ot odnogo polzovatelya ili klienta.
CDN rabotayut putem raspredeleniya vashego kontenta po globalnoy seti periferiynykh serverov. Kogda polzovatel v Tokio zaprashivayet aktiv, CDN obsluzhivayet yego iz blizhayshego periferiynogo mestopolozheniya, a ne napravlyayet zapros ves put do vashego iskhodnogo servera v Virdzhinii. Eto snizhayet zaderzhku s 200 millisekund do 10 millisekund dlya staticheskikh aktivov. Sovremennyye CDN idut dalshe — oni mogut keshirovat otvety API, zavershat soyedineniya TLS i dazhe vypolnyat serverless-funktsii na periferii.
Ogranicheniye skorosti zashchishchayet vashu sistemu na neskolkikh urovnyakh. Globalnoye ogranicheniye skorosti ogranichivayet obshcheye kolichestvo zaprosov, kotoroye mozhet obrabotat vsya vasha sistema v sekundu, zashchishchaya ot vspleshkov trafika i DDoS-atak. Ogranicheniye skorosti na polzovatelya garantiruyet, chto odin zloumyshlennyy tenant ne mozhet lisit resursov drugikh polzovateley. Ogranicheniye skorosti na urovne end-pointa primenyayet raznyye limiti k raznym marshrutam — login-endpoint mozhet razreshit 5 zaprosov v minutu, v to vremya kak read-only poiskovoy endpoint pozvolyayet 100 zaprosov v minutu.
Algoritm skolzyashchego okna yavlyayetsya otraslevym standartom dlya ogranicheniya skorosti, potomu chto on tochen i effektiven. Vmesto sbrosa schetchikov cherez fiksirovannyye intervaly (chto pozvolyayet vspyleshki na granitse), skolzyashcheye okno uchityvayet zaprosy za skolzyashchiy period vremeni. Redis yavlyayetsya yestestvennym vyborom dlya realizatsii etogo — ispolzuyte sortirovannyy nabor s metkami vremeni v kachestve ochenok, udalyayte zapisi za predelami okna i schitayte ostavshiyesya zapisi. Zatraty pamyati minimalny (neskolko baytov na zapros), a vremennaya slozhnost' logarifmicheskaya.
// Redis-bazirovannyy ogranichitel skorosti so skolzyashchim oknom (TypeScript)
import { createClient } from "redis";
const redis = createClient({ url: "redis://ratelimit:6379" });
async function checkRateLimit(
key: string,
limit: number,
windowMs: number
): Promise<{ allowed: boolean; remaining: number }> {
const now = Date.now();
const windowStart = now - windowMs;
const multi = redis.multi();
multi.zRemRangeByScore(key, 0, windowStart);
multi.zAdd(key, { score: now, value: `${now}` });
multi.zCard(key);
multi.expire(key, Math.ceil(windowMs / 1000));
const [, , count] = await multi.exec() as [any, any, number];
return {
allowed: count <= limit,
remaining: Math.max(0, limit - count),
};
}I CDN, i ogranichiteli skorosti razdelyayut vazhnyy operatsionnyy printsip: otkryt pri otkaze ili zakryt pri otkaze? Yesli periferiya CDN ne mozhet dostuchatsya do iskhodnogo servera, dolzhna li ona obsluzhit ustarevshiy keshirovannyy otvet (otkryt pri otkaze) ili vernut oshibku (zakryt pri otkaze)? Yesli Redis-klaster ogranichitelya skorosti padayet, dolzhny li vse zaprosy prokhodit (otkryt pri otkaze — risk peregruzki) ili dolzhny byt otkloneny vse zaprosy (zakryt pri otkaze — garantirovannyy prostoy)?
Net universalnogo otveta, no khoroshiy vychod po umolchaniyu dlya bolshinstva sistem: otkryt pri otkaze dlya chteniya, zakryt pri otkaze dlya zapisi. Ustarevshaya stranitsa s produktom priyemlema. Poteryannyy zakaz na pokupku — net. Dokumentiruyte eto resheniye yavno v vashey runbook, chtoby dezhurnyy inzhener znal, kakogo povedeniya ozhidat, kogda infrastruktura dast sboy.
Sobiraya vse vmeste — myshleniye v kompromissakh
Proektirovaniye sistem — eto ne zapominaniye shablonov. Eto ponimaniye kompromissov i opredeleniye togo, kakoy shablon podkhodit k vashim ogranicheniyam. Kazhdoye resheniye vklyuchayet kompromiss mezhdu soglasovannostyu i dostupnostyu, mezhdu propusknoy sposobnostyu chteniya i zaderzhkoy zapisi, mezhdu operatsionnoy slozhnostyu i chistoy proizvoditelnostyu. Luchshiye inzhenery — eto ne te, kto znayet bolshe vsego shablonov; eto te, kto mozhet posmotret na problemu i opredelit, kakiye ograni-cheniya yavlyayutsya fiksirovannymi, a kakiye — predmetom peregovorov.
Vot bystraya ramka prinyatiya resheniy dlya togo, kogda vy stalkivayetes s novoy problemoy proektirovaniya system. Nachnite s perechisleniya vashikh nefunktsionalnykh trebovaniy: ozhidayemyy obyom trafika, tselevyye zaderzhki, trebovaniya k soglasovannosti, byudzhet na zatraty infrastruktury i znakomstvo komandy s tekhnologiyey. Zatem proydites po shablonam iz etoy stati i sprosite sebya, priblizhayet li kazhdyy iz nikh vas k vashim trebovaniyam ili udalyayet ot nikh.
Yesli zaderzhka yavlyayetsya vashey glavnoy zabotoy, nachnite s keshirovaniya i CDN — oni dayut naibolsheye uluchsheniye pri naimenshey slozhnosti. Yesli dostupnost kriticheski vazhna, ispolzuyte balansirovku nagruzki s proverkami zdorovya, proyektiruyte svoi servisy kak sostoyaniya-bez (stateless) i vybirayte AP vmesto CP tam, gde eto pozvolayet biznes. Yesli vy imeyete delo s nagruzkami, tyazhelymi po zapisi, otsenite sharding i ocheredi soobshcheniy na rannem etape — ikh gorazdo legche vvesti do togo, kak u vas budut milliony strok dannykh. Yesli vy imeyete delo s publichnym API, kotoryy budut ispolzovat storonniye razrabotchiki, realizuyte ogranicheniye skorosti v pervyy zhe den. Dobavleniye yego pozzhe oznachayet versiyonirovaniye vashego API ili polomku sushchestvuyushchikh klientov.
Samyy vazhnyy navyk v proektirovanii system — eto znaniye togo, chto vam ne nuzhno. Bolshinstvu prilozheniy ne nuzhen sharding. Bolshinstvu prilozheniy ne nuzhna ochered soobshcheniy. Prezhdevremennoye raspredeleniye — eto koren vsego zla v proektirovanii system — kazhdaya raspredelonnaya sistema vvodit rezhimy otkazov, kotorykh u odnoserverovnoy sistemy prosto net. Dobavlyayte slozhnost tolko togda, kogda metriki vam govoryat ob etom, a ne potomu, chto shablon zvuchit vpechatlyayushche na sobesedovanii.
Nachinayte s prostogo. Izmeryayte vse. Dobavlyayte odin shablon za raz. Proveryayte uluchsheniye pered tem, kak dvigatsya dalshe. Sistemy, kotoryye vyzhivayut, — eto ne te, u kotorykh samaya slozhnaya arkhitektura; eto te, kotoryye legko ponyat, legko ekspluatirovat i legko izmenit, kogda poyavitsya sleduyushcheye uzkoye mesto.
