Elasticsearch 正排索引

一、正排索引基础概念

在 Elasticsearch 中,正排索引用于存储完整的文档内容,以便通过文档ID 快速定位文档的字段值。正排索引通过 Doc Values 和 Store Fields 两种形式,为聚合、排序、脚本计算等场景提供高效支持。Doc Values 的列式存储设计显著优化了分析性能,而 Store Fields 提供了灵活的直接字段访问能力。

与倒排索引的对比:

  • 倒排索引:词项 → 文档列表(用于搜索)。
  • 正排索引:文档ID → 字段内容(用于聚合、排序、返回原始数据)。

二、正排索引基本结构

Elasticsearch 中的正排索引(正向索引)主要通过两种机制实现:Doc Values 和 Stored Fields。以下面两个文档为例:

  • 文档内容
    • 文档id为 1:

      bash 复制代码
      {
        "title": "Elasticsearch Guide",
        "author": "John Doe",
        "year": 2023,
        "tags": ["search", "database"]
      }
    • 文档id为 2:

      bash 复制代码
      {
        "title": "Introduction to Elasticsearch",
        "author": "Jane Smith",
        "year": 2022,
        "tags": ["tutorial", "search"]
      }
  1. Doc Values 结构(列式存储)

    Doc Values 是 Elasticsearch 默认的正排索引实现方式,采用列式存储结构。

    • 设计目标:支持高效的列式存储(Column-oriented),用于聚合(Aggregations)、排序(Sorting)、脚本计算等。

    • 核心特点:

      • 列式存储:按字段垂直存储,而非按文档水平存储。
      • 默认启用:所有不支持text类型的字段默认开启。
      • 磁盘存储:存储在磁盘,但会被OS缓存到文件系统缓存。
    • 适用场景:

      • 数值、日期、关键字(Keyword)等非文本字段。
      • 默认启用(可通过 mapping 的 doc_values: false 关闭)。
    • 存储结构:

      • 每个字段单独存储为一列,所有文档的该字段值按DocID顺序排列。
      • 列式存储优势:
        • 高效聚合:列式存储适合聚合计算。
        • 内存友好:可以只加载需要的列。
        • 压缩存储:使用多种压缩技术减少空间占用。
        • 缓存友好:CPU缓存命中率高。
      文档 ID(DocID) 字段名
      1 value1
      2 value2

      以year字段为例,Doc Values 结构如下:

      文档 ID(DocID) year
      1 2023
      2 2022
  2. Stored Fields 结构(行式存储)

    Stored Fields 存储原始文档的完整字段值,用于_source和显式标记为store的字段。

    • 设计目标:存储字段的原始值(如文本内容),用于直接返回特定字段(而非整个 _source)。

    • 核心特点:

      • 行式存储:按文档存储完整数据。
      • 按需启用:需要通过"store": true显式配置。
      • 原始格式:保留字段原始值。
    • 适用场景:

      • 需要频繁返回少量字段(避免解析整个 _source)。
      • 默认不启用(需在 mapping 中显式设置 "store": true)。
    • 存储结构:

      • 按字段存储原始值,类似传统数据库的行存储。
      • 通过 stored_fields 参数指定需要返回的字段。
      文档 ID(DocID) 字段名 字段值
      1 title "Elasticsearch Guide"
      1 author "John Doe"
      1 year 2023
      1 tags ["search", "database"]
      2 title "Introduction to Elasticsearch"
      2 author "Jane Smith"
      2 year 2022
      2 tags ["tutorial", "search"]
  3. 正排索引的 JSON 表示

    bash 复制代码
    {
      "documents": [
        {
          "doc_id": 1,
          "fields": {
            "title": "Elasticsearch Guide",
            "author": "John Doe",
            "year": 2023,
            "tags": ["search", "database"]
          }
        },
        {
          "doc_id": 2,
         "fields": {
            "title": "Introduction to Elasticsearch",
            "author": "Jane Smith",
            "year": 2022,
            "tags": ["tutorial", "search"]
          }
        }
      ],
      "doc_values": {
        "year": [
          {"doc_id": 1, "value": 2023},
          {"doc_id": 2, "value": 2022}
        ],
        "tags": [
          {"doc_id": 1, "value": "search"},
          {"doc_id": 1, "value": "database"},
          {"doc_id": 2, "value": "tutorial"},
          {"doc_id": 2, "value": "search"}
        ]
      }
    }

