工作中的点点滴滴:SpringBoot集成Elasticsearch索引多租户

背景:

  供应商系统是一套典型的saas系统,所以我们在使用Elasticsearch的过程中,也就遇到了如何把Elasticsearch中的索引也通过不同的供应商code也就是租户信息来区分来。

技术实现:

  方案一:每个租户都有一套自己的Elasticsearch:这是最难管理的,并且需要大量的devops自动化。 根据客户的不同,完全隔离客户可能是值得的,但这种情况很少发生

  方案二:每个租户的索引–,并且不需要额外的编码(您只需在查询的URL中参数化“ index”参数)。
  方案三:基于租户的路由–这意味着您将所有内容都放在一个群集中,但是将搜索路由配置为特定于租户,这使您可以在逻辑上隔离单个索引中的数据,代码的调整可能会比较大。

  通过对比采取最优的方案二来实现,首先我们先要定义文档结构:

@Data
@Document(indexName = "index_goods")
@ToString
@NoArgsConstructor
@Accessors(chain = true)
public class EsGoodsIndex implements Serializable {

    private static final long serialVersionUID = -6856471777036048874L;

    @Id
    @Schema(description = "商品skuId")
    private String id;

    /**
     * 商品id
     */
    @Schema(description = "商品Id")
    @Field(type = FieldType.Text)
    private String goodsId;

    /**
     * 商品名称
     */
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    @Schema(description = "商品名称")
    private String goodsName;

    /**
     * 商品编号
     */
    @Field(type = FieldType.Keyword)
    @Schema(description = "商品编号")
    private String sn;

    /**
     * 卖家id
     */
    @Field(type = FieldType.Text)
    @Schema(description = "卖家id")
    private String storeId;
}

@Document就是文档对应的缩影的名称,这里我们是需要调整成动态参数的,因为不同的租户过来,在读取这个值的时候应该是跟着租户走的。如果你的saas是一个租户一个计算节点,你就可以把indexName写在配置文件里面,通过@Document(indexName = "#{@elasticsearchProperties.indexPrefix}")来读取。

@Data
@Builder
@Component("elasticsearchProperties")
@NoArgsConstructor
@AllArgsConstructor
@ConfigurationProperties(prefix = "data.elasticsearch")
public class ElasticsearchProperties {

    /**
     * 索引
     */
    private String indexPrefix;
}

因为我的saas服务是公用一个计算节点,所以这里需要调整通过运行时来取值的。

@Component("indexNameGenerator")
public class IndexNameGenerator {
    public String commonIndex() {
        //根据租户生成index
        String date = TenantContext.getTenantId();
        return date + "_mall_" + EsSuffix.GOODS_INDEX_NAME;
    }
}

在文档的@Document里面的赋值就ok了,这样在运行时就可以获取到对应的租户信息,和对应的索引关联。

@Document(indexName = "#{@indexNameGenerator.commonIndex()}")

这个@Document是支持Spel的,所以通过Spel这里就可以想怎么动态就怎么动态了,不熟悉Spel的,请移步这里 。

 

posted @ 2021-01-26 11:07  小杨ABC  阅读(615)  评论(0编辑  收藏  举报