1. 首页 > ElasticSearch教程 > 正文

ElasticSearch教程FG041-ElasticSearch多租户架构实战

内容简介:本文档风哥主要介绍ElasticSearch多租户架构的设计与实现方法,包括索引隔离、文档隔离、集群隔离等方案,以及多租户管理和安全控制。通过学习本文,您将掌握如何构建一个安全、高效的ElasticSearch多租户架构。风哥教程参考ElasticSearch官方文档Security部分。

Part01-基础概念与理论知识

1.1 多租户架构概述

多租户架构是指在一个系统中同时为多个租户(客户)提供服务的架构模式。在ElasticSearch中,多租户架构可以通过以下方式实现:

  • 索引隔离:为每个租户创建独立的索引
  • 文档隔离:在同一个索引中通过字段区分不同租户的文档
  • 集群隔离:为每个租户创建独立的ElasticSearch集群

1.2 多租户架构模式

多租户架构模式包括:

  • 共享模式:多个租户共享同一个索引,通过字段区分
  • 隔离模式:每个租户有独立的索引
  • 混合模式:根据租户需求混合使用共享和隔离模式

1.3 多租户架构优势

多租户架构的优势包括:

  • 资源共享:多个租户共享硬件资源,降低成本
  • 管理简化:集中管理多个租户,简化运维
  • 扩展性好:可以轻松添加新租户
  • 隔离性强:租户之间相互隔离,提高安全性
  • 灵活性高:可以根据租户需求进行定制

Part02-生产环境规划与建议

2.1 多租户架构设计

多租户架构设计建议:

  • 根据租户规模选择隔离方案:大型租户使用独立索引,小型租户使用共享索引
  • 合理规划索引命名:使用统一的命名规范,如 tenant-{tenant_id}-{index_name}
  • 设置合理的分片策略:根据租户数据量设置合适的分片数
  • 考虑数据生命周期:为不同租户设置不同的数据保留策略
  • 监控与告警:为每个租户设置独立的监控和告警

2.2 资源隔离策略

资源隔离策略建议:

  • 内存隔离:通过JVM堆大小限制每个租户的内存使用
  • CPU隔离:通过线程池配置限制每个租户的CPU使用
  • 磁盘隔离:通过索引配额限制每个租户的磁盘使用
  • 网络隔离:通过网络带宽限制每个租户的网络使用
  • 查询隔离:通过查询限制防止单个租户占用过多资源

2.3 安全与权限控制

安全与权限控制建议:

  • 启用安全功能:启用ElasticSearch的安全功能,如X-Pack Security
  • 创建租户用户:为每个租户创建独立的用户
  • 设置角色权限:为每个租户设置合适的角色和权限
  • 使用API密钥:为每个租户生成API密钥,用于身份验证
  • 加密传输:启用SSL/TLS加密,保护数据传输安全

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

3.1 索引隔离方案

索引隔离方案:

# 1. 为每个租户创建独立索引
# 租户1
curl -X PUT “http://192.168.1.10:9200/tenant-1-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
}
}
}
}’

# 租户2
curl -X PUT “http://192.168.1.10:9200/tenant-2-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
}
}
}
}’

# 2. 为租户创建用户和角色
# 创建租户1用户
curl -X POST “http://192.168.1.10:9200/_security/user/tenant1” -H “Content-Type: application/json” -d ‘{
“password”: “tenant1_password”,
“roles”: [“tenant1_role”]
}’

# 创建租户1角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant1_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“tenant-1-*”],
“privileges”: [“all”]
}
]
}’

# 创建租户2用户
curl -X POST “http://192.168.1.10:9200/_security/user/tenant2” -H “Content-Type: application/json” -d ‘{
“password”: “tenant2_password”,
“roles”: [“tenant2_role”]
}’

# 创建租户2角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant2_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“tenant-2-*”],
“privileges”: [“all”]
}
]
}’

3.2 文档隔离方案

文档隔离方案:

# 1. 创建共享索引
curl -X PUT “http://192.168.1.10:9200/shared-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 2
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
},
“tenant_id”: {
“type”: “keyword”
}
}
}
}’