三、正排索引的构建过程

Elasticsearch 的正排索引主要通过 Doc Values 和 Stored Fields 两种机制实现,它们的构建过程有所不同。以下是完整的构建流程:

  1. Doc Values 构建过程

    • 阶段一:内存缓冲

      1. 文档解析:

        • 根据字段映射定义解析文档各字段值。
        • 对非text类型字段自动准备构建Doc Values。
      2. 内存缓冲区:

        bash 复制代码
        // 伪数据结构示例
        Map<FieldName, List<DocValueEntry>> buffer = {
          "price": [(doc1, 100), (doc2, 200), ...],
          "city": [(doc1, "北京"), (doc2, "上海"), ...]
        }
    • 阶段二:列式存储转换

      1. 字典编码:

        • 对字符串等离散值创建唯一值字典。

          bash 复制代码
          // city字段示例
          Dictionary: ["北京", "上海", "广州"]
      2. 值映射:

        • 将原始值替换为字典序数。

          bash 复制代码
          // 原始值 → 编码值
          "北京" → 0
          "上海" → 1
          "北京" → 0
          "广州" → 2
      3. 列式存储:

        • 按字段组织数据,与文档分离。

          bash 复制代码
          price列: [100, 200, 150, ...]
          city列: [0, 1, 0, 2, ...]  // 使用字典编码后的值
    • 阶段三:磁盘持久化

      1. 文件生成:
        • 生成.dvd(数据值)和.dvm(元数据)文件。
        • 使用紧凑的二进制格式。
      2. 压缩处理:
        • 数值类型:增量编码 + 位压缩
        • 字符串类型:前缀压缩
      3. 索引构建:
        • 创建字段值到文档的快速访问索引。
        • 对排序字段构建B-tree类结构加速范围查询。
  2. Stored Fields 构建过程

    • 阶段一:原始文档处理

      1. 字段筛选:

        • 包含_source字段
        • 包含显式设置"store": true的字段
      2. 内存缓冲:

        bash 复制代码
        // 伪数据结构示例
        List<StoredDocument> buffer = [
          {doc1, {"title": "ES指南", "content": "..."}},
          {doc2, {"title": "大数据", "content": "..."}}
        ]
    • 阶段二:文档块组织

      1. 分块处理:
        • 将多个文档打包为一个块(通常4-32KB)
        • 块内文档连续存储
      2. 压缩处理:
        • 使用LZ4算法压缩每个块
        • 字段级压缩优化
    • 阶段三:磁盘存储

      1. 文件生成:
        • 生成.fdt(字段数据)和.fdm(字段元数据)文件
        • 存储文档原始JSON结构
      2. 指针构建:
        • 创建文档ID到磁盘位置的映射表

          bash 复制代码
          // 伪数据结构
          Map<DocID, (fileOffset, compressedSize)> = {
            1 → (0x1000, 1024),
            2 → (0x1400, 768)
          }
  3. 构建过程关键优化

    • 内存控制
      1. 缓冲限制:
        • 默认使用JVM堆外内存
        • 通过indices.memory.index_buffer_size配置(默认10%)
      2. 分段策略:
        • 内存缓冲满后生成新的段(segment)
        • 每个段包含独立的Doc Values
    • 并行构建
      1. 多线程处理:
        • 不同字段的Doc Values并行构建
        • 大型字段使用单独线程
      2. 异步持久化:
        • 内存数据异步刷盘
        • 通过refresh_interval控制(默认1秒)
  4. 构建过程示例

    假设索引以下文档:

    bash 复制代码
    [
      {"id":1, "title":"ES基础", "price":100, "city":"北京"},
      {"id":2, "title":"高级教程", "price":200, "city":"上海"}
    ]
    • Doc Values构建结果:

      bash 复制代码
      price字段:
        - 列数据: [100, 200]
        - 字典: 无(数值类型直接存储)
      
      city字段:
        - 字典: ["北京", "上海"]
        - 列数据: [0, 1] (字典序数)
    • Stored Fields构建结果:

      bash 复制代码
      Segment文件:
        - 文档1原始JSON + 文档2原始JSON
        - 压缩存储为连续数据块

四、正排索引的优势

