Go工程師體系課 009

其它一些功能

  • 個人中心
  • 收藏
  • 管理收貨地址(增刪改查)
  • 留言

拷貝inventory_srv--> userop_srv 查詢替換所有的inventory

Elasticsearch 深度解析文檔

1. 什麼是Elasticsearch

Elasticsearch是一個基於Apache Lucene構建的分佈式、RESTful搜索和分析引擎,能夠快速地存儲、搜索和分析海量數據。它是Elastic Stack(原ELK Stack)的核心組件。

2. MySQL搜索面臨的問題 - 深度剖析

2.1 性能低下問題詳解

問題現象:

-- 當數據量達到100萬條時,以下查詢可能需要數秒
SELECT * FROM products WHERE name LIKE '%手機%' OR description LIKE '%手機%';

性能對比數據:

數據量級 MySQL LIKE查詢 Elasticsearch全文搜索 性能提升
1萬條 50ms 10ms 5倍
10萬條 500ms 15ms 33倍
100萬條 5000ms 20ms 250倍
1000萬條 50000ms+ 30ms 1600倍+

根本原因:

  1. 全表掃描:LIKE '%keyword%' 無法使用B+樹索引,必須掃描所有行
  2. I/O密集:每次查詢都需要從磁盤讀取大量數據
  3. CPU密集:對每一行數據進行字符串匹配運算
  4. 內存壓力:大量數據加載到內存進行處理

實際案例:

某電商平臺商品表有500萬條記錄,使用MySQL模糊查詢搜索"蘋果手機":
- 查詢時間:8.3秒
- CPU使用率:飆升至85%
- 併發10個查詢時,響應時間增長到30秒以上

2.2 沒有相關性排名問題詳解

MySQL查詢結果的痛點:

-- MySQL只能按固定規則排序
SELECT * FROM products
WHERE name LIKE '%手機%'
ORDER BY price DESC;  -- 只能按價格、時間等字段排序

Elasticsearch的相關性評分機制:

搜索詞:"小米手機"

相關性評分計算:
┌─────────────────────────────────────┐
│ 文檔1:"小米手機12 Pro"              │
│ • 詞頻(TF):2個關鍵詞都出現           │
│ • 逆文檔頻率(IDF):計算詞的稀有度      │
│ • 字段長度:標題較短,權重更高         │
│ • 評分:9.8                         │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ 文檔2:"這是一款性價比很高的手機"      │
│ • 詞頻(TF):只有"手機"出現            │
│ • 逆文檔頻率(IDF):"手機"較常見        │
│ • 字段長度:描述較長,權重降低         │
│ • 評分:3.2                         │
└─────────────────────────────────────┘

相關性因素詳解:

  1. TF(詞頻):關鍵詞在文檔中出現的頻率
  2. IDF(逆文檔頻率):關鍵詞在所有文檔中的稀有程度
  3. 字段長度歸一化:短字段中的匹配比長字段權重更高
  4. 字段權重boost:可以設置標題比內容更重要
  5. 查詢時權重:可以指定某些查詢詞更重要

2.3 無法全文搜索問題詳解

MySQL全文索引的侷限:

-- MySQL全文索引創建
ALTER TABLE products ADD FULLTEXT(name, description);

-- 問題1:最小詞長限制(默認4個字符)
-- "手機" 可以搜索,但 "機" 搜不到

-- 問題2:中文分詞支持差
-- "蘋果手機" 被當作一個整體,搜索"蘋果"找不到

Elasticsearch全文搜索能力:

// ES的分析過程示例
輸入文本:"我想買一臺蘋果手機"

分詞結果:
[我] [想] [買] [一臺] [蘋果] [手機] [蘋果手機]

同義詞擴展:
[蘋果] → [Apple, iPhone]
[手機] → [手機, 電話, mobile]

拼寫糾錯:
"蘋果手擊" → 建議 "蘋果手機"

2.4 搜索不準確、沒有分詞問題詳解

MySQL字符串匹配的問題:

-- 搜索"筆記本"
SELECT * FROM products WHERE name LIKE '%筆記本%';
-- 結果:能找到"筆記本電腦"
-- 問題:找不到"筆記 本子"、"notebook"、"手提電腦"

Elasticsearch智能分詞過程:

原始文本:"ThinkPad X1 Carbon超輕薄筆記本電腦"

標準分詞器:
[ThinkPad] [X1] [Carbon] [超輕薄] [筆記本] [電腦]

IK分詞器(中文):
[ThinkPad] [X1] [Carbon] [超] [輕薄] [超輕薄]
[筆記] [本] [筆記本] [電腦] [筆記本電腦]

