Elasticsearch 7中如何实现按组织划分索引的多租户数据隔离方案
Elasticsearch 7+ 多组织多业务数据隔离实现方案
Elasticsearch 7+ 废弃索引type后,官方推荐两种替代多type的思路:拆分独立索引、在文档内新增类型字段做区分,结合你需要按组织做数据隔离的需求,有以下三种可落地的方案:
方案1:组织+业务双维度索引拆分(隔离性最高,适合中大型规模)
直接将原方案的「单组织索引+type区分业务」调整为每个组织下的每种业务对应独立索引,统一索引命名规范为 {业务类型}_{组织唯一ID},比如任务类索引命名为 task_org001、笔记类索引命名为 note_org001。
- 优势:
- 不同组织、不同业务的数据完全物理隔离,彻底避免跨组织、跨业务串数据的风险
- 每个索引可独立配置分片数、生命周期、分词规则,适配不同业务的特性
- 查询时直接指定对应索引即可,不需要额外加业务类型过滤条件,查询效率最高
- 劣势:
- 若组织和业务类型较多,索引数量会出现膨胀,需提前评估集群承载能力,ES单节点活跃分片数建议不超过「20 * 节点CPU核数」
- 适用场景:对数据隔离要求极高,组织数量在千级以内的场景
方案2:单组织索引内嵌业务标识(平衡隔离性和管理成本,适合中小规模)
保留「每个组织对应一个独立索引」的规则,索引命名规范为 {组织唯一ID}_all,同一组织下所有业务的文档都存储在该索引中,在文档中新增固定字段 biz_type 标识业务类型,可选值为 task/note/doc 等。查询时除指定对应组织的索引外,额外加 biz_type 过滤条件即可,示例查询逻辑:
{ "index": "org001_all", "query": { "bool": { "filter": [ {"term": {"biz_type": "task"}}, // 其他业务查询条件 ] } } }
- 优势:
- 索引数量仅等于组织量级,远低于方案1,集群管理成本更低
- 保留了组织级的物理隔离,不会出现跨组织数据泄露
- 同一组织下的跨业务全局搜索无需跨多个索引查询,实现成本极低
- 劣势:
- 不同业务的字段可能出现冲突,需要提前统一索引映射规则,禁止动态映射,避免同一字段在不同业务中类型不一致
- 业务类型较多时单索引体积会偏大,需要定期归档冷数据
- 适用场景:有跨业务全局搜索需求,组织数量在万级以内的场景
方案3:全局单索引加双字段过滤(成本最低,适合超大量级SaaS)
如果组织数量超过十万级,建单组织索引的成本过高,可以选择全局单索引存储所有数据,在文档中新增 org_id 和 biz_type 两个字段分别标识所属组织和业务类型,所有查询强制带上 org_id 过滤条件。
注意必须开启ES的文档级安全(DLS)功能,给每个组织的访问角色配置强制过滤规则,避免业务代码漏写过滤条件导致跨组织数据泄露,DLS规则示例:{"query": {"term": {"org_id": "当前组织唯一ID"}}},配置后ES会自动给所有该角色发起的查询加上该过滤条件,无需业务代码处理
- 优势:
- 索引数量最少,集群管理成本极低
- 扩容无需随组织新增创建索引,适配组织数量高速增长的场景
- 劣势:
- 隔离性最低,靠权限规则保证数据隔离,出现问题的影响范围更大
- 单索引体积大,查询性能低于前两种方案
- 适用场景:组织数量极大,对数据隔离要求非顶级的轻量SaaS场景
落地注意事项
- 所有方案的索引命名、
org_id取值都要统一规范,org_id建议使用无规律的唯一字符串,不要用自增ID避免暴露业务规模 - 生产环境必须开启ES身份认证,严格限制不同角色的索引访问权限,禁止使用超级账号对接业务侧
- 采用方案2、3时必须提前统一管理索引映射,禁止动态字段映射,避免字段类型冲突导致查询异常
- 提前配置索引生命周期策略,冷数据自动归档到低配置节点,降低存储成本
内容的提问来源于stack exchange,提问作者Rajesh
相关产品推荐
相关产品推荐