正排索引作为Elasticsearch的关键组成部分,在特定场景下展现出显著优势,与倒排索引形成互补。以下是其主要优势的详细分析:

  1. 列式存储带来的性能优势
    • 高效聚合计算
      • 相同字段的值连续存储,减少磁盘I/O
      • 直接对整列数据进行统计运算(如sum/avg/max/min)
      • 示例:计算1亿条销售记录的总金额,只需顺序读取price列
    • 更好的压缩率
      • 同列数据相似度高,压缩率可达60-70%
      • 支持多种压缩算法:LZ4、DEFLATE等
      • 显著减少磁盘占用和内存压力
    • CPU缓存友好
      • 现代CPU的缓存预取机制能更好预测列式数据访问模式
      • 相比行式存储,缓存命中率提升3-5倍
  2. 特定操作性能优势
    • 排序(Sorting)效率极高
      • 直接访问有序存储的列数据
      • 避免倒排索引需要"收集-排序"的两阶段操作
      • 测试显示比基于fielddata的排序快2-3倍
    • 聚合(Aggregation)加速
      • terms聚合直接扫描列值
      • 基数聚合(cardinality)使用列式统计
      • 比传统数据库的GROUP BY快10-100倍
    • 脚本访问优化
      • 脚本中访问doc values比_source解析快5-10倍
      • 示例:doc['price'].value * params.tax_rate
  3. 内存与资源管理优势
    • 堆外内存管理
      • 默认使用文件系统缓存而非JVM堆内存
      • 避免GC压力,稳定性提升
      • 可通过indices.queries.cache.size控制内存使用
    • 按需加载机制
      • 仅加载查询涉及的列
      • 支持内存映射(mmap)访问方式
      • 对比fielddata的全量加载更节省资源
    • 冷数据处理能力
      • 数据持久化在磁盘,适合不频繁访问的历史数据
      • 仍能保持较好性能(约为内存性能的60-70%)
  4. 特殊场景优化
    • 高基数字段处理

      • 全局序数(Global Ordinals)优化

        bash 复制代码
        {
          "mappings": {
            "properties": {
              "user_id": {
               "type": "keyword",
               "eager_global_ordinals": true
              }
            }
          }
        }
    • 地理空间数据

      • 地理距离聚合依赖doc values
      • 比传统GIS数据库快3-5倍
    • 二进制数据

      • 支持binary类型的快速读取
      • 适合存储加密数据或序列化对象

五、正排索引的局限性

尽管正排索引(Doc Values)在Elasticsearch中提供了诸多优势,但在实际应用中仍存在一些重要的局限性。

1. 存储开销限制
  1. 冗余存储
    • Doc Values 的默认启用:ES 默认对所有非文本字段(如 keyword、numeric、date)启用 Doc Values,即使某些字段不参与聚合或排序,仍会占用额外存储空间。
    • Store Fields 与 _source 的重复:若字段同时开启 store: true,则同一份数据会存储在 _source 和 Store Fields 中,导致存储冗余。
    • 示例:
      一个 keyword 字段默认生成以下存储结构:
      • 倒排索引(用于搜索)
      • Doc Values(用于聚合)
      • _source(原始值)
      • 若再设置 store: true,则额外存储一份原始值。
    • 优化建议:
      • 禁用不必要的 Doc Values:对无需聚合的字段设置 doc_values: false。
      • 避免滥用 store: true:优先通过 _source 获取字段,仅在需要快速访问时启用。
  2. 高基数字段的存储膨胀
    • 字典编码的局限性:对于高基数字段(如唯一 ID、哈希值),字典编码的压缩效率大幅下降,导致存储空间显著增加。
    • 示例:
      一个存储用户唯一 ID 的字段,若存在 1 亿个唯一值:
      • 字典编码需要维护 1 亿条映射关系。
      • 存储空间可能超过原始值的 2 倍。
    • 优化建议:
      • 对高基数字段禁用 Doc Values,改用倒排索引或其他存储方式。
      • 使用 eager_global_ordinals 优化聚合性能(预加载字典映射)。
