1. 首页 > MongoDB教程 > 正文

MongoDB教程FG092-MongoDB数据库多租户架构实战

本文主要介绍MongoDB的多租户架构设计和实施,包括多租户隔离方案、访问控制、性能优化和最佳实践等内容。风哥教程参考MongoDB官方文档Security相关章节。

目录大纲

Part01-基础概念与理论知识

Part02-生产环境规划与建议

Part03-生产环境项目实施方案

Part04-生产案例与实战讲解

Part05-风哥经验总结与分享

Part01-基础概念与理论知识

1.1 多租户架构概述

多租户架构是指在一个MongoDB实例中为多个租户(客户)提供服务,每个租户的数据相互隔离,确保数据安全和隐私。多租户架构广泛应用于SaaS(软件即服务)系统中,可以提高资源利用率,降低运维成本。

多租户架构的优势:

  • 资源共享:多个租户共享同一MongoDB实例,提高资源利用率
  • 成本降低:减少硬件和运维成本
  • 管理简化:集中管理所有租户的数据
  • 扩展性:便于水平扩展,支持更多租户

多租户架构的挑战:

  • 数据隔离:确保不同租户的数据相互隔离
  • 性能隔离:防止单个租户占用过多资源
  • 安全控制:确保租户只能访问自己的数据
  • 扩展性:随着租户数量增加,性能和管理的挑战

学习交流加群风哥微信: itpux-com

1.2 多租户隔离方案

MongoDB支持三种主要的多租户隔离方案:

  • 数据库级隔离:为每个租户创建单独的数据库,租户之间完全隔离
  • 集合级隔离:为每个租户创建单独的集合,租户之间共享数据库
  • 文档级隔离:所有租户共享集合,通过文档中的租户ID字段进行隔离

各隔离方案的对比:

隔离方案 优点 缺点 适用场景
数据库级隔离 完全隔离,安全级别高 资源消耗大,管理复杂 租户数量少,数据安全要求高
集合级隔离 隔离程度较高,管理相对简单 资源消耗较大,集合数量限制 租户数量中等,数据安全要求较高
文档级隔离 资源消耗小,管理简单 隔离程度较低,查询需要过滤 租户数量多,数据安全要求一般

更多视频教程www.fgedu.net.cn

Part02-生产环境规划与建议

2.1 多租户架构设计

多租户架构设计的考虑因素:

  • 租户数量:根据预期的租户数量选择合适的隔离方案
  • 数据量:每个租户的数据量大小
  • 性能要求:租户的性能需求
  • 安全要求:数据安全和隐私的要求
  • 管理复杂度:运维和管理的复杂度

推荐的架构设计:

  • 租户数量较少(< 100):使用数据库级隔离
  • 租户数量中等(100-1000):使用集合级隔离
  • 租户数量较多(> 1000):使用文档级隔离

风哥提示:选择合适的隔离方案是多租户架构成功的关键。

2.2 性能与安全考虑

性能考虑:

  • 索引优化:为租户ID字段创建索引,提高查询性能
  • 查询优化:避免全表扫描,使用合适的查询条件
  • 资源限制:设置租户的资源使用限制,防止单个租户占用过多资源
  • 分片策略:对于大规模多租户系统,使用分片集群

安全考虑:

  • 认证与授权:为每个租户创建单独的用户,设置适当的权限
  • 数据加密:对敏感数据进行加密存储
  • 审计日志:记录租户的操作日志,便于审计
  • 网络安全:使用SSL/TLS加密传输

更多学习教程公众号风哥教程itpux_com

Part03-生产环境项目实施方案

3.1 数据库级隔离

数据库级隔离实施:

# 1. 为每个租户创建数据库
use tenant1_db
db.createCollection(“fgedu_users”)

use tenant2_db
db.createCollection(“fgedu_users”)

# 2. 为每个租户创建用户
use admin
db.createUser({
user: “tenant1”,
pwd: “tenant1123”,
roles: [
{ role: “readWrite”, db: “tenant1_db” }
]
})

db.createUser({
user: “tenant2”,
pwd: “tenant2123”,
roles: [
{ role: “readWrite”, db: “tenant2_db” }
]
})

# 3. 测试租户访问
# 租户1连接
mongosh –host 192.168.1.100 –port 27017 –username tenant1 –password tenant1123 –authenticationDatabase admin
use tenant1_db
db.fgedu_users.insertOne({ name: “User1”, age: 25 })

# 租户2连接
mongosh –host 192.168.1.100 –port 27017 –username tenant2 –password tenant2123 –authenticationDatabase admin
use tenant2_db
db.fgedu_users.insertOne({ name: “User2”, age: 30 })

3.2 集合级隔离

集合级隔离实施:

# 1. 创建共享数据库
use multi_tenant_db

# 2. 为每个租户创建集合
db.createCollection(“tenant1_fgedu_users”)
db.createCollection(“tenant2_fgedu_users”)

# 3. 为每个租户创建用户
use admin
db.createUser({
user: “tenant1”,
pwd: “tenant1123”,
roles: [
{ role: “readWrite”, db: “multi_tenant_db”, collection: “tenant1_fgedu_users” }
]
})

