Multi-Tenant vs Single-Tenant | Tinkamos SaaS architektūros pasirinkimas
Techninis multi-tenant ir single-tenant SaaS architektūrų palyginimas. Sužinokite kompromisus ir kaip pasirinkti tinkamą požiūrį jūsų produktui.
Kiekvienas SaaS produktas turi atsakyti į fundamentalų klausimą: kaip aptarnauti kelis klientus iš tos pačios programinės įrangos? Atsakymas yra jūsų nuomos modelis. Jis veikia kaštus, saugumą, našumą ir kaip greitai galite pristatyti. Teisingas pasirinkimas anksti apsaugo nuo skausmingų migracijų vėliau.
Apibrėžimai
Multi-tenant
Vienas programos egzempliorius aptarnauja visus klientus. Visi dalijasi tais pačiais serveriais, ta pačia kodų baze ir dažnai ta pačia duomenų baze. Kiekvieno kliento duomenys logiškai izoliuoti, bet infrastruktūra bendra.
Galvokite apie tai kaip daugiabučio namą. Kiekvienas nuomininkas gyvena tame pačiame pastate, dalijasi liftu ir koridoriais, bet turi savo užrakintą butą su savo baldais.
Single-tenant
Kiekvienas klientas gauna savo dedikuotą programos egzempliorių. Atskiri serveriai, atskiros duomenų bazės, kartais atskiros kodų bazės. Tarp klientų nieko nėra bendra.
Galvokite apie tai kaip atskirus namus. Kiekvienas nuomininkas turi savo pastatą, savo vandentiekį, savo kiemą. Pilna izoliacija, bet brangiau prižiūrėti.
Kaip veikia multi-tenancy
Yra trys įprasti multi-tenant architektūros metodai, kiekvienas su skirtingais kompromisais.
1 modelis: Bendra programa, bendra duomenų bazė
Visi nuomininkai dalijasi vienu programos egzemplioriumi ir viena duomenų baze. Nuomininkų duomenys atskiriami naudojant nuomininko identifikatorių (paprastai tenant_id stulpelį) kiekvienoje lentelėje.
Architektūra:
- Vienas programos serveris (ar klasteris) tvarko visas užklausas.
- Viena duomenų bazė saugo visų nuomininkų duomenis.
- Kiekviena užklausa apima
WHERE tenant_id = ?sąlygą duomenims apriboti iki teisingo nuomininko.
Privalumai:
- Mažiausi infrastruktūros kaštai. Viena duomenų bazė, vienas programos diegimas.
- Paprasčiausia diegti ir atnaujinti. Vienas diegimas, visi gauna pakeitimą.
- Lengva agreguoti duomenis per nuomininkus analitikai ir ataskaitoms.
Trūkumai:
- Didžiausia duomenų nutekėjimo rizika, jei užklausa pamiršta nuomininko filtrą.
- Vienas triukšmingas nuomininkas gali pabloginti našumą visiems.
- Duomenų bazės migracijos veikia visus nuomininkus vienu metu.
- Sunkiausia atitikti duomenų rezidencijos reglamentus.
Tai dažniausias požiūris B2B SaaS produktams su dideliu skaičiumi mažų ir vidutinių klientų.
2 modelis: Bendra programa, atskiros duomenų bazės
Visi nuomininkai dalijasi tuo pačiu programos egzemplioriumi, bet kiekvienas nuomininkas gauna savo duomenų bazę. Programa nukreipia užklausas į teisingą duomenų bazę pagal autentifikuotą nuomininką.
Architektūra:
- Vienas programos serveris (ar klasteris) tvarko visas užklausas.
- Atskira duomenų bazė kiekvienam nuomininkui.
- Nukreipimo sluoksnis susieja nuomininko tapatybę su teisingu duomenų bazės ryšiu.
Privalumai:
- Stipresnė duomenų izoliacija. Jokios tarpnuomininkų užklausų rizikos.
- Lengviau atitikti duomenų rezidencijos reikalavimus. Galite kiekvieną duomenų bazę patalpinti nuomininko reikalaujamame regione.
- Kiekvieno nuomininko atsarginė kopija ir atkūrimas paprastas.
- Vieno nuomininko didelis naudojimas neužrakins lentelių kitiems nuomininkams.
Trūkumai:
- Daugiau infrastruktūros valdyti. Šimtai nuomininkų reiškia šimtus duomenų bazių.
- Schemos migracijos turi būti taikomos kiekvienai duomenų bazei atskirai.
- Tarpnuomininkų ataskaitos reikalauja kelių duomenų bazių užklausų.
- Aukštesni kaštai nei pilnai bendras modelis.
Tai stipri vidurio pozicija produktams, kuriems reikia geresnės izoliacijos be pilno single-tenancy kaštų.
3 modelis: Atskira programa, atskira duomenų bazė
Kiekvienas nuomininkas gauna savo programos egzempliorių ir savo duomenų bazę. Pilnai izoliuota. Tai iš esmės single-tenancy, bet valdoma SaaS tiekėjo, o ne kliento.
Architektūra:
- Dedikuotas programos diegimas kiekvienam nuomininkui.
- Dedikuota duomenų bazė kiekvienam nuomininkui.
- Nukreipimo sluoksnis (dažnai apkrovos balansaviklis ar API šliuzas) nukreipia srautą į teisingą egzempliorių.
Privalumai:
- Pilna izoliacija. Jokių bendrų išteklių tarp nuomininkų.
- Maksimalus lankstumas pritaikymui kiekvienam nuomininkui.
- Vieno nuomininko našumas niekada neveikia kito.
- Paprasčiausias atitikties pasakojimas.
Trūkumai:
- Aukščiausi infrastruktūros kaštai.
- Diegimo sudėtingumas auga tiesiškai su nuomininkų skaičiumi.
- Atnaujinimai turi būti diegiami kiekvienam egzemplioriui atskirai (arba automatizuoti labai kruopščiai).
- Ekonomiškai nesveika dideliam skaičiui mažų nuomininkų.
Šis modelis prasmingas korporaciniam SaaS, kur klientai reikalauja dedikuotos infrastruktūros ir yra pasirengę mokėti premiją.
Privalumai ir trūkumai iš pirmo žvilgsnio
| Veiksnys | Multi-Tenant (bendra DB) | Multi-Tenant (atskira DB) | Single-Tenant |
|---|---|---|---|
| Infrastruktūros kaštai | Mažiausi | Vidutiniai | Aukščiausi |
| Duomenų izoliacija | Loginė (eilutės lygiu) | Fizinė (duomenų bazės lygiu) | Pilna |
| Diegimo sudėtingumas | Žemas | Vidutinis | Aukštas |
| Atnaujinimo greitis | Akimirksniu visiems | Akimirksniu programai, per-DB migracijos | Per-egzempliorių diegimas |
| Pritaikymas | Ribotas | Ribotas | Pilnas |
| Atitiktis | Sunkesnė | Vidutinė | Lengviausia |
| Mastelio keitimas (nuomininkų sk.) | Puikus | Geras | Prastas |
| Triukšmingo kaimyno rizika | Aukšta | Vidutinė | Jokia |
Duomenų izoliacija ir saugumas
Duomenų izoliacija yra svarbiausias svarstymas bet kuriame nuomos modelyje. Saugumo pažeidimas, kai vienas nuomininkas gali pasiekti kito nuomininko duomenis, yra katastrofiškas SaaS verslui. Tai gali sunaikinti pasitikėjimą, pažeisti reglamentus ir sunaikinti įmonę.
Eilutės lygio saugumas
Bendros duomenų bazės modelyje PostgreSQL Row-Level Security (RLS) yra viena stipriausių apsaugų nuo duomenų nutekėjimo. RLS užtikrina nuomininko izoliaciją duomenų bazės lygiu, ne programos lygiu. Net jei jūsų programos kode yra klaida, pamirštanti filtruoti pagal nuomininką, pati duomenų bazė neleidžia tarpnuomininkų prieigos.
Štai kaip tai nustatyti:
-- Enable RLS on a table
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
-- Create a policy that restricts access to the current tenant
CREATE POLICY tenant_isolation ON projects
USING (tenant_id = current_setting('app.current_tenant_id')::uuid);
-- Force RLS even for table owners
ALTER TABLE projects FORCE ROW LEVEL SECURITY;
Prieš vykdant bet kurią užklausą, nustatykite nuomininko kontekstą:
-- Set at the beginning of each request/transaction
SET LOCAL app.current_tenant_id = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
-- Now this query automatically returns only the current tenant's data
SELECT * FROM projects;
-- No WHERE clause needed. RLS handles it.
Programos lygio izoliacija
Be duomenų bazės lygio saugumo, jūsų programa turėtų užtikrinti nuomininko ribas:
// Middleware that sets tenant context on every request
async function tenantMiddleware(req: Request, res: Response, next: NextFunction) {
const tenantId = extractTenantId(req); // From JWT, subdomain, or header
if (!tenantId) {
return res.status(401).json({ error: "Tenant not identified" });
}
// Set tenant context for the database connection
await db.raw(`SET LOCAL app.current_tenant_id = '${tenantId}'`);
req.tenantId = tenantId;
next();
}
Gynybos gilumo principas. Niekada nepasitikėkite vienu izoliacijos sluoksniu. Derinkite programos lygio filtravimą, duomenų bazės lygio saugumą ir reguliarius saugumo auditus.
Našumo svarstymai
Bendros duomenų bazės iššūkiai
Bendroje duomenų bazėje visi nuomininkai varžosi dėl tų pačių išteklių. Nuomininkas, paleidęs sunkią ataskaitą, gali sulėtinti užklausas visiems kitiems. Sprendimai:
- Ryšių telkinys. Naudokite PgBouncer ar panašų įrankį, kad vienas nuomininkas neišeikvotų duomenų bazės ryšių.
- Užklausų terminai. Nustatykite maksimalius vykdymo laikus, kad pabėgusi užklausa negalėtų užrakinti išteklių neribotam laikui.
- Užklausų limitavimas. Taikykite nuomininko limitus API užklausoms ir duomenų bazės operacijoms.
- Skaitymo replikos. Nukreipkite sunkias skaitymo operacijas (ataskaitas, eksportus) į repliką, kad jos neveiktų pagrindinės duomenų bazės.
Atskiros duomenų bazės privalumai
Su duomenų baze kiekvienam nuomininkui, našumo izoliacija integruota. Vieno nuomininko didelis darbo krūvis veikia tik jų duomenų bazę. Taip pat galite konfigūruoti didesnes ar mažesnes duomenų bazes pagal kiekvieno nuomininko planą ir naudojimą.
Kompromisas yra valdymo apkrova. 500 duomenų bazių stebėjimas sunkesnis nei vienos. Automatizuoti įrankiai tampa būtini.
Kaštų pasekmės mastu
Pažiūrėkime į apytikslius skaičius. Tarkime, turite 100 nuomininkų.
Bendra duomenų bazė (multi-tenant):
- 1 programos klasteris: ~200 eurų/mėn.
- 1 valdomas PostgreSQL egzempliorius: ~100 eurų/mėn.
- Iš viso: ~300 eurų/mėn. (3 eurai per nuomininką)
Atskiros duomenų bazės (multi-tenant):
- 1 programos klasteris: ~200 eurų/mėn.
- 100 mažų duomenų bazių egzempliorių: ~2 000 eurų/mėn.
- Iš viso: ~2 200 eurų/mėn. (22 eurai per nuomininką)
Single-tenant:
- 100 programos egzempliorių: ~5 000 eurų/mėn.
- 100 duomenų bazių egzempliorių: ~2 000 eurų/mėn.
- Iš viso: ~7 000 eurų/mėn. (70 eurų per nuomininką)
Šie skaičiai supaprastinti, bet modelis teisingas. Bendra infrastruktūra yra dramatiškai pigesnė. Su 1 000 nuomininkų skirtumas dar didesnis.
Todėl kainodara turi derėti su architektūra. Jei imatė 20 eurų per mėnesį ir turite single-tenant infrastruktūrą po 70 eurų per nuomininką, praleidžiate pinigus su kiekvienu klientu.
Kada rinktis multi-tenant
Multi-tenant architektūra yra teisingas pasirinkimas, kai:
- Kuriate B2B SaaS SMB. Didelis kiekis, žemesni kainų taškai ir standartiniai funkcijų rinkiniai.
- Kaštų efektyvumas svarbus. Reikia išlaikyti žemus infrastruktūros kaštus, palyginti su pajamomis.
- Norite greitų, vienodų atnaujinimų. Diekite kartą, visi nuomininkai gauna patobulinimą.
- Jūsų klientai nereikalauja dedikuotos infrastruktūros. Dauguma mažų ir vidutinių įmonių nesirūpina, kur jų duomenys, kol jie saugūs.
- Esate ankstyvoje stadijoje. Pradėkite nuo multi-tenant. Tai pigiau ir paprasčiau. Visada galite vėliau pasiūlyti single-tenant korporaciniams klientams.
Kada rinktis single-tenant
Single-tenant architektūra prasminga, kai:
- Parduodate korporacijoms. Didelės organizacijos dažnai reikalauja dedikuotos infrastruktūros kaip pirkimo proceso dalies.
- Atitiktis to reikalauja. Pramonės šakos kaip sveikatos priežiūra (HIPAA), finansai (SOX, PCI-DSS) ir vyriausybė turi griežtus duomenų izoliacijos reikalavimus.
- Klientams reikia pritaikymo. Jei kiekvienam klientui reikia skirtingų konfigūracijų, integracijų ar net funkcijų, single-tenant suteikia lankstumą.
- Jūsų kainų taškas tai palaiko. Jei imatė 5 000 ar daugiau eurų per mėnesį kiekvienam klientui, infrastruktūros kaštai lengvai pateisinamai.
- Duomenų rezidencija yra griežtas reikalavimas. Kai duomenys turi būti konkrečioje šalyje, atskira infrastruktūra kiekvienam nuomininkui yra paprasčiausias požiūris.
Hibridiniai metodai
Neprivalote rinktis tik vieno. Daugelis sėkmingų SaaS įmonių naudoja hibridinį modelį:
- Multi-tenant standartinėms pakopoms. Nemokami, pradiniai ir pro klientai dalijasi infrastruktūra. Tai palaiko žemus kaštus ir leidžia augti.
- Single-tenant korporacijoms. Premium klientai gauna dedikuotus egzempliorius su pritaikytais SLA, atitikties sertifikavimais ir dedikuotu palaikymu.
Programos kodas tas pats. Diegimo modelis skiriasi. Tam reikia geros infrastruktūros automatizacijos, bet tai įrodytas modelis.
Kaip įgyvendinti hibridinį modelį
- Pirmiausia kurkite programą kaip multi-tenant. Visa nuomininko izoliacijos logika lieka ta pati, nepriklausomai nuo diegimo modelio.
- Naudokite infrastruktūrą-kaip-kodą (Terraform, Pulumi ar CDK) aplinkos kūrimui automatizuoti.
- Sukurkite aprūpinimo konvejerį, galintį paleisti naują dedikuotą aplinką per minutes, ne dienas.
- Palaikykite vieną kodų bazę. Tas pats Docker atvaizdas veikia tiek bendrose, tiek dedikuotose aplinkose. Konfigūracija (ne kodas) nustato elgseną.
Duomenų bazės strategijos detaliau
Duomenų bazė yra ten, kur nuomos sprendimai turi didžiausią poveikį. Štai trys įrodytos strategijos.
1 strategija: Bendros lentelės su tenant_id
Kiekviena lentelė turi tenant_id stulpelį. Visos užklausos filtruoja pagal jį.
CREATE TABLE projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants(id),
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_projects_tenant ON projects(tenant_id);
-- Always query with tenant context
SELECT * FROM projects WHERE tenant_id = $1;
Geriausiai tinka: daugumai SaaS produktų. Paprasta, ekonomiška, gerai suprantama.
2 strategija: Schema kiekvienam nuomininkui
Kiekvienas nuomininkas gauna savo PostgreSQL schemą bendroje duomenų bazėje. Lentelės turi tą pačią struktūrą, bet duomenys fiziškai atskirti.
-- Create a schema for a new tenant
CREATE SCHEMA tenant_abc123;
-- Create tables in the tenant's schema
CREATE TABLE tenant_abc123.projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
-- Set the search path per request
SET search_path TO tenant_abc123, public;
-- Now queries are automatically scoped
SELECT * FROM projects;
Geriausiai tinka: produktams, kuriems reikia stipresnės izoliacijos nei eilutės lygiu, bet nenori atskiros duomenų bazės kaštų. Gerai veikia iki kelių šimtų nuomininkų.
3 strategija: Atskiros duomenų bazės
Kiekvienas nuomininkas gauna dedikuotą PostgreSQL egzempliorių (arba dedikuotą duomenų bazę bendrame serveryje).
// Database connection routing
class TenantDatabaseRouter {
private connections: Map<string, DatabasePool> = new Map();
async getConnection(tenantId: string): Promise<DatabasePool> {
if (this.connections.has(tenantId)) {
return this.connections.get(tenantId)!;
}
const config = await this.loadTenantDbConfig(tenantId);
const pool = new DatabasePool({
host: config.host,
port: config.port,
database: config.database,
user: config.user,
password: config.password,
});
this.connections.set(tenantId, pool);
return pool;
}
private async loadTenantDbConfig(tenantId: string): Promise<DbConfig> {
// Look up tenant's database connection details
// from a central configuration store
return await configStore.get(`tenants/${tenantId}/database`);
}
}
Geriausiai tinka: korporaciniam SaaS su aukštos vertės klientais, griežtais atitikties reikalavimais ar duomenų rezidencijos prievolėmis.
Sprendimo priėmimas
Štai paprasta sprendimų priėmimo sistema:
- Koks jūsų tikslinio kliento dydis? SMB rodo multi-tenant. Korporacija rodo single-tenant arba hibridinį.
- Koks jūsų kainų taškas? Žemiau 100 eurų/mėn. reikia multi-tenant, kad būtumėte pelningi. Virš 1 000 eurų/mėn. single-tenant tampa prieinamas.
- Kokie atitikties reikalavimai? Reguliuojamos pramonės dažnai reikalauja stipresnės izoliacijos.
- Kiek nuomininkų tikitės? Šimtams ar tūkstančiams nuomininkų reikia bendros infrastruktūros. Nuo dešimt iki penkiasdešimt didelių nuomininkų gali veikti su dedikuotais egzemplioriais.
- Koks jūsų komandos operacinis pajėgumas? Single-tenant reikalauja daugiau DevOps investicijų. Multi-tenant yra operaciškai paprastesnis.
Jei nesate tikri, pradėkite nuo multi-tenant su bendra duomenų baze ir eilutės lygio saugumu. Tai pigiausias variantas, saugus, kai teisingai įgyvendintas, ir palaiko paprastą architektūrą. Visada galite vėliau pridėti dedikuotą pakopą korporaciniams klientams.
Esmė
Nėra universaliai teisingo nuomos modelio. Teisingas pasirinkimas priklauso nuo jūsų klientų, kainodaros, atitikties reikalavimų ir operacinių galimybių.
Dauguma SaaS produktų turėtų pradėti nuo multi-tenant. Tai pigiau, paprasčiau ir gerai keičia mastelį. Pereinant prie didesnių organizacijų ir pradedant pardavinėti didesnėms, pridėkite single-tenant galimybes klientams, kuriems jų reikia ir kurie atitinkamai mokės.
Architektūra turėtų tarnauti verslui, ne atvirkščiai. Kurkite klientams, kuriuos turite šiandien, ir projektuokite su pakankamu lankstumu aptarnauti klientus, kuriuos norite rytoj.
Reikia pagalbos pasirenkant tinkamą architektūrą jūsų SaaS produktui? Sukūrėme multi-tenant ir single-tenant sistemas įvairiose pramonėse. Raskime geriausią požiūrį jūsų projektui.