2. 内存与性能的局限性
  1. 内存压力

    • 文件系统缓存依赖:Doc Values 依赖操作系统的 Page Cache 加载数据,若物理内存不足,频繁的磁盘 IO 会严重降低聚合性能。
    • 全局序号(Global Ordinals)的构建开销:高基数字段在聚合时需构建全局序号映射,首次查询延迟较高。
    • 示例:
      对包含 1 千万唯一值的 product_id 字段执行 terms 聚合:
      • 首次查询需构建全局序号,耗时可能达数百毫秒。
      • 后续查询复用缓存,但内存占用较高。
    • 优化建议:
      • 增加物理内存,确保文件系统缓存充足。
      • 对高频聚合的高基数字段启用 eager_global_ordinals,在段合并时预构建全局序号。
  2. 写入性能损耗

    • 正排索引的构建成本:写入文档时,ES 需同步构建倒排索引和正排索引(Doc Values/Store Fields),增加 CPU 和 IO 开销。
    • 实时性与吞吐量的权衡:高频写入场景下,正排索引的构建可能成为瓶颈,限制写入吞吐量。
    • 优化建议:
      • 对写入性能敏感的场景(如日志采集),关闭非必要字段的 Doc Values。
      • 使用更快的存储介质(如 SSD)提升 IOPS。
3. 功能支持的局限性
  1. 不支持文本字段的 Doc Values

    • 文本类型(text)的限制:text 字段默认不支持 Doc Values,因其内容经过分词处理,无法直接用于聚合或排序。
    • 优化建议:
      • 对需要聚合的文本字段,使用 keyword 类型子字段(Multi-fields):

        bash 复制代码
        PUT my_index
        {
          "mappings": {
            "properties": {
              "message": {
                "type": "text",
                "fields": {
                    "keyword": { 
                        "type": "keyword"  // 支持聚合
                    }
                }
              }
            }
          }
        }
  2. 不支持动态更新

    • 段不可变性:正排索引(Doc Values)随 Lucene 段(Segment)的生成而固化,更新文档需重新构建整个段,无法原地修改。
    • 近实时性限制:新写入的数据需通过 refresh 操作生成新段后,其正排索引才可见,默认延迟 1 秒。
    • 优化建议:
      • 调低 refresh_interval(如设置为 30s)减少段生成频率,平衡实时性与写入性能。
      • 对实时性要求高的场景,使用 GET /_doc/{id} 直接访问文档(依赖 _source 而非正排索引)。
4. 查询场景的局限性
  1. 无法高效支持全文搜索
    • 正排索引的定位:正排索引设计用于按文档访问字段值,而非通过词项定位文档。
    • 全文搜索依赖倒排索引:若仅依赖正排索引,全文搜索需遍历所有文档,性能极差。
    • 对比示例:
      • 倒排索引:搜索 "error" 直接定位倒排列表,复杂度 O(1)。
      • 正排索引:需遍历所有文档的 message 字段,复杂度 O(N)。
  2. 范围查询的局限性
    • 非数值字段的低效性:对非数值字段(如 keyword)执行范围查询(如 "a" TO "z"),需遍历字典映射,性能较差。
    • 优化建议:
      • 对需要范围查询的字符串字段,使用 text 类型分词后结合倒排索引。
      • 对数值或日期字段,优先使用 Doc Values 的范围查询优化。

六、正排索引的用途