# 2. 插入不同租户的数据
# 租户1数据
curl -X POST “http://192.168.1.10:9200/shared-users/_doc/1” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “张三”,
“age”: 25,
“tenant_id”: “tenant1”
}’

# 租户2数据
curl -X POST “http://192.168.1.10:9200/shared-users/_doc/2” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “李四”,
“age”: 30,
“tenant_id”: “tenant2”
}’

# 3. 创建租户角色,限制只能访问自己的数据
# 创建租户1角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant1_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“shared-users”],
“privileges”: [“read”, “write”],
“query”: “{\”term\”: {\”tenant_id\”: \”tenant1\”}}”
}
]
}’

# 创建租户2角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant2_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“shared-users”],
“privileges”: [“read”, “write”],
“query”: “{\”term\”: {\”tenant_id\”: \”tenant2\”}}”
}
]
}’

3.3 集群隔离方案

集群隔离方案:

# 1. 为每个租户创建独立的ElasticSearch集群
# 租户1集群
# 配置elasticsearch.yml
cluster.name: tenant1-cluster
node.name: tenant1-node-1
network.host: 192.168.1.10
http.port: 9200
transport.port: 9300

# 租户2集群
# 配置elasticsearch.yml
cluster.name: tenant2-cluster
node.name: tenant2-node-1
network.host: 192.168.1.11
http.port: 9200
transport.port: 9300

# 2. 启动每个集群
# 启动租户1集群
/es/app/elasticsearch-8.10.0/bin/elasticsearch -d

# 启动租户2集群
/es/app/elasticsearch-8.10.0/bin/elasticsearch -d

# 3. 验证集群状态
# 检查租户1集群
curl -X GET “http://192.168.1.10:9200/_cluster/health?pretty”

# 检查租户2集群
curl -X GET “http://192.168.1.11:9200/_cluster/health?pretty”

3.4 多租户管理

多租户管理:

# 1. 租户管理脚本
vi /es/app/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() {
TENANT_ID=$1
TENANT_NAME=$2

echo “Creating tenant: $TENANT_NAME (ID: $TENANT_ID)”

# 创建租户索引
curl -X PUT “http://192.168.1.10:9200/tenant-${TENANT_ID}-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
}
}
}
}’

# 创建租户用户
curl -X POST “http://192.168.1.10:9200/_security/user/tenant${TENANT_ID}” -H “Content-Type: application/json” -d ‘{
“password”: “tenant${TENANT_ID}_password”,
“roles”: [“tenant${TENANT_ID}_role”]
}’

# 创建租户角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant${TENANT_ID}_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“tenant-${TENANT_ID}-*”],
“privileges”: [“all”]
}
]
}’

echo “Tenant $TENANT_NAME created successfully”
}

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

echo “Deleting tenant with ID: $TENANT_ID”

# 删除租户索引
curl -X DELETE “http://192.168.1.10:9200/tenant-${TENANT_ID}-*”

# 删除租户用户
curl -X DELETE “http://192.168.1.10:9200/_security/user/tenant${TENANT_ID}”

# 删除租户角色
curl -X DELETE “http://192.168.1.10:9200/_security/role/tenant${TENANT_ID}_role”

echo “Tenant with ID $TENANT_ID deleted successfully”
}

# 列出所有租户
list_tenants() {
echo “Listing all tenants…”

# 列出所有租户索引
curl -X GET “http://192.168.1.10:9200/_cat/indices/tenant-*?v”

# 列出所有租户用户
curl -X GET “http://192.168.1.10:9200/_security/user?pretty” | grep -E “tenant[0-9]+”
}

# 主函数
case $1 in
create)
create_tenant $2 $3
;;
delete)
delete_tenant $2
;;
list)
list_tenants
;;
*)
echo “Usage: $0 {create|delete|list} [tenant_id] [tenant_name]”
;;
esac

# 设置执行权限
chmod +x /es/app/scripts/tenant_management.sh

Part04-生产案例与实战讲解

4.1 索引隔离实战

索引隔离实战:

# 1. 创建租户管理脚本
vi /es/app/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() {
TENANT_ID=$1
TENANT_NAME=$2

echo “Creating tenant: $TENANT_NAME (ID: $TENANT_ID)”

# 创建租户索引
curl -X PUT “http://192.168.1.10:9200/tenant-${TENANT_ID}-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
}
}
}
}’

