ã€æž¶æž„实战】ElasticSearchæœç´¢é›†ç¾¤ï¼šå
¨æ–‡æ£€ç´¢çš„艺术
倒排索引ã€åˆ†ç‰‡å‰¯æœ¬ã€æœç´¢ä¼˜åŒ–ã€å®žæˆ˜æ¡ˆä¾‹
一ã€ä»Žä¸€ä¸ªçœŸå®žçš„æ•
事说起
2024å¹´åŒå一,æŸç”µå•†å¹³å°æœç´¢ç³»ç»Ÿåœ¨æµé‡æ´ªå³°åˆ°æ¥çš„那一刻,çªç„¶"å“‘ç«"了。
用户在æœç´¢æ¡†è¾“å
¥"iPhone 15 Pro Max",ç‰äº†æ•´æ•´8ç§’ï¼Œé¡µé¢æ‰åˆ·å‡ºç»“果。而更诡异的是,有些用户æœç´¢"手机壳",å±
ç„¶æœå‡ºäº†"手机支架"——相å
³æ€§å®Œå
¨é”™ä¹±ã€‚è¿ç»´å›¢é˜Ÿç´§æ€¥æŽ’查,å‘现是ElasticSearch集群的æŸä¸ªåˆ†ç‰‡å› 为ç£ç›˜IO瓶颈导致查询è¶
æ—¶ï¼Œè€Œå‰¯æœ¬åˆ†ç‰‡å› ä¸ºè´Ÿè½½å‡è¡¡ç–略问题,å
¨éƒ¨æ‰“在了åŒä¸€å°æœºå™¨ä¸Šã€‚
"æˆ‘ä»¬ä¸æ˜¯é
置了副本å—ï¼Ÿä¸ºä»€ä¹ˆè¿˜ä¼šè¿™æ ·ï¼Ÿ"å¼€å‘åŒå¦ä¸€è„¸æ‡µã€‚
"副本是é
ç½®äº†ï¼Œä½†ä½ ä»¬æŠŠ5个副本分片å
¨éƒ¨åˆ†é
到了åŒä¸€å°é«˜é
æœºå™¨ä¸Šï¼Œä»¥ä¸ºè¿™æ ·èƒ½æé«˜æ€§èƒ½ã€‚ç»“æžœé‚£å°æœºå™¨çš„ç£ç›˜IO被打满,查询å
¨éƒ¨è¶
时。"è¿ç»´åŒå¦æ— 奈地解释。
这个æ•
事告诉我们:ElasticSearch䏿˜¯å¼€ç®±å³ç”¨çš„æœç´¢å¼•æ“Žï¼Œç†è§£å
¶åº•层原ç†å¹¶æ£ç¡®é
置,æ‰èƒ½çœŸæ£å‘挥它的å¨åŠ›ã€‚
äºŒã€æ ¸å¿ƒæ¦‚念:倒排索引——æœç´¢çš„基石
2.1 什么是倒排索引?
ä¼ ç»Ÿçš„å
³ç³»åž‹æ•°æ®åº“使用**æ£å‘索引**:文档ID → 文档å†
容。比如:
1文档ID: 1 → å† 2容: "iPhone 15 Pro Max 256GB 深空黑" 3文档ID: 2 → å† 4容: "iPhone 15 Pro 手机壳 逿˜Ž" 5文档ID: 3 → å† 6容: "iPhone 14 Pro Max 手机壳 黑色" 7
å¦‚æžœè¦æœç´¢"iPhone",数æ®åº“éœ€è¦æ‰«ææ‰€æœ‰æ–‡æ¡£ï¼Œé€ä¸ªåŒ¹é
——这就是å
¨è¡¨æ‰«æï¼Œæ•ˆçއæžä½Žã€‚
而ElasticSearch使用**倒排索引**ï¼šè¯æ¡ → 文档ID列表。
1è¯æ¡ 文档ID列表 2───────────────────────── 3iPhone → [1, 2, 3] 415 → [1, 2] 5Pro → [1, 2, 3] 6Max → [1, 3] 7手机壳 → [2, 3] 8256GB → [1] 9深空黑 → [1] 10逿˜Ž → [2] 11黑色 → [3] 12
现在æœç´¢"iPhone",åªéœ€è¦åœ¨å€’æŽ’ç´¢å¼•ä¸æ‰¾åˆ°"iPhone"è¿™ä¸ªè¯æ¡ï¼Œç›´æŽ¥å¾—到文档ID列表[1, 2, 3]ï¼Œæ— éœ€æ‰«æä»»ä½•文档。这就是**O(1)级别**的查询效率。
2.2 倒排索引的结构
å€’æŽ’ç´¢å¼•ç”±ä¸‰ä¸ªæ ¸å¿ƒç»“æž„ç»„æˆï¼š
- Term Dictionaryï¼ˆè¯æ¡å—å
**¸ï¼‰**:所有ä¸é‡å¤çš„è¯æ¡ï¼ŒæŒ‰å—å
¸åºæŽ’åºã€‚ElasticSearch使用FST(Finite State Transducer)压缩å˜å‚¨ï¼Œå†
å˜å 用æžå°ã€‚ - **Term Indexï¼ˆè¯æ¡ç´¢å¼•)**:Term Dictionary的索引,用于快速定ä½è¯æ¡åœ¨ç£ç›˜ä¸Šçš„ä½ç½®ã€‚通常æ¯128ä¸ªè¯æ¡å»ºç«‹ä¸€ä¸ªç´¢å¼•项。
- **Posting List(倒排表)**:æ¯ä¸ªè¯æ¡å¯¹åº”的文档ID列表。ElasticSearch使用Frame of Referenceç¼–ç å’ŒRoaring Bitmaps压缩,大å¹
å‡å°‘å˜å‚¨ç©ºé—´ã€‚
1Term Index (å† 2å˜) → Term Dictionary (ç£ç›˜) → Posting List (ç£ç›˜) 3 ↓ ↓ ↓ 4 å¿«é€Ÿå®šä½ è¯æ¡è¯¦æƒ 5 文档ID列表 6
2.3 实战:查看倒排索引
我们å¯ä»¥é€šè¿‡ElasticSearchçš„_termvectorsAPI查看æŸä¸ªæ–‡æ¡£çš„倒排索引信æ¯ï¼š
1GET /products/_termvectors/1?fields=name&term_statistics=true 2 3{ 4 "term_vectors": { 5 "name": { 6 "terms": { 7 "iphone": { 8 "term_freq": 1, 9 "doc_freq": 3, 10 "ttf": 3 11 }, 12 "15": { 13 "term_freq": 1, 14 "doc_freq": 2, 15 "ttf": 2 16 } 17 } 18 } 19 } 20} 21
å
¶ä¸ï¼š
term_freqï¼šè¯¥è¯æ¡åœ¨å½“剿–‡æ¡£ä¸å‡ºçŽ°çš„æ¬¡æ•°doc_freq:åŒ
å«è¯¥è¯æ¡çš„æ–‡æ¡£æ•°é‡ï¼ˆæ–‡æ¡£é¢‘率)ttfï¼šè¯¥è¯æ¡åœ¨æ‰€æœ‰æ–‡æ¡£ä¸å‡ºçŽ°çš„æ€»æ¬¡æ•°
三ã€åˆ†ç‰‡ä¸Žå‰¯æœ¬ï¼šåˆ†å¸ƒå¼çš„艺术
3.1 分片(Shard):数æ®çš„æ°´å¹³åˆ‡åˆ†
ElasticSearch将一个索引的数æ®åˆ†æ•£åˆ°å¤šä¸ªåˆ†ç‰‡ä¸ï¼Œæ¯ä¸ªåˆ†ç‰‡æ˜¯ä¸€ä¸ªç‹¬ç«‹çš„Lucene索引。
为什么需è¦åˆ†ç‰‡ï¼Ÿ
- **水平扩展**:å•å°æœºå™¨å˜ä¸ä¸‹æµ·é‡æ•°æ®ï¼Œåˆ†ç‰‡è®©æ•°æ®åˆ†æ•£åˆ°å¤šå°æœºå™¨
- **并行查询**:查询å¯ä»¥å¹¶è¡Œæ‰§è¡Œåœ¨å¤šä¸ªåˆ†ç‰‡ä¸Šï¼Œæé«˜æ€§èƒ½
分片数é‡å¦‚何确定?
官方建议:**æ¯ä¸ªåˆ†ç‰‡å¤§å°åœ¨10GB-50GB之间**ï¼Œåˆ†ç‰‡æ•°é‡ = æ•°æ®æ€»é‡ / 30GB。
1// 创建索引时指定分片数 2PUT /products 3{ 4 "settings": { 5 "number_of_shards": 5, 6 "number_of_replicas": 1 7 } 8} 9
3.2 副本(Replica):高å¯ç”¨çš„ä¿éšœ
副本是分片的拷è´ï¼Œç”¨äºŽï¼š
- 容ç¾ï¼šä¸»åˆ†ç‰‡æ•
障时,副本自动å‡çº§ä¸ºä¸»åˆ†ç‰‡ - **è´Ÿè½½å‡è¡¡**:查询请求å¯ä»¥åˆ†å‘到副本上,æé«˜æŸ¥è¯¢åžåé‡
副本数é‡å¦‚何确定?
- å¼€å‘环境:0个副本(节çœèµ„æºï¼‰
- 生产环境:至少1个副本
- 高å¯ç”¨åœºæ™¯ï¼š2个副本(å
许任æ„2å°æœºå™¨åŒæ—¶æ•
障)
3.3 分片分é
ç–ç•¥
ElasticSearch通过分片分é **器(Shard Allocator)**å†³å®šåˆ†ç‰‡æ”¾åœ¨å“ªäº›èŠ‚ç‚¹ä¸Šã€‚æ ¸å¿ƒåŽŸåˆ™ï¼š
- **å‡è¡¡åŽŸåˆ™**:尽é‡è®©æ¯ä¸ªèŠ‚ç‚¹çš„åˆ†ç‰‡æ•°é‡ç›¸è¿‘
- **感知原则**:é¿å
主分片和副本分片分é
到åŒä¸€å°æœºå™¨ - **属性感知**:å¯ä»¥æ ¹æ®æœºæž¶ã€å¯ç”¨åŒºç‰å±žæ€§åˆ†é
,é¿å
å•点æ•
障
1# elasticsearch.yml é 2置机架感知 3cluster.routing.allocation.awareness.attributes: rack_id 4 5node.attr.rack_id: rack1 # 节点1 6node.attr.rack_id: rack2 # 节点2 7
è¿™æ ·é
ç½®åŽï¼ŒElasticSearch会尽é‡å°†ä¸»åˆ†ç‰‡å’Œå‰¯æœ¬åˆ†ç‰‡åˆ†é
到ä¸åŒçš„æœºæž¶ä¸Šã€‚
3.4 实战案例:分片分é
失败排查
**问题现象**:集群状æ€ä¸ºYellow,æç¤º"分片分é
失败"。
**排查æ¥éª¤**:
1// 1. 查看集群å¥åº·çŠ¶æ€ 2GET /_cluster/health 3 4{ 5 "status": "yellow", 6 "unassigned_shards": 2 7} 8 9// 2. 查看分片分é 10解释 11GET /_cluster/allocation/explain 12 13{ 14 "index": "products", 15 "shard": 1, 16 "primary": false, 17 "current_state": "unassigned", 18 "unassigned_info": { 19 "reason": "NODE_LEFT", 20 "at": "2024-11-11T10:00:00.000Z" 21 }, 22 "can_allocate": "no", 23 "allocate_explanation": "cannot allocate because the node left the cluster" 24} 25
解决方案:
如果是节点临时æ•
障,ç‰å¾
节点æ¢å¤å³å¯ã€‚如果节点永ä¹
下线,需è¦è°ƒæ•´åˆ†ç‰‡åˆ†é
ç–略:
1// 釿–°åˆ†é 2副本 3POST /_cluster/reroute?retry_failed=true 4
å››ã€æœç´¢ä¼˜åŒ–:从å
¥é—¨åˆ°ç²¾é€š
4.1 查询DSLï¼šæž„å»ºå¤æ‚查询
ElasticSearchæä¾›äº†å¼ºå¤§çš„Query DSL(Domain Specific Language):
1// boolç»„åˆæŸ¥è¯¢ 2GET /products/_search 3{ 4 "query": { 5 "bool": { 6 "must": [ 7 { "match": { "name": "iPhone" }} 8 ], 9 "should": [ 10 { "match": { "brand": "Apple" }}, 11 { "range": { "price": { "lte": 10000 }}} 12 ], 13 "must_not": [ 14 { "match": { "status": "下架" }} 15 ], 16 "filter": [ 17 { "term": { "category": "手机" }} 18 ] 19 } 20 } 21} 22
å
¶ä¸ï¼š
must:å¿
须匹é
,å‚与评分should:选择性匹é
,å‚与评分must_not:å¿
é¡»ä¸åŒ¹é
,ä¸å‚与评分filter:å¿
须匹é
,ä¸å‚与评分(性能更高)
4.2 相å
³æ€§è¯„分:BM25算法
ElasticSearch默认使用BM25算法计算文档相å
³æ€§è¯„分:
1score(D, Q) = Σ IDF(qi) * (f(qi, D) * (k1 + 1)) / (f(qi, D) + k1 * (1 - b + b * |D| / avgdl)) 2
å
¶ä¸ï¼š
f(qi, D)ï¼šè¯æ¡qi在文档Dä¸çš„出现频率|D|:文档D的长度avgdl:所有文档的平å‡é•¿åº¦k1ã€bï¼šè°ƒèŠ‚å‚æ•°ï¼Œé»˜è®¤k1=1.2,b=0.75
实战:调整BM25傿•°
1PUT /products 2{ 3 "settings": { 4 "index": { 5 "similarity": { 6 "custom_bm25": { 7 "type": "BM25", 8 "k1": 1.5, 9 "b": 0.8 10 } 11 } 12 } 13 }, 14 "mappings": { 15 "properties": { 16 "name": { 17 "type": "text", 18 "similarity": "custom_bm25" 19 } 20 } 21 } 22} 23
4.3 高亮显示:让结果更直观
1GET /products/_search 2{ 3 "query": { 4 "match": { "name": "iPhone" } 5 }, 6 "highlight": { 7 "fields": { 8 "name": { 9 "pre_tags": ["<em>"], 10 "post_tags": ["</em>"], 11 "fragment_size": 150, 12 "number_of_fragments": 3 13 } 14 } 15 } 16} 17 18// 返回结果 19{ 20 "hits": { 21 "hits": [ 22 { 23 "_source": { 24 "name": "iPhone 15 Pro Max 256GB 深空黑" 25 }, 26 "highlight": { 27 "name": ["<em>iPhone</em> 15 Pro Max 256GB 深空黑"] 28 } 29 } 30 ] 31 } 32} 33
4.4 èšåˆåˆ†æžï¼šä¸åªæ˜¯æœç´¢
ElasticSearchçš„èšåˆåŠŸèƒ½å¯ä»¥å®žçް夿‚的数æ®åˆ†æžï¼š
1// 按å“牌分组,计算平å‡ä»·æ ¼å’Œé”€é‡ 2GET /products/_search 3{ 4 "size": 0, 5 "aggs": { 6 "brands": { 7 "terms": { "field": "brand.keyword", "size": 10 }, 8 "aggs": { 9 "avg_price": { "avg": { "field": "price" }}, 10 "total_sales": { "sum": { "field": "sales" }} 11 } 12 } 13 } 14} 15
五ã€å®žæˆ˜æ¡ˆä¾‹ï¼šç”µå•†æœç´¢ç³»ç»Ÿæž¶æž„
5.1 系统架构设计
1用户请求 2 ↓ 3API网å 4³ï¼ˆé™æµã€é‰´æƒï¼‰ 5 ↓ 6æœç´¢æœåŠ¡ï¼ˆæŸ¥è¯¢é‡å†™ã€ç»“果排åºï¼‰ 7 ↓ 8ElasticSearch集群(3主3从) 9 ↓ 10æ•°æ®åŒæ¥æœåŠ¡ï¼ˆMySQL → ES) 11
5.2 æ•°æ®åŒæ¥æ–¹æ¡ˆ
方案一:åŒå†™æ¨¡å¼
åº”ç”¨å±‚åŒæ—¶å†™å
¥MySQLå’ŒElasticSearch:
1@Transactional 2public void saveProduct(Product product) { 3 // 1. 写å 4¥MySQL 5 productMapper.insert(product); 6 7 // 2. 写å 8¥ElasticSearch 9 try { 10 elasticsearchTemplate.save(product); 11 } catch (Exception e) { 12 // 写å 13¥å¤±è´¥ï¼Œè®°å½•日志,异æ¥è¡¥å¿ 14 log.error("ES写å 15¥å¤±è´¥", e); 16 mqService.send("es_sync_topic", product); 17 } 18} 19
优点:实现简å•,实时性高
缺点:代ç ä¾µå
¥æ€§å¼ºï¼Œä¸€è‡´æ€§éš¾ä»¥ä¿è¯
方案二:CDC(Change Data Capture)
通过监å¬MySQLçš„binlogï¼Œå®žæ—¶åŒæ¥åˆ°ElasticSearch:
1# Canalé 2ç½® 3canal.instance.master.address: 127.0.0.1:3306 4canal.instance.filter.regex: shop\\.products 5 6# åŒæ¥åˆ°ES 7canal.adapters: 8 - name: es 9 hosts: 127.0.0.1:9200 10 index: products 11 mapping: 12 id: _id 13 name: name 14 price: price 15
ä¼˜ç‚¹ï¼šä»£ç æ— ä¾µå
¥ï¼Œä¸€è‡´æ€§æœ‰ä¿éšœ
缺点:需è¦é¢å¤–部署Canal,è¿ç»´æˆæœ¬é«˜
5.3 æœç´¢æ€§èƒ½ä¼˜åŒ–
优化一:使用filter代替query
1// æ 2¢ï¼šä½¿ç”¨query 3GET /products/_search 4{ 5 "query": { 6 "bool": { 7 "must": [ 8 { "term": { "category": "手机" }}, 9 { "term": { "brand": "Apple" }} 10 ] 11 } 12 } 13} 14 15// 快:使用filter 16GET /products/_search 17{ 18 "query": { 19 "bool": { 20 "filter": [ 21 { "term": { "category": "手机" }}, 22 { "term": { "brand": "Apple" }} 23 ] 24 } 25 } 26} 27
filterä¸è®¡ç®—评分,且会被缓å˜ï¼Œæ€§èƒ½æ›´é«˜ã€‚
优化二:预çƒç¼“å˜
åœ¨ä¸šåŠ¡ä½Žå³°æœŸé¢„çƒæŸ¥è¯¢ç¼“å˜ï¼š
1@Scheduled(cron = "0 0 3 * * ?") 2public void warmUpCache() { 3 List<String> hotKeywords = getHotKeywords(); 4 for (String keyword : hotKeywords) { 5 elasticsearchTemplate.query(keyword); 6 } 7} 8
ä¼˜åŒ–ä¸‰ï¼šå¼‚æ¥æŸ¥è¯¢
å¯¹äºŽéžæ ¸å¿ƒæŸ¥è¯¢ï¼ˆå¦‚推èã€å¹¿å‘Šï¼‰ï¼Œä½¿ç”¨å¼‚æ¥æŸ¥è¯¢ï¼š
1CompletableFuture<List<Product>> recommendFuture = CompletableFuture.supplyAsync(() -> { 2 return recommendService.query(userId); 3}); 4 5CompletableFuture<List<Ad>> adFuture = CompletableFuture.supplyAsync(() -> { 6 return adService.query(userId); 7}); 8 9// ç‰å¾ 10æ‰€æœ‰æŸ¥è¯¢å®Œæˆ 11CompletableFuture.allOf(recommendFuture, adFuture).join(); 12
å
ã€è¸©å‘实录
踩å‘一:深度分页性能问题
**问题**:查询第10000页,æ¯é¡µ10æ¡ï¼Œè€—æ—¶10秒。
1GET /products/_search 2{ 3 "from": 100000, 4 "size": 10, 5 "query": { "match_all": {} } 6} 7
**åŽŸå› **:ElasticSearchéœ€è¦æŸ¥è¯¢æ‰€æœ‰åˆ†ç‰‡çš„from+sizeæ¡æ•°æ®ï¼Œåœ¨å调节点排åºåŽå–[from, from+size]。from越大,排åºçš„æ•°æ®è¶Šå¤šï¼Œæ€§èƒ½è¶Šå·®ã€‚
解决方案:使用search_after代替from/size:
1// 第一次查询 2GET /products/_search 3{ 4 "size": 10, 5 "sort": [ 6 { "_id": "asc" } 7 ] 8} 9 10// åŽç»æŸ¥è¯¢ 11GET /products/_search 12{ 13 "size": 10, 14 "sort": [ 15 { "_id": "asc" } 16 ], 17 "search_after": ["AVd3d3d3d3d3d3d3"] 18} 19
踩å‘äºŒï¼šå—æ®µç±»åž‹é”™è¯¯å¯¼è‡´æ— 法èšåˆ
**问题**:对priceå—æ®µèšåˆæ—¶æŠ¥é”™ã€‚
1GET /products/_search 2{ 3 "aggs": { 4 "price_stats": { "stats": { "field": "price" }} 5 } 6} 7 8// 报错 9{ 10 "error": { 11 "type": "illegal_argument_exception", 12 "reason": "Field [price] of type [text] is not supported for aggregation" 13 } 14} 15
**åŽŸå› **:priceå—æ®µè¢«æ˜ 射为text类型,textç±»åž‹ä¸æ”¯æŒèšåˆã€‚
解决方案:使用keywordç±»åž‹æˆ–æ·»åŠ åå—æ®µï¼š
1PUT /products/_mapping 2{ 3 "properties": { 4 "price": { 5 "type": "text", 6 "fields": { 7 "keyword": { "type": "keyword" }, 8 "double": { "type": "double" } 9 } 10 } 11 } 12} 13 14// 使用åå—æ®µèšåˆ 15GET /products/_search 16{ 17 "aggs": { 18 "price_stats": { "stats": { "field": "price.double" }} 19 } 20} 21
踩å‘三:集群脑裂问题
**问题**:集群出现两个Master节点,数æ®ä¸ä¸€è‡´ã€‚
**åŽŸå› **ï¼šç½‘ç»œåˆ†åŒºå¯¼è‡´éƒ¨åˆ†èŠ‚ç‚¹æ— æ³•é€šä¿¡ï¼Œå„自选举出Master。
解决方案:
1# elasticsearch.yml 2# 设置最å°ä¸»èŠ‚ç‚¹æ•° = 节点数/2 + 1 3discovery.zen.minimum_master_nodes: 2 4 5# æˆ–è€ 6使用7.x+版本的自动é 7ç½® 8cluster.initial_master_nodes: ["node1", "node2", "node3"] 9
踩å‘四:JVMå †å†
å˜è®¾ç½®ä¸å½“
**问题**:频ç¹Full GC,查询è¶
时。
**åŽŸå› **ï¼šå †å†
å˜è®¾ç½®è¿‡å¤§ï¼Œè¶
过物ç†å†
å˜çš„50%,导致大é‡å†
å˜ç”¨äºŽPage Cache,å而é™ä½Žæ€§èƒ½ã€‚
解决方案:
1# jvm.options 2-Xms16g 3-Xmx16g 4 5# å †å† 6å˜ä¸è¶ 7过物ç†å† 8å˜çš„50%,且ä¸è¶ 9过32GB 10# Lucene利用æ“作系统的Page CacheåŠ é€ŸæŸ¥è¯¢ï¼Œå †å† 11å˜è¿‡å¤§åè€Œå½±å“æ€§èƒ½ 12
ä¸ƒã€æ€»ç»“
ElasticSearchä½œä¸ºåˆ†å¸ƒå¼æœç´¢å¼•擎,å
¶æ ¸å¿ƒä¼˜åŠ¿åœ¨äºŽï¼š
- **倒排索引**:O(1)级别的查询效率
- **分片副本**:水平扩展和高å¯ç”¨ä¿éšœ
- 丰富的查询DSL:支æŒå¤æ‚查询和èšåˆåˆ†æž
- **åˆ†å¸ƒå¼æž¶æž„**:自动分片分é
å’Œæ•
éšœæ¢å¤
ä½†åŒæ—¶ï¼ŒElasticSearch也有å
¶å¤æ‚性:
- **分片规划**:分片数é‡å’Œå¤§å°éœ€è¦åˆç†è§„划
- **æ•°æ®ä¸€è‡´æ€§**:与MySQLç‰å
³ç³»åž‹æ•°æ®åº“çš„åŒæ¥æ–¹æ¡ˆéœ€è¦è°¨æ
Žé€‰æ‹© - **性能优化**:深度分页ã€å—段类型ã€JVMé
ç½®ç‰éƒ½éœ€è¦æ·±å
¥ç†è§£ - **è¿ç»´å¤æ‚度**ï¼šé›†ç¾¤ç›‘æŽ§ã€æ•
障排查ã€å®¹é‡è§„划都需è¦ä¸“业能力
å
«ã€æ€è€ƒé¢˜
- å¦‚æžœä½ çš„ä¸šåŠ¡éœ€è¦æ”¯æŒ"æœç´¢æŽ¨è"(用户输å
¥æ—¶å®žæ—¶æŽ¨èæœç´¢è¯ï¼‰ï¼Œä½ 会如何设计?需è¦è€ƒè™‘哪些技术点? - ElasticSearchå’ŒMySQL儿œ‰ä¼˜åŠ£ï¼Œä»€ä¹ˆåœºæ™¯ä¸‹åº”è¯¥é€‰æ‹©ElasticSearch作为主å˜å‚¨ï¼Ÿä»€ä¹ˆåœºæ™¯ä¸‹åº”è¯¥ä¿æŒMySQL为主å˜å‚¨ï¼ŒElasticSearchä»
作为æœç´¢åŠ é€Ÿï¼Ÿ - 在微æœåŠ¡æž¶æž„ä¸‹ï¼Œå¦‚ä½•ä¿è¯ElasticSearchæ•°æ®ä¸Žå„个微æœåŠ¡æ•°æ®çš„ä¸€è‡´æ€§ï¼Ÿä½ ä¼šé€‰æ‹©å“ªç§åŒæ¥æ–¹æ¡ˆï¼Ÿ
ä¹ã€ä¸ªäººè§‚点
在我å‚与过的多个项目ä¸ï¼ŒElasticSearch最常è§çš„误区是:**把它当作数æ®åº“æ¥ç”¨**。
很多团队直接把业务数æ®å˜åˆ°ElasticSearch,ä¸å†ä½¿ç”¨MySQLã€‚è¿™åœ¨åˆæœŸç¡®å®žç®€å•高效,但éšç€ä¸šåŠ¡å‘å±•ï¼Œé—®é¢˜é€æ¸æš´éœ²ï¼š
- **事务支æŒå¼±**:ElasticSearchæ²¡æœ‰å®Œæ•´çš„äº‹åŠ¡æœºåˆ¶ï¼Œå¤æ‚业务逻辑难以实现
- **更新性能差**ï¼šé¢‘ç¹æ›´æ–°ä¼šå¯¼è‡´å¤§é‡segment文件,查询性能下é™
- æ•°æ®ä¸€è‡´æ€§éš¾ä¿è¯ï¼šåˆ†å¸ƒå¼çŽ¯å¢ƒä¸‹çš„æ•°æ®ä¸€è‡´æ€§æ˜¯ä¸ªå¤§é—®é¢˜
我的建议是:ElasticSearch作为æœç´¢å¼•擎,MySQL作为数æ®å˜å‚¨ï¼Œä¸¤è€ å„å¸å ¶èŒã€‚通过CDC或åŒå†™æ¨¡å¼ä¿æŒæ•°æ®åŒæ¥ï¼Œæ—¢äº«å—ElasticSearchçš„æœç´¢èƒ½åŠ›ï¼Œåˆä¿ç•™MySQL的事务特性。
å¦ä¸€ä¸ªå¸¸è§è¯¯åŒºæ˜¯ï¼š**忽视集群è¿ç»´**。很多团队æå»ºå®Œé›†ç¾¤å°±ä¸ç®¡äº†ï¼Œç›´åˆ°å‡ºé—®é¢˜æ‰ä¸´æ—¶æŠ±ä½›è„šã€‚å»ºè®®ä»Žé¡¹ç›®åˆæœŸå°±å»ºç«‹å®Œå–„的监控体系(使用ElasticSearch Headã€Kibanaã€Prometheusç‰ï¼‰ï¼Œå®šæœŸè¿›è¡Œå®¹é‡è§„划和æ•
障演练。
最åŽï¼ŒElasticSearchçš„å¦ä¹ 曲线确实陡å³ï¼Œä½†ä¸€æ—¦æŽŒæ¡ï¼Œä½ 会å‘现它是一个强大而优é›
çš„æœç´¢å¼•æ“Žã€‚å¸Œæœ›è¿™ç¯‡æ–‡ç« èƒ½å¸®åŠ©ä½ å°‘èµ°å¼¯è·¯ï¼Œåœ¨å®žè·µä¸çœŸæ£å‘挥ElasticSearchçš„å¨åŠ›ã€‚
ä½œè€ ï¼šæž¶æž„å®žæˆ˜ç³»åˆ— | å—æ•°ï¼šçº¦4500å—
《【架构实战】ElasticSearch搜索集群:全文检索的艺术》 是转载文章,点击查看原文。