db.createUser({
user: “tenant2”,
pwd: “tenant2123”,
roles: [
{ role: “readWrite”, db: “multi_tenant_db”, collection: “tenant2_fgedu_users” }
]
})

# 4. 测试租户访问
# 租户1连接
mongosh –host 192.168.1.100 –port 27017 –username tenant1 –password tenant1123 –authenticationDatabase admin
use multi_tenant_db
db.tenant1_fgedu_users.insertOne({ name: “User1”, age: 25 })

# 租户2连接
mongosh –host 192.168.1.100 –port 27017 –username tenant2 –password tenant2123 –authenticationDatabase admin
use multi_tenant_db
db.tenant2_fgedu_users.insertOne({ name: “User2”, age: 30 })

3.3 文档级隔离

文档级隔离实施:

# 1. 创建共享集合
use multi_tenant_db
db.createCollection(“fgedu_users”)

# 2. 为租户ID字段创建索引
db.fgedu_users.createIndex({ tenantId: 1 })

# 3. 插入租户数据
db.fgedu_users.insertOne({ tenantId: “tenant1”, name: “User1”, age: 25 })
db.fgedu_users.insertOne({ tenantId: “tenant2”, name: “User2”, age: 30 })

# 4. 为每个租户创建用户
use admin
db.createUser({
user: “tenant1”,
pwd: “tenant1123”,
roles: [
{ role: “readWrite”, db: “multi_tenant_db” }
]
})

db.createUser({
user: “tenant2”,
pwd: “tenant2123”,
roles: [
{ role: “readWrite”, db: “multi_tenant_db” }
]
})

# 5. 应用程序层面过滤租户数据
# 租户1只能访问自己的数据
db.fgedu_users.find({ tenantId: “tenant1” })

# 租户2只能访问自己的数据
db.fgedu_users.find({ tenantId: “tenant2” })

3.4 访问控制

访问控制实施:

# 1. 创建角色
use admin
db.createRole({
role: “tenant_role”,
privileges: [
{ resource: { db: “multi_tenant_db”, collection: “fgedu_users” }, actions: [“find”, “insert”, “update”, “delete”] }
],
roles: []
})

# 2. 创建租户用户并分配角色
db.createUser({
user: “tenant1”,
pwd: “tenant1123”,
roles: [“tenant_role”]
})

# 3. 启用审计日志
# 在mongod.conf中添加
auditLog:
destination: file
format: JSON
path: /mongodb/logs/audit.json
filter: ‘{ “atype”: { “$in”: [“authCheck”, “insert”, “update”, “delete”] } }’

Part04-生产案例与实战讲解

4.1 数据库级隔离实战

数据库级隔离实战:

# 1. 编写租户管理脚本
vi /mongodb/scripts/tenant_management.sh
# 内容:
#!/bin/bash
# tenant_management.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

# 创建租户
create_tenant() {
local tenant_id=$1
local password=$2

# 创建数据库
mongosh –eval “use ${tenant_id}_db; db.createCollection(‘fgedu_users’);”

# 创建用户
mongosh –eval “use admin; db.createUser({ user: ‘${tenant_id}’, pwd: ‘${password}’, roles: [{ role: ‘readWrite’, db: ‘${tenant_id}_db’ }] });”

echo “Tenant ${tenant_id} created successfully”
}

# 删除租户
delete_tenant() {
local tenant_id=$1

# 删除用户
mongosh –eval “use admin; db.dropUser(‘${tenant_id}’);”

# 删除数据库
mongosh –eval “db.getSiblingDB(‘${tenant_id}_db’).dropDatabase();”

echo “Tenant ${tenant_id} deleted successfully”
}

# 示例使用
# create_tenant tenant3 tenant3123
# delete_tenant tenant3

# 2. 执行脚本创建租户
/mongodb/scripts/tenant_management.sh

# 3. 测试租户访问
mongosh –host 192.168.1.100 –port 27017 –username tenant3 –password tenant3123 –authenticationDatabase admin
use tenant3_db
db.fgedu_users.insertOne({ name: “User3”, age: 35 })
db.fgedu_users.find()
# 输出:
{ “_id” : ObjectId(“60a7b8c9d0e1f2a3b4c5d6ea”), “name” : “User3”, “age” : 35 }

from MongoDB视频:www.itpux.com

4.2 文档级隔离实战

文档级隔离实战:

# 1. 编写应用程序代码(Python)
vi /mongodb/scripts/multi_tenant_app.py
# 内容:
#!/usr/bin/env python3
# multi_tenant_app.py
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

from pymongo import MongoClient