拼音分詞器:
[si] [kao] [pad] → 可以通過拼音搜索

N-gram分詞:
[Thi] [hin] [ink] [nkP] → 支持部分匹配

3. 什麼是全文搜索 - 核心原理解析

3.1 結構化數據 vs 非結構化數據

結構化數據(MySQL存儲方式):
┌──────┬────────┬────────┬────────┐
│  ID  │  Name  │ Price  │ Stock  │
├──────┼────────┼────────┼────────┤
│  1   │iPhone  │ 5999   │  100   │
│  2   │ 小米   │ 2999   │  200   │
└──────┴────────┴────────┴────────┘

非結構化數據(文本內容):
"這款iPhone手機採用A15處理器,性能強勁,
拍照效果出色,續航能力提升20%,
用戶評價:'太棒了,物超所值!'"

3.2 倒排索引原理詳解

正排索引(MySQL):

文檔ID → 內容
Doc1 → "小米手機"
Doc2 → "蘋果手機"
Doc3 → "小米電視"

倒排索引(Elasticsearch):

詞項 → 文檔列表
"小米" → [Doc1, Doc3]
"手機" → [Doc1, Doc2]
"蘋果" → [Doc2]
"電視" → [Doc3]

搜索"小米手機":
1. 查找"小米" → 得到 [Doc1, Doc3]
2. 查找"手機" → 得到 [Doc1, Doc2]
3. 計算交集 → Doc1(最相關)

3.3 倒排索引的詳細結構

完整的倒排索引結構:

詞項:"手機"
├── 文檔頻率(DF):1000個文檔包含此詞
├── 倒排列表:
│   ├── Doc1:
│   │   ├── 詞頻(TF):3次
│   │   ├── 位置:[5, 28, 102]
│   │   └── 字段:[title, description]
│   ├── Doc2:
│   │   ├── 詞頻(TF):1次
│   │   ├── 位置:[15]
│   │   └── 字段:[title]
│   └── ...
└── 統計信息:最高詞頻、平均詞頻等

4. Elasticsearch架構詳解

4.1 集羣架構

Elasticsearch集羣架構圖:

┌─────────────── ES Cluster ──────────────┐
│                                         │
│  ┌─────────────────────────────────┐   │
│  │     Master Node (主節點)         │   │
│  │  • 集羣管理                      │   │
│  │  • 索引創建/刪除                 │   │
│  │  • 分片分配                      │   │
│  └─────────────────────────────────┘   │
│                                         │
│  ┌──────────┐  ┌──────────┐           │
│  │ Data     │  │ Data     │           │
│  │ Node 1   │  │ Node 2   │           │
│  │ ┌──────┐ │  │ ┌──────┐ │           │
│  │ │ P0   │ │  │ │ R0   │ │           │
│  │ ├──────┤ │  │ ├──────┤ │           │
│  │ │ R1   │ │  │ │ P1   │ │           │
│  │ └──────┘ │  │ └──────┘ │           │
│  └──────────┘  └──────────┘           │
│                                         │
│  P = Primary Shard (主分片)            │
│  R = Replica Shard (副本分片)          │
└─────────────────────────────────────────┘

4.2 數據寫入流程

寫入流程詳解:

客戶端 → 協調節點 → 主分片 → 副本分片

1. 客戶端發送寫請求
   ↓
2. 協調節點通過hash路由確定分片
   ↓
3. 請求轉發到主分片節點
   ↓
4. 主分片寫入成功
   ↓
5. 並行複製到副本分片
   ↓
6. 所有副本確認
   ↓
7. 返回成功響應給客戶端

時間線:
T0 ──→ T1 ──→ T2 ──→ T3 ──→ T4
接收   路由   主分片  副本   響應

4.3 查詢流程

查詢執行過程:

Phase 1: Query(查詢階段)
┌─────────────────────────────────┐
│ 協調節點向所有分片發送查詢請求   │
│ 每個分片返回Top N的文檔ID和分數  │
└─────────────────────────────────┘
           ↓
Phase 2: Fetch(獲取階段)
┌─────────────────────────────────┐
│ 協調節點整合所有結果並排序       │
│ 獲取最終需要的文檔完整內容       │
└─────────────────────────────────┘

5. Elasticsearch核心功能詳解

5.1 查詢類型詳解

// 1. Match查詢 - 全文搜索
{
  "query": {
    "match": {
      "title": {
        "query": "蘋果手機",
        "operator": "and"  // 必須包含所有詞
      }
    }
  }
}