# 创建租户用户
curl -X POST “http://192.168.1.10:9200/_security/user/tenant${TENANT_ID}” -H “Content-Type: application/json” -d ‘{
“password”: “tenant${TENANT_ID}_password”,
“roles”: [“tenant${TENANT_ID}_role”]
}’

# 创建租户角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant${TENANT_ID}_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“tenant-${TENANT_ID}-*”],
“privileges”: [“all”]
}
]
}’

echo “Tenant $TENANT_NAME created successfully”
}

# 2. 创建租户
/es/app/scripts/tenant_management.sh create 1 “租户1”
/es/app/scripts/tenant_management.sh create 2 “租户2”

# 3. 验证租户创建
/es/app/scripts/tenant_management.sh list

# 4. 测试租户隔离
# 租户1登录
curl -u tenant1:tenant1_password -X GET “http://192.168.1.10:9200/tenant-1-users/_search?pretty”

# 租户2登录
curl -u tenant2:tenant2_password -X GET “http://192.168.1.10:9200/tenant-2-users/_search?pretty”

# 尝试访问其他租户的索引(应该失败)
curl -u tenant1:tenant1_password -X GET “http://192.168.1.10:9200/tenant-2-users/_search?pretty”

4.2 文档隔离实战

文档隔离实战:

# 1. 创建共享索引
curl -X PUT “http://192.168.1.10:9200/shared-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 3,
“number_of_replicas”: 2
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
},
“tenant_id”: {
“type”: “keyword”
}
}
}
}’

# 2. 插入测试数据
# 租户1数据
curl -X POST “http://192.168.1.10:9200/shared-users/_doc/1” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “张三”,
“age”: 25,
“tenant_id”: “tenant1”
}’

# 租户2数据
curl -X POST “http://192.168.1.10:9200/shared-users/_doc/2” -H “Content-Type: application/json” -d ‘{
“id”: 1,
“name”: “李四”,
“age”: 30,
“tenant_id”: “tenant2”
}’

# 3. 创建租户角色
# 创建租户1角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant1_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“shared-users”],
“privileges”: [“read”, “write”],
“query”: “{\”term\”: {\”tenant_id\”: \”tenant1\”}}”
}
]
}’

# 创建租户2角色
curl -X POST “http://192.168.1.10:9200/_security/role/tenant2_role” -H “Content-Type: application/json” -d ‘{
“indices”: [
{
“names”: [“shared-users”],
“privileges”: [“read”, “write”],
“query”: “{\”term\”: {\”tenant_id\”: \”tenant2\”}}”
}
]
}’

# 4. 创建租户用户
# 创建租户1用户
curl -X POST “http://192.168.1.10:9200/_security/user/tenant1” -H “Content-Type: application/json” -d ‘{
“password”: “tenant1_password”,
“roles”: [“tenant1_role”]
}’

# 创建租户2用户
curl -X POST “http://192.168.1.10:9200/_security/user/tenant2” -H “Content-Type: application/json” -d ‘{
“password”: “tenant2_password”,
“roles”: [“tenant2_role”]
}’

# 5. 测试文档隔离
# 租户1查询
curl -u tenant1:tenant1_password -X GET “http://192.168.1.10:9200/shared-users/_search?pretty”

# 租户2查询
curl -u tenant2:tenant2_password -X GET “http://192.168.1.10:9200/shared-users/_search?pretty”

4.3 集群隔离实战

集群隔离实战:

# 1. 准备服务器
# 租户1集群:192.168.1.10
# 租户2集群:192.168.1.11

# 2. 配置租户1集群
vi /es/app/elasticsearch-8.10.0/config/elasticsearch.yml

cluster.name: tenant1-cluster
node.name: tenant1-node-1
network.host: 192.168.1.10
http.port: 9200
transport.port: 9300
discovery.seed_hosts: [“192.168.1.10”]
cluster.initial_master_nodes: [“tenant1-node-1”]

# 3. 配置租户2集群
vi /es/app/elasticsearch-8.10.0/config/elasticsearch.yml

