Elasticsearch知识点

发布于:2025-05-22 ⋅ 阅读:(23) ⋅ 点赞:(0)

一、Elasticsearch 基础概念

1. 定位与特点
  • 分布式搜索引擎:基于 Lucene 构建,提供分布式、高扩展、高可用的实时搜索与数据分析能力。
  • 核心优势
    • 分布式架构,支持水平扩展(节点自动发现、负载均衡)。
    • 实时索引与搜索,数据写入后可被立即搜索。
    • 灵活的数据建模(JSON 文档存储,动态映射)。
    • 强大的聚合分析功能,支持复杂查询(如布尔查询、模糊查询、范围查询等)。
2. 核心术语
术语 含义描述
Cluster 集群,由一个或多个节点组成,共同存储数据并提供搜索服务。
Node 集群中的单个服务器实例,负责存储数据、处理请求。
Index 索引,逻辑上的数据集(类似关系型数据库中的 “数据库”),包含多个文档。
Type 旧版本(7.x 前)用于区分索引内不同类别的文档,7.x 后废弃,默认唯一类型为 _doc
Document 索引中的单个数据单元(类似关系型数据库中的 “行”),以 JSON 格式存储。
Field 文档中的字段(类似关系型数据库中的 “列”),每个字段有特定的数据类型。
Shard 索引的物理分片,一个索引可拆分为多个分片,分布在不同节点以实现分布式存储。
Replica 分片的副本,用于高可用性(故障恢复)和读扩展(分担查询压力)。

二、核心架构与原理

1. 分布式架构
  • 节点类型
    • 主节点(Master Node):负责集群状态管理(如创建索引、分配分片、追踪节点)。
    • 数据节点(Data Node):存储数据,处理数据相关操作(索引、搜索、聚合)。
    • 协调节点(Coordinating Node):路由请求,合并多个节点的查询结果(默认每个节点都是协调节点)。
    • 预处理节点(Ingest Node):对文档进行预处理(如数据转换、 enrichment)。
  • 分片机制
    • 主分片(Primary Shard):负责数据写入和读取,数量在索引创建时固定(默认 1 个)。
    • 副本分片(Replica Shard):主分片的副本,可在节点间动态分配。
    • 分片策略:通过哈希算法(如文档 ID 哈希)将数据分配到不同主分片,确保数据均衡。
2. 索引与搜索流程
  • 索引流程
    1. 文档被写入某个主分片,同步到副本分片。
    2. 数据先写入内存缓冲区(Buffer),定时生成 Segment(分段)并刷新到磁盘(Refresh 机制)。
    3. 多个 Segment 定期合并(Merge),减少磁盘 I/O 开销。
  • 搜索流程
    1. 协调节点将查询请求分发到相关分片(主分片或副本分片)。
    2. 各分片执行查询并返回结果(命中文档的 ID 和评分)。
    3. 协调节点合并结果,按评分排序后返回给客户端。
3. 倒排索引(Inverted Index)
  • 核心原理:Lucene 的底层实现,将文档中的关键词映射到包含该词的文档列表,用于快速检索。
  • 结构示例
    • 关键词 "elastic" → 文档列表 [Doc1, Doc3]
    • 关键词 "search" → 文档列表 [Doc1, Doc2]
  • 优势:通过分词、归一化(如小写、去重)等预处理,实现高效全文搜索。

三、常用操作与 API

1. 索引操作
  • 创建索引

    json

    PUT /my_index
    {
      "settings": {
        "number_of_shards": 3,        // 主分片数
        "number_of_replicas": 1       // 副本数
      },
      "mappings": {
        "properties": {
          "title": {"type": "text"},    // 文本类型(可分词)
          "price": {"type": "integer"}   // 数值类型
        }
      }
    }
    
  • 查看索引

    json

    GET /my_index
    
  • 删除索引

    json

    DELETE /my_index
    
2. 文档操作
  • 新增 / 更新文档
    • 按 ID 新增(若 ID 不存在则创建,存在则覆盖):

      json

      PUT /my_index/_doc/1
      {
        "title": "Elasticsearch Guide",
        "price": 99
      }
      
    • 自动生成 ID:

      json

      POST /my_index/_doc
      {
        "title": "Elasticsearch Basics",
        "price": 59
      }
      
  • 查询文档

    json

    GET /my_index/_doc/1
    
  • 删除文档

    json

    DELETE /my_index/_doc/1
    