Elasticsearch 的正排索引(Forward Index)主要用于支持高效的字段值访问和分析操作,与倒排索引(Inverted Index)形成互补,共同满足搜索、聚合、排序等复杂场景的需求。以下是正排索引的核心用途及其实际应用场景的详细说明:

  1. 聚合(Aggregations)

    • 用途说明:正排索引通过 列式存储(Doc Values) 高效支持聚合操作,如统计字段分布、计算平均值/总和等。

    • 优势:列式数据连续存储,便于批量遍历,压缩率高,减少磁盘 I/O。

    • 示例:

      bash 复制代码
      GET sales/_search
      {
        "aggs": {
          "total_sales": { "sum": { "field": "amount" } },
          "category_distribution": { "terms": { "field": "product_category.keyword" } }
        }
      }
      • amount 字段的 Doc Values 直接遍历所有值求和。
      • product_category.keyword 的 Doc Values 统计每个类别的文档数。
  2. 排序(Sorting)

    • 用途说明:通过正排索引快速访问字段值,对搜索结果按指定字段排序。

    • 优势:直接读取列式数据,避免解析 _source,性能显著提升。

    • 示例:

      bash 复制代码
      GET products/_search
      {
        "sort": [
          { "price": { "order": "desc" } },  // 使用 price 字段的 Doc Values
          { "_score": "desc" }
        ]
      }
  3. 脚本计算(Scripting)

    • 用途说明:在查询脚本中动态访问字段值,支持复杂计算逻辑。

    • 优势:通过 doc['field'].value 直接读取 Doc Values,延迟低。

    • 示例:

      bash 复制代码
      GET products/_search
      {
        "script_fields": {
          "discounted_price": {
            "script": "doc['price'].value * 0.9"  // 使用 price 字段的 Doc Values
          }
        }
      }
  4. 高亮显示(Highlighting)

    • 用途说明:快速返回字段原始内容,用于搜索结果的高亮展示。

    • 优势:若字段设置为 store: true,可直接从 Store Fields 读取数据,跳过解析 _source 的开销。

    • 示例:

      bash 复制代码
      GET articles/_search
      {
        "query": { "match": { "content": "Elasticsearch" } },
        "highlight": {
          "fields": { "content": {} }  // 从 Store Fields 或 _source 获取原始内容
        }
      }
  5. 部分字段返回(Stored Fields)

    • 用途说明:直接返回指定字段的原始值,无需解析完整 _source。

    • 优势:减少网络传输和 JSON 解析开销,提升响应速度。

    • 示例:

      bash 复制代码
      GET logs/_search
      {
        "stored_fields": ["timestamp", "status_code"],  // 从 Store Fields 获取
        "query": { "match_all": {} }
      }
  6. 范围查询(Range Queries)

    • 用途说明:对数值、日期等字段执行范围查询时,正排索引优化数据访问。

    • 优势:列式存储天然有序,支持快速范围过滤。

    • 示例:

      bash 复制代码
      GET logs/_search
      {
        "query": {
          "range": {
            "timestamp": {
              "gte": "2023-01-01",
              "lte": "2023-12-31"
            }
          }
        }
      }
  7. 字段值存在性检查(Exists Query)

    • 用途说明:快速判断某字段是否存在非空值。

    • 优势:直接遍历 Doc Values 检查字段值的非空性。

    • 示例:

      bash 复制代码
      GET users/_search
      {
        "query": {
          "exists": { "field": "email" }  // 检查 email 字段是否有值
        }
      }
  8. 地理空间分析(Geospatial Analytics)

    • 用途说明:对地理坐标字段(如 geo_point)进行聚合或距离计算。

    • 优势:Doc Values 支持高效的地理数据遍历。

    • 示例:

      bash 复制代码
      GET locations/_search
      {
        "aggs": {
          "heatmap": {
            "geohash_grid": { "field": "coordinates", "precision": 5 }
          }
        }
      }
  9. 多字段组合分析

    • 用途说明:在复杂分析场景中,联合使用多个字段的 Doc Values。

    • 示例:

      bash 复制代码
      GET sales/_search
      {
        "aggs": {
          "sales_by_region": {
            "terms": { "field": "region.keyword" },  // 使用 region 的 Doc Values
            "aggs": {
              "avg_amount": { "avg": { "field": "amount" } }  // 使用 amount 的 Doc Values
            }
          }
        }
      }
  10. 时序数据分析(Time Series)

    • 用途说明:针对时间序列数据(如日志、指标),利用 Doc Values 高效处理时间范围聚合。

    • 示例:

      bash 复制代码
      GET metrics/_search
      {
        "aggs": {
          "hourly_stats": {
            "date_histogram": {
              "field": "timestamp",
            "calendar_interval": "1h"
          },
           "aggs": { "avg_value": { "avg": { "field": "value" } } }
          }
        }
      }

七、正排索引的优化策略