cluster.name: tenant2-cluster
node.name: tenant2-node-1
network.host: 192.168.1.11
http.port: 9200
transport.port: 9300
discovery.seed_hosts: [“192.168.1.11”]
cluster.initial_master_nodes: [“tenant2-node-1”]

# 4. 启动集群
# 启动租户1集群
/es/app/elasticsearch-8.10.0/bin/elasticsearch -d

# 启动租户2集群
/es/app/elasticsearch-8.10.0/bin/elasticsearch -d

# 5. 验证集群状态
# 检查租户1集群
curl -X GET “http://192.168.1.10:9200/_cluster/health?pretty”

# 检查租户2集群
curl -X GET “http://192.168.1.11:9200/_cluster/health?pretty”

# 6. 为每个集群创建索引
# 租户1集群
curl -X PUT “http://192.168.1.10:9200/tenant1-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
}
}
}
}’

# 租户2集群
curl -X PUT “http://192.168.1.11:9200/tenant2-users” -H “Content-Type: application/json” -d ‘{
“settings”: {
“number_of_shards”: 2,
“number_of_replicas”: 1
},
“mappings”: {
“properties”: {
“id”: {
“type”: “integer”
},
“name”: {
“type”: “text”
},
“age”: {
“type”: “integer”
}
}
}
}’

4.4 多租户管理实战

多租户管理实战:

# 1. 使用租户管理脚本
# 创建租户
/es/app/scripts/tenant_management.sh create 1 “租户1”
/es/app/scripts/tenant_management.sh create 2 “租户2”
/es/app/scripts/tenant_management.sh create 3 “租户3”

# 列出租户
/es/app/scripts/tenant_management.sh list

# 删除租户
/es/app/scripts/tenant_management.sh delete 3

# 2. 监控租户资源使用
# 查看租户索引大小
curl -X GET “http://192.168.1.10:9200/_cat/indices/tenant-*?v&s=pri.store.size:desc”

# 查看租户查询性能
curl -X GET “http://192.168.1.10:9200/_nodes/stats/indices/search?pretty”

# 3. 为租户设置资源限制
# 设置索引配额
curl -X PUT “http://192.168.1.10:9200/_cluster/settings” -H “Content-Type: application/json” -d ‘{
“persistent”: {
“cluster”: {
“indices”: {
“quota”: {
“enabled”: “true”,
“default”: “50gb”
}
}
}
}
}’

# 为特定租户设置配额
curl -X PUT “http://192.168.1.10:9200/tenant-1-*/_settings” -H “Content-Type: application/json” -d ‘{
“index”: {
“quota”: {
“size”: “100gb”
}
}
}’

Part05-风哥经验总结与分享

5.1 多租户架构最佳实践

  • 根据租户规模选择隔离方案:大型租户使用独立索引或集群,小型租户使用共享索引
  • 合理规划索引命名:使用统一的命名规范,便于管理
  • 设置资源限制:为每个租户设置合理的资源限制,防止资源滥用
  • 加强安全控制:启用安全功能,设置合适的角色和权限
  • 监控与告警:为每个租户设置独立的监控和告警
  • 自动化管理:使用脚本自动化租户管理,减少人工操作

5.2 常见问题与解决方案

  • 资源竞争:设置资源限制,防止单个租户占用过多资源
  • 性能下降:优化查询,合理设置分片策略,增加硬件资源
  • 安全问题:加强安全控制,设置合适的角色和权限
  • 管理复杂:使用脚本自动化租户管理,减少人工操作
  • 数据隔离:确保租户之间数据严格隔离,防止数据泄露
  • 扩展性:设计可扩展的架构,便于添加新租户

5.3 性能优化建议

  • 分片策略优化:根据租户数据量设置合理的分片数
  • 缓存优化:合理配置缓存,提高查询性能
  • 查询优化:优化查询语句,避免全表扫描
  • 硬件优化:使用高性能硬件,如SSD存储
  • 网络优化:确保网络连接稳定,延迟低
  • 监控优化:建立完善的监控体系,及时发现性能问题

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

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

学习交流加群风哥QQ113257174

风哥提示:多租户架构是ElasticSearch在SaaS场景中的重要应用,需要合理设计和管理

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

from ElasticSearch视频:www.itpux.com

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

联系我们

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

微信号:itpux-com

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