// 2. Term查詢 - 精確匹配
{
  "query": {
    "term": {
      "category.keyword": "手機"  // 不分詞,精確匹配
    }
  }
}

// 3. Range查詢 - 範圍查詢
{
  "query": {
    "range": {
      "price": {
        "gte": 1000,
        "lte": 5000
      }
    }
  }
}

// 4. Bool複合查詢
{
  "query": {
    "bool": {
      "must": [
        {"match": {"title": "手機"}}
      ],
      "filter": [
        {"range": {"price": {"lte": 5000}}}
      ],
      "should": [
        {"match": {"brand": "蘋果"}}  // 加分項
      ],
      "must_not": [
        {"term": {"status": "discontinued"}}
      ]
    }
  }
}

5.2 聚合分析功能

// 銷售數據分析示例
{
  "aggs": {
    "sales_per_category": {
      "terms": {
        "field": "category"
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        },
        "total_sales": {
          "sum": {
            "field": "sales_count"
          }
        },
        "price_ranges": {
          "range": {
            "field": "price",
            "ranges": [
              {"to": 1000},
              {"from": 1000, "to": 5000},
              {"from": 5000}
            ]
          }
        }
      }
    }
  }
}

6. 實際應用案例分析

6.1 電商搜索優化案例

某電商平臺搜索優化前後對比:

指標 MySQL方案 Elasticsearch方案 改善效果
平均搜索耗時 2.3秒 0.05秒 46倍提升
搜索準確率 65% 92% 提升27%
零結果率 18% 3% 降低15%
服務器數量 8臺 3臺 節省62.5%成本
併發能力 100 QPS 5000 QPS 50倍提升

實施細節:

  1. 數據同步架構:
    MySQL(主數據) → Binlog → Logstash → Elasticsearch

    定時全量同步(每晚)

  2. 搜索優化策略:

  3. 拼音搜索:支持 "pinguo" 搜索到 "蘋果"
  4. 同義詞:配置 "手機"、"電話"、"mobile" 爲同義詞
  5. 搜索建議:實時提示用戶可能的搜索詞
  6. 糾錯功能:自動糾正常見拼寫錯誤

6.2 日誌分析系統案例

某互聯網公司日誌分析系統:

日誌處理流程:

應用服務器 → Filebeat → Logstash → Elasticsearch → Kibana
     ↓           ↓          ↓            ↓            ↓
   產生日誌    收集      處理轉換      存儲索引     可視化展示

處理規模:
• 日誌量:每天100GB
• 日誌條數:10億條/天
• 查詢響應:毫秒級
• 保存週期:30天熱數據,1年冷數據

7. 性能優化最佳實踐

7.1 索引設計優化

// 優化的Mapping設計
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart",
        "fields": {
          "keyword": {
            "type": "keyword"  // 支持精確匹配
          },
          "pinyin": {
            "type": "text",
            "analyzer": "pinyin"  // 支持拼音搜索
          }
        }
      },
      "price": {
        "type": "scaled_float",
        "scaling_factor": 100  // 價格精度優化
      },
      "category": {
        "type": "keyword"  // 分類不需要分詞
      },
      "description": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "created_time": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
      }
    }
  }
}

7.2 查詢性能優化技巧

  1. 使用Filter代替Query(當不需要評分時)
    ```json
    // 優化前:使用query(計算評分)
    {"query": {"term": {"status": "active"}}}

// 優化後:使用filter(不計算評分,可緩存)
{"query": {"bool": {"filter": {"term": {"status": "active"}}}}}
```

  1. 合理設置分片數量
    ```
    分片數量參考公式:
    分片數 = 數據量(GB) / 30GB

示例:
- 100GB數據:3-4個分片
- 1TB數據:35-40個分片
```

  1. 批量操作優化
    json
    // 使用bulk API批量索引
    POST _bulk
    {"index": {"_index": "products", "_id": 1}}
    {"name": "iPhone", "price": 5999}
    {"index": {"_index": "products", "_id": 2}}
    {"name": "小米", "price": 2999}

8. Elasticsearch vs 傳統數據庫

8.1 適用場景對比

場景 MySQL Elasticsearch 推薦選擇
全文搜索 ❌ 差 ✅ 優秀 ES
事務支持 ✅ 完整ACID ❌ 無事務 MySQL
實時統計分析 ⚠️ 一般 ✅ 優秀 ES
關係查詢 ✅ 優秀 ❌ 有限 MySQL
地理位置搜索 ❌ 差 ✅ 優秀 ES
日誌分析 ❌ 不適合 ✅ 專長 ES
精確數值計算 ✅ 精確 ⚠️ 近似 MySQL

8.2 混合架構方案