Elasticsearch 的正排索引(Forward Index)优化策略需结合存储效率、查询性能、写入速度等多方面因素。以下是系统化的优化方案,涵盖配置调整、数据结构设计及硬件调优:

  1. 存储优化

    • 按需启用 Doc Values
      • 禁用非必要字段:对不参与聚合、排序的字段关闭 Doc Values。

        bash 复制代码
        PUT my_index/_mapping
        {
          "properties": {
            "log_message": {
              "type": "text",
              "doc_values": false  // 关闭聚合能力,减少存储
            }
          }
        }
      • 高基数字段特殊处理:唯一ID等字段建议禁用 Doc Values,改用倒排索引。

    • 避免冗余存储
      • 慎用 store: true:仅对高频访问字段(如标题、摘要)启用存储字段。

        bash 复制代码
        PUT my_index/_mapping
        {
          "properties": {
            "title": {
              "type": "text",
              "store": true  // 显式存储,用于快速返回
            }
          }
        }
      • 依赖 _source 作为主存储:默认通过 _source 返回数据,减少冗余。

    • 压缩优化
      • 数值类型优化:
        • 使用最小化数据类型(如 byte 替代 integer)。
        • 启用 index_options: docs 减少倒排索引开销(仅记录文档ID)。
      • 字符串类型优化:
        • 使用 keyword 类型代替 text 进行聚合。
        • 对长文本禁用 norms 和 index_options。
  2. 查询性能优化

    • 全局序号(Global Ordinals)预热

      • 启用 eager_global_ordinals:对高基数字段预加载字典映射,减少首次聚合延迟。

        bash 复制代码
        PUT my_index/_mapping
        {
          "properties": {
            "user_id": {
              "type": "keyword",
              "eager_global_ordinals": true  // 预加载字典
            }
          }
        }
    • 缓存策略

      • 聚合结果缓存:对重复查询使用 cache: true。

        bash 复制代码
        GET sales/_search
        {
          "aggs": {
            "total_sales": {
              "sum": { "field": "amount", "missing": 0 }
            }
          },
          "size": 0,
          "request_cache": true  // 启用查询缓存
        }
    • 分页优化

      • 避免深度分页:使用 search_after 替代 from/size,减少内存占用。
      • 聚合分页:对海量数据聚合使用 composite 分桶。
  3. 写入性能优化

    • 降低 Refresh 频率

      • 增大 refresh_interval,减少段生成频率:

        bash 复制代码
        PUT my_index/_settings
        {
          "index.refresh_interval": "30s"  // 默认1s,调整为30秒
        }
    • 批量写入

      • 使用 bulk API 批量提交数据,减少 IOPS 压力。
      • 控制单批次文档数(建议 5-15MB/批次)。
    • 关闭副本写入

      • 写入高峰期临时关闭副本,写入完成后再恢复:

        bash 复制代码
        PUT my_index/_settings
        {
          "index.number_of_replicas": 0
        }
  4. 数据结构与映射优化

    • 字段类型选择

      • 数值类型:优先使用 integer、short、byte 等最小化类型。
      • 时间类型:使用 date 而非 text 或 keyword。
      • 高维数据:地理位置使用 geo_point,IP地址使用 ip 类型。
    • 多字段(Multi-fields)设计

      • 对文本字段同时支持搜索和聚合:

        bash 复制代码
        PUT my_index/_mapping
        {
          "properties": {
            "message": {
              "type": "text",        // 支持全文搜索
              "fields": {
                "keyword": { 
                  "type": "keyword"  // 支持聚合
                }
              }
            }
          }
        }
    • 避免嵌套对象

      • 扁平化数据结构,减少 nested 类型使用(因其 Doc Values 效率较低)。
  5. 硬件与架构优化

    • 分片策略
      • 控制分片大小:单个分片建议 10-50GB(过小导致段过多,过大影响并行性)。
      • 预创建索引:对时序数据按时间滚动(如每日索引),避免分片膨胀。
    • 存储介质
      • 使用 SSD 提升 IOPS,尤其对高写入场景。
      • 确保足够内存,保障文件系统缓存(Page Cache)容量。
    • 冷热架构
      • 对历史数据迁移至冷节点(使用高压缩率存储),热节点专注实时查询。
相关推荐
TDengine (老段)6 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
这个懒人8 小时前
深入解析Translog机制:Elasticsearch的数据守护者
数据库·elasticsearch·nosql·translog
直裾10 小时前
Mapreduce的使用
大数据·数据库·mapreduce
LCY13311 小时前
spring 中的DAO是什么
运维·git·jenkins
wangjun515912 小时前
jenkins 参数化发布到服务器 publish over ssh、label、Parameterized publishing
服务器·ssh·jenkins
愿你天黑有灯下雨有伞12 小时前
Docker 安装 Elasticsearch 教程
运维·elasticsearch·docker
遇见火星12 小时前
自动化发布工具CI/CD实践Jenkins常用工具和插件的使用
运维·ci/cd·自动化·jenkins·自动化发布
麻芝汤圆12 小时前
使用 MapReduce 进行高效数据清洗:从理论到实践
大数据·linux·服务器·网络·数据库·windows·mapreduce
树莓集团13 小时前
树莓集团海南落子:自贸港布局的底层逻辑
大数据
不剪发的Tony老师13 小时前
Hue:一个大数据查询工具
大数据