class MultiTenantApp:
def __init__(self, tenant_id):
self.tenant_id = tenant_id
self.client = MongoClient(‘mongodb://fgedu:fgedu123@192.168.1.100:27017/admin’)
self.db = self.client[‘multi_tenant_db’]
self.collection = self.db[‘fgedu_users’]

def get_users(self):
return list(self.collection.find({ ‘tenantId’: self.tenant_id }))

def add_user(self, name, age):
user = {
‘tenantId’: self.tenant_id,
‘name’: name,
‘age’: age
}
return self.collection.insert_one(user)

def update_user(self, name, age):
return self.collection.update_one(
{ ‘tenantId’: self.tenant_id, ‘name’: name },
{ ‘$set’: { ‘age’: age } }
)

def delete_user(self, name):
return self.collection.delete_one(
{ ‘tenantId’: self.tenant_id, ‘name’: name }
)

# 测试代码
if __name__ == ‘__main__’:
# 租户1操作
app1 = MultiTenantApp(‘tenant1’)
app1.add_user(‘User1’, 25)
print(‘Tenant1 users:’, app1.get_users())

# 租户2操作
app2 = MultiTenantApp(‘tenant2’)
app2.add_user(‘User2’, 30)
print(‘Tenant2 users:’, app2.get_users())

# 2. 执行应用程序
python3 /mongodb/scripts/multi_tenant_app.py
# 输出:
Tenant1 users: [{‘_id’: ObjectId(’60a7b8c9d0e1f2a3b4c5d6eb’), ‘tenantId’: ‘tenant1’, ‘name’: ‘User1’, ‘age’: 25}]
Tenant2 users: [{‘_id’: ObjectId(’60a7b8c9d0e1f2a3b4c5d6ec’), ‘tenantId’: ‘tenant2’, ‘name’: ‘User2’, ‘age’: 30}]

风哥提示:文档级隔离需要在应用程序层面进行数据过滤,确保租户只能访问自己的数据。

4.3 访问控制实战

访问控制实战:

# 1. 创建细粒度角色
use admin
db.createRole({
role: “tenant_read_only”,
privileges: [
{ resource: { db: “multi_tenant_db”, collection: “fgedu_users” }, actions: [“find”] }
],
roles: []
})

db.createRole({
role: “tenant_read_write”,
privileges: [
{ resource: { db: “multi_tenant_db”, collection: “fgedu_users” }, actions: [“find”, “insert”, “update”, “delete”] }
],
roles: []
})

# 2. 创建租户用户并分配角色
db.createUser({
user: “tenant1_read”,
pwd: “tenant1read123”,
roles: [“tenant_read_only”]
})

db.createUser({
user: “tenant1_write”,
pwd: “tenant1write123”,
roles: [“tenant_read_write”]
})

# 3. 测试访问控制
# 只读用户测试
mongosh –host 192.168.1.100 –port 27017 –username tenant1_read –password tenant1read123 –authenticationDatabase admin
use multi_tenant_db
db.fgedu_users.find({ tenantId: “tenant1” })
# 成功
db.fgedu_users.insertOne({ tenantId: “tenant1”, name: “User4”, age: 40 })
# 失败,没有插入权限

# 读写用户测试
mongosh –host 192.168.1.100 –port 27017 –username tenant1_write –password tenant1write123 –authenticationDatabase admin
use multi_tenant_db
db.fgedu_users.insertOne({ tenantId: “tenant1”, name: “User4”, age: 40 })
# 成功

Part05-风哥经验总结与分享

5.1 多租户架构最佳实践

风哥建议的多租户架构最佳实践:

  • 选择合适的隔离方案:根据租户数量、数据量和安全要求选择合适的隔离方案
  • 索引优化:为租户ID字段创建索引,提高查询性能
  • 访问控制:使用角色和权限管理,确保租户只能访问自己的数据
  • 监控与告警:监控每个租户的资源使用情况,设置告警阈值
  • 备份与恢复:为每个租户制定单独的备份策略
  • 审计日志:记录租户的操作日志,便于审计和故障排查
  • 性能隔离:设置租户的资源使用限制,防止单个租户影响其他租户
  • 扩展性:设计可扩展的架构,支持租户数量的增长

学习交流加群风哥QQ113257174

5.2 常见问题与解决方案

常见问题与解决方案:

  • 问题:租户数据隔离不严格
  • 解决方案:使用数据库级或集合级隔离,确保租户数据完全隔离
  • 问题:查询性能下降
  • 解决方案:为租户ID字段创建索引,优化查询条件
  • 问题:单个租户占用过多资源
  • 解决方案:设置租户的资源使用限制,监控资源使用情况
  • 问题:租户数量增长导致管理复杂
  • 解决方案:使用自动化脚本管理租户,建立租户管理系统
  • 问题:安全漏洞
  • 解决方案:定期更新MongoDB版本,使用SSL/TLS加密,设置强密码策略

更多视频教程www.fgedu.net.cn

注意事项

  • 选择合适的隔离方案,根据租户数量和安全要求
  • 为租户ID字段创建索引,提高查询性能
  • 使用角色和权限管理,确保租户只能访问自己的数据
  • 监控每个租户的资源使用情况,设置告警阈值
  • 为每个租户制定单独的备份策略
  • 记录租户的操作日志,便于审计和故障排查
  • 设置租户的资源使用限制,防止单个租户影响其他租户
  • 设计可扩展的架构,支持租户数量的增长

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息