3. 搜索与聚合查询
  • 简单搜索(Match Query)

    json

    GET /my_index/_search
    {
      "query": {
        "match": {
          "title": "elasticsearch"
        }
      }
    }
    
  • 布尔查询(Bool Query):组合多个查询条件(must/filter/should/must_not):

    json

    GET /my_index/_search
    {
      "query": {
        "bool": {
          "must": { "match": { "title": "search" } },
          "filter": { "range": { "price": { "lte": 100 } } }
        }
      }
    }
    
  • 聚合分析(Aggregation)

    json

    GET /my_index/_search
    {
      "aggs": {
        "avg_price": { "avg": { "field": "price" } },  // 计算平均价格
        "price_stats": { "stats": { "field": "price" } }  // 统计最大值、最小值等
      }
    }
    

四、数据建模与 Mapping

1. 数据类型
  • 核心类型
    • 文本类型(Text):可分词,用于全文搜索(如标题、内容)。
    • 关键字类型(Keyword):不可分词,用于精确匹配(如 ID、标签)。
    • 数值类型(Number):支持整数、浮点数(如 integerdouble)。
    • 日期类型(Date):存储日期时间(如 2023-10-01 或时间戳)。
    • 二进制类型(Binary):存储二进制数据(如文件内容,需配合 Base64 编码)。
  • 复杂类型
    • 对象类型(Object):嵌套文档(类似 JSON 对象)。
    • 数组类型(Array):同一字段存储多个值(如 [1, 2, 3] 或 ["apple", "banana"])。
2. 动态映射(Dynamic Mapping)
  • 自动创建字段:当写入文档时,若字段未定义,ES 会根据数据类型自动生成 Mapping。
  • 控制动态映射:通过 dynamic 参数禁用自动映射:

    json

    PUT /my_index
    {
      "mappings": {
        "dynamic": "strict"  // 禁止自动创建新字段,写入未知字段会报错
      }
    }
    
3. 分词器(Analyzer)
  • 作用:将文本拆分为 tokens(词元),用于倒排索引构建。
  • 内置分词器
    • 标准分词器(Standard Analyzer):按词边界拆分(默认,适合英文)。
    • 中文分词器:需安装插件(如 ik-analyzer),支持按词语拆分(如 “Elasticsearch 教程”→ ["Elasticsearch", "教程"])。
  • 自定义分词器:组合字符过滤器、分词器、词元过滤器:

    json

    PUT /my_index
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "my_analyzer": {
              "type": "custom",
              "tokenizer": "standard",
              "filter": ["lowercase"]  // 转换为小写
            }
          }
        }
      }
    }
    

五、集群管理与高可用性

1. 集群发现与节点配置
  • 单播(Unicast):手动指定可连接的节点列表(默认方式,避免广播风暴):

    yaml

    # elasticsearch.yml 配置
    cluster.name: my-es-cluster
    node.name: node-1
    network.host: 0.0.0.0
    discovery.seed_hosts: ["node-1:9300", "node-2:9300"]  # 种子节点
    
  • 自动发现:通过云服务(如 AWS、阿里云)或 Kubernetes 实现节点自动加入集群。
2. 分片分配策略
  • 默认策略:ES 自动平衡分片在节点间的分布,确保主分片和副本分片不位于同一节点。
  • 自定义策略:通过节点属性(如 node.attr.rack)和分片分配规则,控制分片分布:

    json

    PUT /my_index/_settings
    {
      "index.routing.allocation.require.rack": "rack1"  // 要求分片分配到属性为 rack1 的节点
    }
    
3. 故障恢复与副本机制
  • 高可用性保障
    • 当主节点故障时,集群自动选举新的主节点(基于 Quorum 机制,需超过半数节点存活)。
    • 主分片故障时,副本分片自动升级为主分片,确保数据不丢失。
  • 副本调整:动态增加或减少副本数:

    json

    PUT /my_index/_settings
    {
      "number_of_replicas": 2  // 调整副本数为 2
    }
    

六、性能优化与调优

1. 硬件与配置优化
  • 节点角色分离:主节点、数据节点、协调节点分离,避免资源竞争。
  • 内存配置
    • 单个节点内存不超过 32GB(受限于 Lucene 的内存压缩机制)。
    • 预留至少 50% 内存给操作系统文件缓存(Lucene 依赖磁盘缓存提升查询性能)。
  • 磁盘选择:使用 SSD 存储热数据,HDD 存储冷数据(配合冷热节点架构)。