推薦的混合架構:

        用戶請求
           ↓
    ┌──────────────┐
    │   應用層     │
    └──────────────┘
           ↓
    ┌──────────────────────────┐
    │      搜索請求  → ES       │
    │      事務操作  → MySQL    │
    │      緩存     → Redis    │
    └──────────────────────────┘

數據同步:
MySQL(寫) → Binlog → Canal/Debezium → Kafka → ES(讀)

9. 常見問題與解決方案

9.1 數據一致性問題

問題: MySQL和ES數據不一致

解決方案:
1. 雙寫策略:同時寫MySQL和ES,使用消息隊列保證最終一致性
2. CDC(Change Data Capture):通過Binlog實時同步
3. 定期校驗:定時任務對比數據差異並修復

9.2 深度分頁問題

問題: 查詢第10000頁數據時性能極差

解決方案:

// 1. 使用search_after(推薦)
{
  "size": 10,
  "sort": [{"_id": "asc"}],
  "search_after": [10000]  // 上一頁最後一個文檔的sort值
}

// 2. 使用scroll API(適合導出)
POST /products/_search?scroll=1m
{
  "size": 100,
  "query": {"match_all": {}}
}

10. 總結

Elasticsearch通過倒排索引、分佈式架構和強大的全文搜索能力,完美解決了傳統數據庫在搜索場景下的各種問題。合理使用Elasticsearch可以:

  1. 提升搜索性能:從秒級降到毫秒級
  2. 改善搜索質量:通過相關性評分和智能分詞
  3. 支持複雜分析:實時聚合和統計分析
  4. 降低運維成本:更少的服務器,更高的效率

但需要注意的是,Elasticsearch不是MySQL的替代品,而是補充。在實際項目中,應該根據具體場景選擇合適的存儲方案,通常採用MySQL+Elasticsearch的混合架構能夠發揮各自優勢。

主題測試文章,只做測試使用。發佈者:Walker,轉轉請注明出處:https://walker-learn.xyz/archives/6775

(0)
Walker的頭像Walker
上一篇 2026年3月8日 15:11
下一篇 2026年3月9日 12:56

相關推薦

  • Go工程師體系課 007

    商品微服務 實體結構說明 本模塊包含以下核心實體: 商品(Goods) 商品分類(Category) 品牌(Brands) 輪播圖(Banner) 品牌分類(GoodsCategoryBrand) 1. 商品(Goods) 描述平臺中實際展示和銷售的商品信息。 字段說明 字段名 類型 說明 name String 商品名稱,必填 brand Pointer …

    後端開發 2026年3月6日
    5800
  • Go工程師體系課 004

    需求分析 後臺管理系統 商品管理 商品列表 商品分類 品牌管理 品牌分類 訂單管理 訂單列表 用戶信息管理 用戶列表 用戶地址 用戶留言 輪播圖管理 電商系統 登錄頁面 首頁 商品搜索 商品分類導航 輪播圖展示 推薦商品展示 商品詳情頁 商品圖片展示 商品描述 商品規格選擇 加入購物車 購物車 商品列表 數量調整 刪除商品 結算功能 用戶中心 訂單中心 我的…

    2026年3月6日
    5900
  • 編程基礎 0009_testing詳解

    Go testing 詳解 目錄 testing 包基礎 表格驅動測試 子測試 t.Run 基準測試 Benchmark 測試覆蓋率 TestMain httptest 包 Mock 和接口測試技巧 模糊測試 Fuzz 1. testing 包基礎 1.1 測試文件和函數命名規則 Go 測試遵循嚴格的命名約定: 測試文件以 _test.go 結尾(如 use…

    後端開發 2026年3月6日
    6900
  • Go工程師體系課 007

    商品微服務 實體結構說明 本模塊包含以下核心實體: 商品(Goods) 商品分類(Category) 品牌(Brands) 輪播圖(Banner) 品牌分類(GoodsCategoryBrand) 1. 商品(Goods) 描述平臺中實際展示和銷售的商品信息。 字段說明 字段名 類型 說明 name String 商品名稱,必填 brand Pointer …

    後端開發 2026年3月7日
    6100
  • Go工程師體系課 012

    Go 中集成 Elasticsearch 1. 客戶端庫選擇 1.1 主流 Go ES 客戶端 olivere/elastic:功能最全面,API 設計優雅,支持 ES 7.x/8.x elastic/go-elasticsearch:官方客戶端,輕量級,更接近原生 REST API go-elasticsearch/elasticsearch:社區維護的官…

    後端開發 2026年3月7日
    5400
簡體中文 繁體中文 English