使用 spring-data-elasticsearch 的多租户

Posted

技术标签:

【中文标题】使用 spring-data-elasticsearch 的多租户【英文标题】:Multitenancy with spring-data-elasticsearch 【发布时间】:2014-04-19 13:54:34 【问题描述】:

有什么方法可以让 spring-data-elasticsearch 用于多租户应用程序?

我已经让它在没有多租户的情况下工作,但我不知道如何为每个租户拥有多个索引或多个节点?我想知道是否有任何方法可以为每个租户定义不同的索引名称或在我的实体类中添加瞬态属性,该属性用@Document(...) 正确注释。当我试图解决这个问题时,@Transient 也被标记在ElasticSearchRepository 中。 有什么想法吗?

【问题讨论】:

您能详细说明一下吗?当您说 multi tanant 时,是用于搜索多个索引吗? 是的,我希望每个租户都有多个索引。使用 spring-data-elasticsearch 我还没有找到任何这样的解决方案。所以任何其他解决方案,如多节点或任何适合我的解决方案 你想在单节点架构中配置弹性搜索,其中多个用户@一次[或]多节点架构?? 具有多个租户的单节点架构 【参考方案1】:

这是我针对这个问题所做的解决方案。默认情况下,我们会添加一个带有@Document 的 POJO 注释的索引,这没关系。但是在某些情况下,我们希望每个客户端有不同的索引,所以我决定自己创建它们。我使用 ElasticSearch 模板为不同的租户创建索引,而不是依赖 Spring Data ElasticSearch repo 进行保存。这就是我所做的

    IndexQuery indexQuery = new IndexQueryBuilder()
                        .withId("ID")
                        .withIndexName("yourtenant")
                        .withType("yourtype")
                        .withObject(obj)
                        .build();

    es.index(indexQuery)

【讨论】:

Elasticsearch 的第一条诫命:“你不能在你的类映射中使用 'type'(在 95% 的情况下 - 有继承和时间序列数据等例外情况)”。请参阅下面的答案。【参考方案2】:

首先,您必须了解 Elasticsearch(尤其是 Lucene)如何存储您的数据。

Elasticsearch 的命名约定“index”和“type”有点误导,很可能不是你最初想的那样!


如果您在 Elasticsearch 的索引中创建类型 (id, field1, field2),它将创建类似于 SQL 表的内容:

id     | field1 | field2
-------------------------
string | int    | boolean

您可能期望的是,当您向该索引添加第二种类型 (id, type2field) 时会发生什么。索引映射将变为:

id     | field1 | field2  | type2field
--------------------------------------
string | int    | boolean | string

会发生这种情况,因为没有 没有 类型映射 - 即使 Elasticsearch 会让它看起来像那样。 只有索引级别的映射!这样,您很可能最终会得到很多空字段。


虽然一般来说,特别是对于多租户设置,您应该为每个类创建一个 index - 不是类型!您应该使用类型来分隔相似形状的数据,即为您的租户使用类型。或者在您的映射中添加一个附加字段以识别租户。


在此处了解更多信息:https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping.html#_type_takeaways

【讨论】:

【参考方案3】:

我已经解决了这个问题。这可能不是最好的解决方案,但我没有找到其他任何东西。 我已将字段tenantName 添加到我的索引类中,并用注释@javax.persistence.Transient 而不是@org.springframework.data.annotation.Transient 对其进行标记。之后,我将进行搜索查询,条件是租户必须是当前用户所属的租户。

【讨论】:

【参考方案4】:

我发现了一个使用 SpEL 的非常简单的解决方案,用于为

等索引添加前缀
@Document(indexName = "#@prefixProvider.getPrefix()_foo", type="bar")

prefixProvider 只是一个普通的春豆。

【讨论】:

以上是关于使用 spring-data-elasticsearch 的多租户的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)