2. 索引优化
  • 减少分片数量:单个分片建议大小为 10-50GB,避免过多分片导致集群状态维护开销。
  • 预分配主分片:创建索引时指定合理的主分片数(如预计数据量 1TB,主分片数设为 20,每个分片约 50GB)。
  • 禁用副本写入:写入大量数据时,先将副本数设为 0,写入完成后再恢复(减少网络传输开销):

    json

    PUT /my_index/_settings
    {
      "number_of_replicas": 0
    }
    
3. 查询优化
  • 优先使用 Filter 而非 Query:Filter 结果可缓存,性能更高(如范围查询、布尔查询中的 filter 子句)。
  • 批量操作(Bulk API):通过一次请求批量处理多个文档(索引、删除等),减少网络往返次数:

    json

    POST /_bulk
    {"index":{"_index":"my_index","_id":"1"}}
    {"title":"Bulk Example 1","price":100}
    {"index":{"_index":"my_index","_id":"2"}}
    {"title":"Bulk Example 2","price":200}
    
  • 避免深翻页(Deep Pagination):当查询结果超过数万条时,使用 Scroll API 或 Search After 替代 from + size,避免内存溢出。

七、生态工具与集成

1. 数据摄入工具
  • Logstash:用于日志收集、处理和传输(支持多种数据源,如文件、数据库、消息队列)。
  • Filebeat:轻量级日志采集器,配合 Logstash 或直接写入 ES。
  • Ingest Node Pipeline:在文档写入时通过预处理管道(Pipeline)实时转换数据(如提取字段、添加元数据)。
2. 可视化工具
  • Kibana:ES 官方可视化工具,支持仪表盘、图表、日志分析、告警配置等。
  • Grafana:与 ES 集成,用于监控数据可视化(需配置 ES 数据源)。
3. 客户端与集成
  • 官方客户端:支持 Java、Python、JavaScript(Node.js)、Go 等语言。
  • Spring Data Elasticsearch:Spring 框架集成 ES 的官方库,简化数据操作。
  • SQL 接口:通过 Elasticsearch SQL 或 Apache Hive/Spark 插件,使用 SQL 查询 ES 数据。

八、高级主题

1. 冷热架构(Hot-Warm-Cold)
  • 热节点:存储最近期数据,使用 SSD,支持高读写性能。
  • 温节点:存储中期数据,使用 HDD,性能中等。
  • 冷节点:存储历史数据,支持归档(如冻结合约),仅支持读取。
  • 策略配置:通过 Time-Based Index(按时间创建索引)和 ILM(索引生命周期管理)自动迁移数据。
2. 跨集群复制(CCR)
  • 作用:将一个集群(源集群)的数据实时复制到另一个集群(目标集群),用于灾备或读写分离。
  • 配置示例

    json

    PUT /_cluster/settings
    {
      "persistent": {
        "ccr": {
          "auto_follow": {
            "my_repo": {
              "source": "source_cluster",
              "remote_cluster": "remote_cluster"
            }
          }
        }
      }
    }
    
3. 安全与权限控制
  • 内置安全特性(需 X-Pack 插件):
    • 节点间 TLS 加密、客户端认证。
    • 基于角色的访问控制(RBAC),控制用户对索引、文档的操作权限。
    • 审计日志,记录用户操作。
  • 配置示例:启用基本认证:

    yaml

    xpack.security.enabled: true
    xpack.security.authc.accept_default_password: true  # 首次启动时生成默认密码
    

九、常见问题与排查

  1. 分片分配失败
    • 原因:磁盘空间不足、节点属性不匹配、副本与主分片在同一节点。
    • 排查:通过 GET /_cluster/health?pretty 查看集群状态,GET /_cat/shards 检查分片分布。
  2. 查询性能慢
    • 原因:分片数过多、未使用合适的分词器、查询语句复杂。
    • 优化:使用 Query Profiler 分析查询耗时,添加字段别名或索引。
  3. 集群脑裂(Split Brain)
    • 原因:网络分区导致主节点选举冲突。
    • 预防:设置 discovery.zen.minimum_master_nodes 为 (master节点数/2)+1,确保选举需要多数节点同意。

网站公告

今日签到

点亮在社区的每一天
去签到