MST
星途 面试题库

面试题:设计一个复杂场景下ElasticSearch模糊匹配容错处理的架构

设想一个电商搜索场景,用户输入商品名称进行搜索,不仅要考虑拼写错误的容错(如将“笔记本电脑”误输为“笔计本电脑”),还要处理同义词(如“手机”和“移动电话”)以及多语言(如英文和中文混合搜索)的情况。请设计一个基于ElasticSearch的模糊匹配容错处理架构,详细描述索引结构设计、查询流程、以及如何通过配置和代码实现这些复杂的容错处理需求,同时说明该架构在高并发情况下的扩展性和稳定性如何保障。
41.1万 热度难度
数据库ElasticSearch

知识考点

AI 面试

面试题答案

一键面试

索引结构设计

  1. 字段类型选择
    • 对于商品名称字段,使用text类型。例如,在映射定义中:
    {
        "mappings": {
            "properties": {
                "product_name": {
                    "type": "text",
                    "analyzer": "my_custom_analyzer"
                }
            }
        }
    }
    
  2. 自定义分析器
    • 处理拼写错误:使用edgengram分词器来创建前缀和后缀的子词。例如:
    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "my_custom_analyzer": {
                        "tokenizer": "my_custom_tokenizer",
                        "filter": ["lowercase"]
                    }
                },
                "tokenizer": {
                    "my_custom_tokenizer": {
                        "type": "edge_ngram",
                        "min_gram": 2,
                        "max_gram": 10
                    }
                }
            }
        }
    }
    
    • 处理同义词:创建同义词文件(如synonyms.txt),内容格式为手机,移动电话,并在分析器中添加同义词过滤器:
    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "my_custom_analyzer": {
                        "tokenizer": "my_custom_tokenizer",
                        "filter": ["lowercase", "my_synonym_filter"]
                    }
                },
                "tokenizer": {
                    "my_custom_tokenizer": {
                        "type": "edge_ngram",
                        "min_gram": 2,
                        "max_gram": 10
                    }
                },
                "filter": {
                    "my_synonym_filter": {
                        "type": "synonym",
                        "synonyms_path": "synonyms.txt"
                    }
                }
            }
        }
    }
    
    • 处理多语言:可以使用icu_analyzer,它对多种语言有较好的支持。例如:
    {
        "settings": {
            "analysis": {
                "analyzer": {
                    "my_custom_analyzer": {
                        "type": "icu_analyzer",
                        "filter": ["my_synonym_filter"]
                    }
                },
                "filter": {
                    "my_synonym_filter": {
                        "type": "synonym",
                        "synonyms_path": "synonyms.txt"
                    }
                }
            }
        }
    }
    

查询流程

  1. 用户输入处理:接收用户输入的商品名称,传递给ElasticSearch查询接口。
  2. 查询构建
    • 使用match查询,并设置fuzziness参数来处理拼写错误。例如,在Java代码中:
    SearchRequest searchRequest = new SearchRequest("products_index");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("product_name", userInput)
       .fuzziness(Fuzziness.AUTO);
    searchSourceBuilder.query(matchQueryBuilder);
    searchRequest.source(searchSourceBuilder);
    
    • 由于分析器在索引和查询时都会应用同义词,所以同义词处理是自动的。对于多语言,由于icu_analyzer的使用,也能较好地处理混合搜索情况。
  3. 结果返回:ElasticSearch执行查询后,将匹配的商品信息返回给应用层展示给用户。

配置和代码实现

  1. 配置
    • 在ElasticSearch的config/elasticsearch.yml文件中,可以设置集群相关配置,如节点数量、分片和副本数等,以适应高并发。例如:
    cluster.name: my_ecommerce_cluster
    node.name: node - 1
    network.host: 0.0.0.0
    http.port: 9200
    discovery.seed_hosts: ["node - 1", "node - 2"]
    cluster.initial_master_nodes: ["node - 1", "node - 2"]
    index.number_of_shards: 3
    index.number_of_replicas: 2
    
  2. 代码实现:以Java为例,使用Elasticsearch Java High - Level REST Client。
    • 引入依赖:
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch - rest - high - level - client</artifactId>
        <version>7.10.2</version>
    </dependency>
    
    • 构建客户端并执行查询:
    RestHighLevelClient client = new RestHighLevelClient(
        RestClient.builder(
            new HttpHost("localhost", 9200, "http")));
    // 构建查询如上述查询构建部分
    SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
    client.close();
    

高并发扩展性和稳定性保障

  1. 扩展性
    • 水平扩展:通过增加ElasticSearch节点来提高集群的处理能力。可以根据业务增长情况,逐步添加节点到集群中,ElasticSearch会自动重新分配分片,平衡负载。例如,在云环境中,可以轻松地启动新的EC2实例作为ElasticSearch节点。
    • 索引分片:合理设置索引的分片数,在高并发情况下,每个分片可以并行处理查询请求,提高整体查询性能。如上述配置中设置index.number_of_shards: 3,可以根据数据量和并发量调整该值。
  2. 稳定性
    • 副本机制:设置索引的副本数,如index.number_of_replicas: 2,当某个节点出现故障时,副本分片可以接替故障节点的工作,保证数据的可用性和查询的正常执行。
    • 监控和预警:使用Elasticsearch的监控工具(如Elasticsearch Monitoring),实时监控集群的健康状态、节点负载、索引性能等指标。设置预警规则,当指标超出阈值时及时通知运维人员进行处理,避免出现严重故障影响业务。
    • 负载均衡:在应用层和ElasticSearch集群之间部署负载均衡器(如Nginx),将高并发的查询请求均匀分配到各个ElasticSearch节点上,防止单个节点过载。