← 返回首页
🗄️

Elasticsearch架构

📂 architecture ⏱ 1 min 200 words

Elasticsearch架构

倒排索引原理

Elasticsearch通过倒排索引实现全文检索,将文档分词后建立词项到文档ID的映射。

正排索引: doc1 → "Elasticsearch是搜索引擎"
倒排索引: "搜索引擎" → [doc1, doc3, doc5]
         "搜索"     → [doc1, doc2, doc3, doc4, doc5]
@Service
public class ProductSearchService {

    @Autowired
    private ElasticsearchOperations operations;

    public void indexProduct(Product product) {
        IndexCoordinates index = IndexCoordinates.of("products");
        operations.save(product, index);
    }

    public List<Product> search(String keyword) {
        Query query = new NativeQueryBuilder()
            .withQuery(QueryBuilders.multiMatchQuery(keyword, "name", "description")
                .type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
                .fuzziness(Fuzziness.AUTO))
            .withSort(Sort.by(Sort.Direction.DESC, "_score"))
            .withPageable(PageRequest.of(0, 20))
            .build();
        return operations.search(query, Product.class).stream()
            .map(SearchHit::getContent)
            .collect(Collectors.toList());
    }
}

分片策略

合理设置主分片和副本分片,平衡查询性能和存储容量。

PUT /products
{
  "settings": {
    "number_of_shards": 5,
    "number_of_replicas": 2,
    "refresh_interval": "30s"
  },
  "mappings": {
    "properties": {
      "name": { "type": "text", "analyzer": "ik_max_word" },
      "price": { "type": "double" },
      "category": { "type": "keyword" },
      "created_at": { "type": "date" }
    }
  }
}

集群架构

ES集群由Master节点、Data节点和Coordinating节点组成。

# elasticsearch.yml
cluster.name: my-cluster
node.name: node-1
node.roles: [master, data]
path.data: /data/elasticsearch
network.host: 0.0.0.0
discovery.seed_hosts: ["node-1:9300", "node-2:9300", "node-3:9300"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
@Configuration
public class ElasticsearchConfig {

    @Bean
    public ElasticsearchClient elasticsearchClient() {
        RestClient restClient = RestClient.builder(
            new HttpHost("localhost", 9200))
            .setRequestConfigCallback(config -> config
                .setConnectTimeout(5000)
                .setSocketTimeout(60000))
            .build();
        ElasticsearchTransport transport = new RestClientTransport(
            restClient, new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }
}

搜索优化

通过调整查询方式、使用filter缓存、优化mapping提升搜索性能。

public List<Product> optimizedSearch(String keyword, Double minPrice) {
    Query query = new NativeQueryBuilder()
        .withQuery(QueryBuilders.matchQuery("name", keyword))
        .withFilter(QueryBuilders.rangeQuery("price").gte(minPrice))
        .withTrackTotalHits(true)
        .withSourceFilter(FetchSourceFilter.of().includes("name", "price"))
        .withPageable(PageRequest.of(0, 20))
        .build();
    return operations.search(query, Product.class).getContent();
}