复制 MongoDB + spring-data-mongodb

问题描述 投票:0回答:2

有一个复制的 mongodb(mongodb-1 - 主数据库,mongodb-2 - 辅助数据库,mongodb-3 - 辅助数据库)。 该应用程序通过 spring-boot-starter-data-mongodb 运行。

服务:

public class FooBarService {
  private FooBarRepository repository;

  public FooBar method1() {
    return repository.someQuery();
  }
  
  public FooBar method2() {
    return repository.someQuery();
  }
}

存储库:

public interface FooBarRepository extends MongoRepository<FooBar, String> {
  FooBar someQuery();
}

我的问题是,让 method1 从 mongo 副本集中的主要参与者读取,method2 从 mongo 副本集中的次要参与者读取有多好?

想找到某种方法在服务级别管理此问题(类似于@Transactional,但选择一个mongo副本集成员)。

您能告诉我这方面有什么解决方案吗?

java spring mongodb spring-data-mongodb mongodb-replica-set
2个回答
3
投票

解决方案1:
@Meta
注释

如果您想继续使用存储库接口,您可以使用

@Meta
注释来注释查询方法定义,该注释允许您传递标志以指示从辅助 mongodb 成员读取。

public interface FooBarRepository extends MongoRepository<FooBar, String> {

  @Query("{}")
  @Meta(flags = Meta.CursorOption.SECONDARY_READS)
  FooBar someQuery();
}

但是您无法从服务级别控制该标志。您必须创建 2 种查询方法:一种带有标志,一种不带有标志。就像

someQueryFromSecondary()
someQueryFromPrimary()

解决方案 2:使用
MongoTemplate

另一种选择是直接使用

MongoTemplate
并在
Query
上设置标志。

public void someQuery(boolean readFromSecondary) {
    var query = Query.query(Criteria.where("someKey").is("1"));

    if (readFromSecondary) {
        query.allowSecondaryReads();
    }

    return mongoTemplate.findOne(query, FooBar.class);
}

无论您选择哪种解决方案:请注意,从次要成员读取可能会导致检索过时的数据。 考虑查看 mongodb 文档。


0
投票

这已经有所改变。 如果您使用 Spring 的 Repo 接口,则只需使用 @ReadPreference 即可。 像这样:

public interface SearchRepository extends MongoRepository<SearchItem, String>
{
    @ReadPreference("secondaryPreferred")
    public Optional<SearchItem> findById(String id);

如果你使用Spring的MongoOperations,你可以这样做。

    AggregationOptions aggOps = AggregationOptions.builder().readPreference(
        com.mongodb.ReadPreference.secondaryPreferred()).build();
                
    Aggregation agg = Aggregation.newAggregation(match, buildRuntimeProjection()).
        withOptions(aggOps);

如果您希望代码中的所有读取都使用特定的读取首选项,您只需将其附加到您的 url 字符串即可。 即“readPreference=secondaryPreferred”。 即您的 applications.properties 文件中类似于以下内容。

spring.data.mongodb.uri=mongodb://localhost:27017,localhost:27018,.../dbName?authSource=admin&readPreference=secondaryPreferred
© www.soinside.com 2019 - 2024. All rights reserved.