欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文詳解為什么用ElasticSearch以及和傳統(tǒng)數(shù)據(jù)庫MySQL有什么區(qū)別

 更新時間:2025年07月17日 09:51:17   作者:尤物程序猿  
Elasticsearch和MySQL都是非常重要的數(shù)據(jù)庫管理系統(tǒng),它們在各種應(yīng)用場景中都有著廣泛的應(yīng)用,這篇文章主要介紹了為什么用ElasticSearch以及和傳統(tǒng)數(shù)據(jù)庫MySQL有什么區(qū)別的相關(guān)資料,需要的朋友可以參考下

Elasticsearch 深度解析:從原理到實踐

一、為什么選擇 Elasticsearch?

數(shù)據(jù)模型
Elasticsearch 是基于文檔的搜索引擎,它使用 JSON 文檔來存儲數(shù)據(jù)。在 Elasticsearch 中,相關(guān)的數(shù)據(jù)通常存儲在同一個文檔中,而不是分散在多個表中。

MySQL 是一個關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它使用表、行和列的結(jié)構(gòu)來組織數(shù)據(jù)。數(shù)據(jù)通過外鍵關(guān)系分散在多個表中。

查詢語言
Elasticsearch 使用 Query DSL(Domain Specific Language),這是一種非常靈活的查詢語言,基于 JSON,支持全文搜索、復(fù)合查詢、過濾以及聚合等。

MySQL 使用 SQL(Structured Query Language),這是一種強類型和非常成熟的語言,專門用于查詢和管理關(guān)系數(shù)據(jù)庫。

全文搜索
Elasticsearch 的核心功能是全文搜索。
它對數(shù)據(jù)進(jìn)行索引時會自動建立全文搜索索引,使其在搜索大量文本數(shù)據(jù)時表現(xiàn)優(yōu)異。

MySQL 雖然也提供了基本的全文搜索功能,但其主要設(shè)計目標(biāo)是處理結(jié)構(gòu)化數(shù)據(jù)的存儲和查詢,對全文搜索的支持不如 Elasticsearch 那樣強大。

事務(wù)支持
Elasticsearch 不支持傳統(tǒng)的 ACID(原子性、一致性、隔離性、持久性)事務(wù)。雖然它確保了單個文檔操作的原子性,但不適用于跨多個文檔的復(fù)雜事務(wù)。雖然 Elasticsearch 不支持傳統(tǒng)的事務(wù),但是他是可以確保單個文檔的更改(如創(chuàng)建、更新、刪除)是原子性的。這意味著任何文檔級的操作都完整地成功或完整地失敗,但不保證跨多個文檔或操作的一致性。

MySQL 支持 ACID 事務(wù),這使得它非常適合需要嚴(yán)格數(shù)據(jù)一致性的應(yīng)用,如金融服務(wù)和其他商業(yè)數(shù)據(jù)處理。

支持樂觀鎖:

Elasticsearch 支持通過使用文檔版本控制來實現(xiàn)樂觀鎖。

6.7之前。在 ES 中,每個文檔存儲時都有一個 _version 字段,這個版本號在每次文檔更新時自動增加。當(dāng)我們執(zhí)行更新、刪除或者使用腳本處理文檔時,可以指定這個版本號來確保正在操作的文檔是預(yù)期中的版本。如果操作中的版本號與存儲在索引中的文檔版本號不一致,說明文檔已被其他操作更改,當(dāng)前操作將會失敗。(CAS)

為什么_version在后續(xù)版本被拋棄

_version 機制是基于單一遞增整數(shù),它主要適用于簡單的沖突檢測,但在復(fù)雜的分布式系統(tǒng)中,僅依靠版本號可能無法準(zhǔn)確地反映數(shù)據(jù)的歷史和復(fù)制狀態(tài)。尤其是在發(fā)生網(wǎng)絡(luò)分區(qū)或節(jié)點故障時,僅憑 _version 可能導(dǎo)致數(shù)據(jù)丟失或過時的數(shù)據(jù)被錯誤地寫入。

主要還是高并發(fā)和高可用的環(huán)境下,單一的-version不足以處理因節(jié)點故障網(wǎng)絡(luò)問題導(dǎo)致的多個副本之間的數(shù)據(jù)不一致問題。

然而if_seq_no 和 if_primary_term這兩個參數(shù)可以更準(zhǔn)確地確定操作是否應(yīng)當(dāng)被執(zhí)行,可以跟蹤每個文檔變更的序列號主分片的期限。這種機制幫助確保即使在集群狀態(tài)發(fā)生變化(如分片重新分配到新的節(jié)點)的情況下,也不會應(yīng)用基于過時副本的更新。它有效地防止了腦裂問題

6.7之后,使用 _version 關(guān)鍵字進(jìn)行樂觀鎖已經(jīng)被廢棄了,替代方法是使用

if_seq_no (是一個遞增的序列號,表示文檔的每次修改)和

if_primary_term(表示主分片的當(dāng)前任期,每當(dāng)主分片發(fā)生變化時,這個值會增加。) 

來指定版本。

1. 核心優(yōu)勢()

維度ElasticsearchMySQL
數(shù)據(jù)模型文檔型(JSON),動態(tài)映射關(guān)系型(嚴(yán)格Schema)
搜索能力全文檢索、模糊匹配、語義分析僅支持精確查詢和簡單LIKE
擴展性分布式架構(gòu),自動分片/副本分庫分表復(fù)雜
吞吐量單集群支持每秒10萬+查詢高并發(fā)寫入更優(yōu)
一致性最終一致性(近實時)強一致性(ACID)

Elasticsearch是一個開源的分布式搜索和分析引擎,主要適用于以下場景:

1:搜索引擎:用于快速檢索文檔、商品、新聞等。

2:日志分析:通過分析日志數(shù)據(jù),幫助企業(yè)了解其業(yè)務(wù)的性能情況。

3:數(shù)據(jù)分析:幫助數(shù)據(jù)科學(xué)家和數(shù)據(jù)分析師進(jìn)行數(shù)據(jù)分析,以獲取有價值的信息。

4:商業(yè)智能:幫助企業(yè)制定數(shù)據(jù)驅(qū)動的決策,以實現(xiàn)商業(yè)上的成功。

5:實時監(jiān)控:幫助企業(yè)實時監(jiān)測系統(tǒng)性能、監(jiān)控數(shù)據(jù)變化,以保證系統(tǒng)正常運行。

6:安全性:幫助企業(yè)保證數(shù)據(jù)的安全性,保證數(shù)據(jù)不被非法竊取。

7:應(yīng)用程序開發(fā):幫助開發(fā)人員開發(fā)基于搜索的應(yīng)用程序,以增加用戶體驗。

Elasticsearch具有以下幾個優(yōu)勢:

1:高性能:Elasticsearch具有高性能的搜索和分析能力,其中涵蓋了多種查詢語言和數(shù)據(jù)結(jié)構(gòu)。

2:可擴展性:Elasticsearch是分布式的,可以通過增加節(jié)點數(shù)量擴展搜索和分析能力。

3:靈活性:Elasticsearch支持多種數(shù)據(jù)類型,支持多種語言,支持動態(tài)映射,允許快速地調(diào)整模型以適應(yīng)不同的需求。

4:實時分析:Elasticsearch支持實時分析,可以對數(shù)據(jù)進(jìn)行實時查詢,這對于快速檢索數(shù)據(jù)非常有用。

5:可靠性:Elasticsearch具有可靠性和高可用性,支持?jǐn)?shù)據(jù)備份和恢復(fù)。

ES為什么塊:

1:分布式存儲:Elasticsearch使用分布式存儲技術(shù),將數(shù)據(jù)存儲在多個節(jié)點上,從而減少單個節(jié)點的壓力,提高整體性能。

2:索引分片:Elasticsearch把每個索引劃分成多個分片,這樣可以讓查詢操作并行化,從而提高查詢速度。

3:全文索引:Elasticsearch使用了高效的全文索引技術(shù),把文檔轉(zhuǎn)化成可搜索的結(jié)構(gòu)化數(shù)據(jù),使得搜索操作快速高效。

4:倒排索引:Elasticsearch支持倒排索引這種數(shù)據(jù)結(jié)構(gòu),倒排索引將文檔中的每個詞與該詞出現(xiàn)在哪些文檔中進(jìn)行映射,并存儲這些信息。當(dāng)搜索請求發(fā)生時,ES可以快速查找包含所有搜索詞的文檔,從而返回結(jié)果。

5:索引優(yōu)化:Elasticsearch通過索引優(yōu)化技術(shù),可以使查詢速度更快。例如,它支持索引覆蓋、索引下推等優(yōu)化技術(shù),使得查詢速度更快。

6:預(yù)存儲結(jié)果:Elasticsearch在插入數(shù)據(jù)時,對數(shù)據(jù)進(jìn)行預(yù)處理,把結(jié)果預(yù)存儲到索引中,從而在查詢時不需要再重新計算,提高查詢速度。

7:高效的查詢引擎:Elasticsearch使用了高效的查詢引擎,支持各種類型的查詢,并對復(fù)雜查詢提供了優(yōu)化策略,從而提高查詢速度。

8:異步請求處理:ES使用了異步請求處理機制,能夠在請求到達(dá)時立即返回,避免長時間的等待,提高用戶體驗。

9:內(nèi)存存儲:ES使用了內(nèi)存存儲技術(shù),能夠在讀寫數(shù)據(jù)時大大減少磁盤訪問次數(shù),提高數(shù)據(jù)存儲和查詢效率。

我覺得最重要就是倒排索引了:它 用于快速搜索文檔中的某個詞匯。

假設(shè)我們有一個原始文檔:

文檔ID文檔內(nèi)容
Doc1"Elasticsearch is fast"
Doc2"Redis is fast too"
Doc3

"Elasticsearch and Redis"

主要分為倆個過程:

分詞(Tokenization)

  • Doc1 → ["elasticsearch", "is", "fast"]

  • Doc2 → ["redis", "is", "fast", "too"]

  • Doc3 → ["elasticsearch", "and", "redis"]

生成詞項-文檔映射

Term            DocIDs (Postings List)
─────────────────────────────────────
"and"           → [Doc3]
"elasticsearch" → [Doc1, Doc3]
"fast"          → [Doc1, Doc2]
"is"            → [Doc1, Doc2]
"redis"         → [Doc2, Doc3]
"too"           → [Doc2]

2. 倒排索引的核心組件

組件作用示例
詞項字典(Term Dictionary)存儲所有唯一詞項,通常用 FST(有限狀態(tài)轉(zhuǎn)換器) 壓縮存儲"elasticsearch", "redis"
倒排列表(Postings List)記錄包含該詞項的文檔ID及位置信息(支持快速跳表SkipList優(yōu)化遍歷)Doc1:[pos1,pos2], Doc3:[pos1]
詞頻(TF)詞項在文檔中的出現(xiàn)次數(shù)(用于相關(guān)性評分)"fast"在Doc1中TF=1
文檔頻率(DF)包含該詞項的文檔數(shù)(用于IDF計算)"elasti

倒排索引的優(yōu)化技術(shù)

  1. 壓縮存儲

    • FST:壓縮詞項字典,減少內(nèi)存占用。

    • Delta Encoding:對文檔ID差值編碼(如[100, 102, 105]→[100, +2, +3])。

  2. 跳表(SkipList)

    • 加速倒排列表的合并操作(如AND查詢)。

  3. 多級索引

    • 內(nèi)存中保留熱點詞項,磁盤存全量數(shù)據(jù)。

二、Elasticsearch 核心技術(shù)細(xì)節(jié)

1. 分詞器(Analyzer)

分詞器類型功能說明示例
Standard默認(rèn)分詞器,按空格/標(biāo)點切分"Elasticsearch" → ["elasticsearch"]
IK Analyzer中文分詞(社區(qū)版+擴展詞典)

IK分詞器有幾種模式?

  • ik_smart:智能切分,粗粒度
  • ik_max_word:最細(xì)切分,細(xì)粒度

IK分詞器如何拓展詞條?如何停用詞條?

  • 利用config目錄的IkAnalyzer.cfg.xml文件添加拓展詞典和停用詞典
  • 在詞典中添加拓展詞條或者停用詞條
"華為手機" → ["華為", "手機"]
Pinyin中文轉(zhuǎn)拼音搜索"北京" → ["beijing", "bj"]
Whitespace僅按空格切分"hello world" → ["hello", "world"]
Keyword不分詞,整體作為Term"2023-08-15" → ["2023-08-15"]

自定義分詞器

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ik": {
          "type": "custom",
          "tokenizer": "ik_max_word",
          "filter": ["lowercase"]
        }
      }
    }
  }
}

2. 底層原理

  • 倒排索引(Inverted Index)

    • Term → Document ID 的映射(如“手機” → [Doc1, Doc3])。

    • 通過 FST(Finite State Transducer) 壓縮存儲,減少內(nèi)存占用。

  • 分片(Shard)機制

    • 索引自動拆分為多個分片(默認(rèn)5個),分散到不同節(jié)點。

    • 每個分片有1個主副本和N個從副本(通過_settings調(diào)整)。

  • 近實時(NRT)

    • 數(shù)據(jù)寫入后默認(rèn)1秒(refresh_interval)可被搜索,通過 translog 保證持久化。

3. 查詢高效的原因

  • 分布式計算

    • 查詢并行發(fā)送到所有分片,結(jié)果聚合(Scatter-Gather模式)。

  • 緩存優(yōu)化

    • Query Cache:緩存過濾條件結(jié)果。

    • Fielddata:文本字段啟用內(nèi)存緩存(慎用,易OOM)。

  • 列式存儲(Doc Values)

    • 對排序、聚合字段預(yù)先構(gòu)建磁盤數(shù)據(jù)結(jié)構(gòu),避免實時計算。

4. 增刪改操作

  • 寫入流程

    1. 請求發(fā)送到協(xié)調(diào)節(jié)點。

    2. 路由到對應(yīng)分片的主副本。

    3. 寫入Lucene內(nèi)存Buffer和translog。

    4. 定期刷新(Refresh)生成新Segment(可搜索)。

    5. 后臺合并(Merge)Segment優(yōu)化存儲。

  • 刪除

    • 標(biāo)記文檔為deleted,Merge時物理刪除。

  • 更新

    • 先刪除舊文檔,再寫入新文檔(版本號_version遞增)。

三、關(guān)鍵問題解決方案

1. 深度分頁優(yōu)化

  • 問題from 10000, size 10 需遍歷所有分片的10010條記錄。在Elasticsearch中進(jìn)行分頁查詢通常使用from和size參數(shù)。當(dāng)我們對Elasticsearch發(fā)起一個帶有分頁參數(shù)的查詢(如使用from和size參數(shù))時,ES需要遍歷所有匹配的文檔直到達(dá)到指定的起始點(from),然后返回從這一點開始的size個文檔。跟MySQL的深度分頁原因差不多,

  • 方案

    • Search After:search_after 是 Elasticsearch 中用于實現(xiàn)深度分頁的一種機制。與傳統(tǒng)的分頁方法(使用 from 和 size 參數(shù))不同,search_after 允許你基于上一次查詢的結(jié)果來獲取下一批數(shù)據(jù),這在處理大量數(shù)據(jù)時特別有效。

      在第一次查詢時,你需要定義一個排序規(guī)則。不需要指定 search_after 參數(shù):

      {
        "query": { "match_all": {} },
        "size": 10,
        "sort": [{"_id": "asc"}],//在第一次查詢時,你需要定義一個排序規(guī)則。
        "search_after": [last_id]
      //第一次查詢不要定義,在后續(xù)的查詢中,使用上一次查詢結(jié)果中最后一條記錄的排序值
      //search_after包含timestamp和last_id 的值,對應(yīng)上一次查詢結(jié)果的最后一條記錄。
      
      }

      search_after 可以有效解決深度分頁問題,原因如下:
      避免重復(fù)處理數(shù)據(jù):與傳統(tǒng)的分頁方式不同,search_after 不需要處理每個分頁請求中所有先前頁面上的數(shù)據(jù)。這大大減少了處理數(shù)據(jù)的工作量。

      提高查詢效率:由于不需要重復(fù)計算和跳過大量先前頁面上的數(shù)據(jù),search_after 方法能顯著提高查詢效率,尤其是在訪問數(shù)據(jù)集靠后部分的數(shù)據(jù)時。

      但是這個方案有一些局限,一方面需要有一個全局唯一的字段用來排序,另外雖然一次分頁查詢時不需要處理先前頁面中的數(shù)據(jù),但實際需要依賴上一個頁面中的查詢結(jié)果。

    • 適用于深度分頁和大數(shù)據(jù)集的遍歷。

    • Scroll API:Scroll API在Elasticsearch中的主要目的是為了能夠遍歷大量的數(shù)據(jù),它通常用于數(shù)據(jù)導(dǎo)出或者進(jìn)行大規(guī)模的數(shù)據(jù)分析??梢杂糜谔幚泶罅繑?shù)據(jù)的深度分頁問題。

  • POST /_search/scroll { "scroll": "1m", "scroll_id": "DXF1ZXJ5QW..." }
    //如上方式初始化一個帶有scroll參數(shù)的搜索請求。這個請求返回一個scroll ID,用于后續(xù)的滾動。Scroll參數(shù)指定了scroll的有效期,例如1m表示一分鐘。
    
    //接下來就可以使用返回的scroll ID來獲取下一批數(shù)據(jù)。每次請求也會更新scroll ID的有效期。
    • 業(yè)務(wù)妥協(xié):限制最大頁碼(如只展示前100頁)。

    • 避免重復(fù)排序:在傳統(tǒng)的分頁方式中,每次分頁請求都需要對所有匹配的數(shù)據(jù)進(jìn)行排序,以確定分頁的起點。Scroll避免了這種重復(fù)排序,因為它保持了一個游標(biāo)。

    • 穩(wěn)定視圖:Scroll提供了對數(shù)據(jù)的“穩(wěn)定視圖”。當(dāng)你開始一個scroll時,Elasticsearch會保持搜索時刻的數(shù)據(jù)快照,這意味著即使數(shù)據(jù)隨后被修改,返回的結(jié)果仍然是一致的。

    • 減少資源消耗:
      由于不需要重復(fù)排序,Scroll減少了對CPU和內(nèi)存的消耗,特別是對于大數(shù)據(jù)集。

    • Scroll非常適合于處理需要訪問大量數(shù)據(jù)但不需要快速響應(yīng)的場景,如數(shù)據(jù)導(dǎo)出、備份或大規(guī)模數(shù)據(jù)分析。

      但是,需要知道,使用Scroll API進(jìn)行分頁并不高效,因為你需要先獲取所有前面頁的數(shù)據(jù)。Scroll API主要用于遍歷整個索引或大量數(shù)據(jù),而不是用于快速訪問特定頁數(shù)的數(shù)據(jù)。

2. 數(shù)據(jù)一致性

第一種方法:雙寫一致性

對MySQL和ES進(jìn)行雙寫,先更新數(shù)據(jù)庫,再更新ES,放在一個事務(wù)里面,需要保證事務(wù)的一致性。有數(shù)據(jù)不一致的風(fēng)險,比如MySQL寫入成功,但是ES發(fā)生了寫入成功但因為超時拋異常了就會出現(xiàn)數(shù)據(jù)不一致的情況。

第二種方法:使用消息隊列MQ進(jìn)行處理

在更新數(shù)據(jù)庫時,發(fā)送一個消息到MQ中,然后數(shù)據(jù)庫和ES各設(shè)置一個監(jiān)聽者,監(jiān)聽消息之后各自去做數(shù)據(jù)變更,如果失敗了就基于消息的重試在重新執(zhí)行。

好處是進(jìn)行了異步解耦,性能稍后,但是有延遲

第三種方法:定時掃描MySQL

如果ES中的數(shù)據(jù)變更的實時性要求不高,可以考慮定時任務(wù)掃表來批量更新ES。

這個方案優(yōu)點是沒有侵入性,數(shù)據(jù)庫的寫操作處不需要改代碼。

缺點是實時性很差,并且輪詢可能存在性能問題、效率問題以及給數(shù)據(jù)庫帶來壓力。

第四種方法:監(jiān)聽binlog日志(基于canal做數(shù)據(jù)同步的方案)

對業(yè)務(wù)代碼完全沒有侵入性,業(yè)務(wù)也非常解耦,不需要關(guān)心這個ES的更新操作。

缺點就是需要基于binlog監(jiān)聽,需要引入第三方框架。存在一定的延遲。

一致性級別實現(xiàn)方案優(yōu)缺點
強一致性寫入后立即refresh(性能差)數(shù)據(jù)最新,吞吐量下降
最終一致性默認(rèn)1秒刷新 + 手動_refresh(平衡選擇)性能高,短暫延遲

與Canal集成:主要的過程

  1. MySQL Binlog → Canal Server 解析變更。

  2. Canal Client → Kafka 發(fā)送變更事件。

  3. Logstash/自定義Consumer → 寫入ES

關(guān)于Logstash和自定義Consumer

. Logstash 是什么?

  • 定位:開源的數(shù)據(jù)處理管道工具,屬于 Elastic Stack(ELK)的一部分。

  • 核心功能

    • 數(shù)據(jù)輸入(Input):從 Kafka、MySQL、文件等讀取數(shù)據(jù)。

    • 數(shù)據(jù)過濾(Filter):清洗、轉(zhuǎn)換、豐富數(shù)據(jù)(如字段重命名、類型轉(zhuǎn)換)。

    • 數(shù)據(jù)輸出(Output):將處理后的數(shù)據(jù)寫入 ES、MySQL、文件等。

  • 特點

    • 配置驅(qū)動:通過配置文件定義數(shù)據(jù)處理流程,無需編碼。

    • 插件化:支持 200+ 官方/社區(qū)插件(如 kafkaelasticsearch、grok)。

Canal → ES 場景中的用途

將 Canal 發(fā)送到 Kafka 的 MySQL Binlog 數(shù)據(jù)轉(zhuǎn)換為 ES 所需的格式,并寫入 ES。

 自定義 Consumer 是什么?

  • 定位:用戶自行編寫的程序(通常用 Java/Python/Go),用于消費 Kafka 消息并處理。

  • 核心功能

    • 從 Kafka 拉取 Canal 生成的 Binlog 消息。

    • 解析消息并轉(zhuǎn)換為 ES 支持的格式(如 JSON)。

    • 調(diào)用 ES 的 API 寫入數(shù)據(jù)。

  • 特點

    • 靈活可控:可自定義業(yè)務(wù)邏輯(如特殊字段處理、錯誤重試)。

    • 高性能:通過批量寫入、異步請求等優(yōu)化吞吐量。

整體架構(gòu)流程:

3. ES支持的數(shù)據(jù)結(jié)構(gòu)

  • 核心類型

    • Text:用于存儲全文文本數(shù)據(jù)。

    • Keyword:用于存儲文本值,通常用于索引結(jié)構(gòu)化內(nèi)容,如郵件地址、標(biāo)簽或任何需要精確匹配的內(nèi)容。

    • Nested:類似于 Object 類型,但用于存儲數(shù)組列表,其中列表中的每個元素都是完全獨立且可搜索的。

    • Long, Integer, Short, Byte, Double, Float: 這些是數(shù)值類型,用于存儲各種形式的數(shù)字。

    • Date: 存儲日期或日期和時間。

    • Boolean: 存儲 true 或 false 值。

    • Binary: 用于存儲二進(jìn)制數(shù)據(jù)。

    • Object: 用于嵌套文檔,即文檔內(nèi)部可以包含文檔。

  • 特殊類型

    • Flattened:避免深層JSON字段爆炸。

    • Join:父子文檔(性能較差,慎用)。

  • text 和 keyword 有啥區(qū)別?

    text 類型被設(shè)計用于全文搜索。這意味著當(dāng)文本被存儲為 text 類型時,Elasticsearch 會對其進(jìn)行分詞,把文本分解成單獨的詞或短語,便于搜索引擎進(jìn)行全文搜索。因為 text 字段經(jīng)過分詞,它不適合用于排序或聚合查詢。

    text適用于存儲需要進(jìn)行全文搜索的內(nèi)容,比如新聞文章、產(chǎn)品描述等。

    keyword 類型用于精確值匹配,不進(jìn)行分詞處理。這意味著存儲在 keyword 字段的文本會被當(dāng)作一個完整不可分割的單元進(jìn)行處理。因為 keyword 類型字段是作為整體存儲,它們非常適合用于聚合(如計數(shù)、求和、過濾唯一值等)和排序操作。由于不進(jìn)行分詞,keyword 類型字段不支持全文搜索,但可以進(jìn)行精確匹配查詢。

    keyword適用于需要進(jìn)行精確搜索的場景,比如標(biāo)簽、ID 編號、郵箱地址等。

  • ES 不支持 decimal,如何避免丟失精度?

五種方法:

一:使用字符串類型(比較好用)

完全保留數(shù)字的精度。簡單易于實現(xiàn),數(shù)據(jù)遷移時不需特別處理。但是作為字符串存儲的數(shù)字不能直接用于數(shù)值比較或數(shù)學(xué)運算,需要在應(yīng)用層處理轉(zhuǎn)換。但也不是什么大毛病。

二:擴大浮點類型的精度

就是直接使用 double 類型,在理論上可能會有精度損失,但實際上 double 類型提供的精度對于許多業(yè)務(wù)需求已經(jīng)足夠使用。需要接受減小精度損失。

三:使用scaled_float(推薦)

Elasticsearch 的 scaled_float 類型是一種數(shù)值數(shù)據(jù)類型,專門用于存儲浮點數(shù)。其特點是通過一個縮放因子(scaling factor)將浮點數(shù)轉(zhuǎn)換為整數(shù)來存儲,從而在一定范圍內(nèi)提高存儲和計算的效率。他使用一個縮放因子將浮點數(shù)轉(zhuǎn)換為整數(shù)存儲。例如,如果縮放因子是 100,那么值 123.45 會存儲為 12345。這樣可以避免浮點數(shù)存儲和計算中的精度問題。

四:使用多個字段

在某些情況下,可以將 decimal 數(shù)值拆分為兩個字段存儲:一個為整數(shù)部分,另一個為小數(shù)部分。這樣做可以在不丟失精度的情況下,將數(shù)值分開處理。可以保持?jǐn)?shù)值精確,同時可進(jìn)行部分?jǐn)?shù)學(xué)運算。但是增加了數(shù)據(jù)處理的復(fù)雜性,需要在應(yīng)用層重建數(shù)值。

五:使用自定義腳本

用 Elasticsearch 的腳本功能(如 Painless 腳本)來處理數(shù)值計算,確保在處理過程中控制精度。優(yōu)點:靈活控制數(shù)據(jù)處理邏輯。缺點:可能影響查詢性能,增加系統(tǒng)復(fù)雜性。

四、實際應(yīng)用場景

1. 電商搜索

  • 需求:支持顏色、品牌、價格區(qū)間等多維度過濾。

  • 實現(xiàn)

{
  "query": {
    "bool": {
      "must": [
        { "term": { "brand": "華為" } },
        { "range": { "price": { "gte": 1000, "lte": 2000 } } }
      ],
      "filter": { "term": { "color": "紅色" } }
    }
  },
  "aggs": {
    "price_stats": { "stats": { "field": "price" } }
  }
}

2. 日志告警

  • 需求:實時檢測ERROR日志并觸發(fā)告警。

  • 實現(xiàn)

    • Watcher 插件定時查詢:

  • {
      "query": { "match": { "level": "ERROR" } },
      "condition": { "compare": { "ctx.hits.total": { "gt": 0 } } },
      "actions": { "email": { "to": "admin@example.com" } }
    }

3. 數(shù)據(jù)同步容災(zāi)

  • 雙寫方案

    • 應(yīng)用同時寫MySQL和ES,通過本地事務(wù)表記錄同步狀態(tài)。

  • 補償機制

    • 定時任務(wù)掃描MySQL與ES差異數(shù)據(jù),修復(fù)不一致。

五、性能調(diào)優(yōu)

集群和硬件優(yōu)化

負(fù)載均衡: 確保查詢負(fù)載在集群中均衡分配。

硬件資源: 根據(jù)需要增加 CPU、內(nèi)存或改善 I/O 性能(例如使用 SSD)。

配置 JVM: 優(yōu)化 JVM 設(shè)置,如堆大小,以提高性能。

  • 硬件:SSD磁盤、32GB+內(nèi)存(堆內(nèi)存不超過31GB)。

  • 索引設(shè)計

    • 選擇合適的分詞器

      冷熱分離:hot-warm架構(gòu)(熱數(shù)據(jù)用SSD,冷數(shù)據(jù)用HDD)。
    • 生命周期管理(ILM):自動滾動到新索引。

  • 查詢優(yōu)化

    • 避免wildcard、regexp查詢(如*test*)。

    • 使用constant_score過濾不相關(guān)文檔。

    • 使用過濾器: 對于不需要評分的查詢條件,使用 filter 而不是 query,因為 filter 可以被緩存以加快后續(xù)相同查詢的速度。

    • 合理使用聚合:聚合可以用于高效地進(jìn)行數(shù)據(jù)分析,但復(fù)雜的聚合也可能非常消耗資源。優(yōu)化聚合查詢,如通過限制桶的數(shù)量,避免過度復(fù)雜的嵌套聚合。

    • 查詢盡可能少的字段: 只返回查詢中需要的字段,減少數(shù)據(jù)傳輸和處理時間。

    • 避免深度分頁: 避免深度分頁,對于需要處理大量數(shù)據(jù)的情況,考慮使用 search_after。

總結(jié)

  • 選型:ES適合搜索/分析,MySQL適合事務(wù)/精準(zhǔn)查詢。

  • 核心能力:分詞器、倒排索引、分布式計算支撐高效查詢。

  • 一致性:通過refresh、Canal同步等方案平衡實時性與性能。

  • 實踐:結(jié)合業(yè)務(wù)場景選擇分頁策略、數(shù)據(jù)結(jié)構(gòu)、同步機制。

到此這篇關(guān)于為什么用ElasticSearch以及和傳統(tǒng)數(shù)據(jù)庫MySQL有什么區(qū)別的文章就介紹到這了,更多相關(guān)es和mysql對比內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 跨域問題的處理方式

    Java 跨域問題的處理方式

    這篇文章主要介紹了Java 跨域問題的處理方式,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • Mybatis動態(tài)調(diào)用表名和字段名的解決方法

    Mybatis動態(tài)調(diào)用表名和字段名的解決方法

    今天在項目開發(fā)中有個業(yè)務(wù)是需要限制各個用戶對某些表里的字段查詢以及某些字段是否顯示,這種情況下,就需要構(gòu)建sql來動態(tài)傳入表名、字段名了,下面給大家介紹mybatis動態(tài)調(diào)用表名和字段名的解決方法,一起看看吧
    2016-10-10
  • java實現(xiàn)簡單租車系統(tǒng)

    java實現(xiàn)簡單租車系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)簡單租車系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Spring @Cacheable redis異常不影響正常業(yè)務(wù)方案

    Spring @Cacheable redis異常不影響正常業(yè)務(wù)方案

    這篇文章主要介紹了Spring @Cacheable redis異常不影響正常業(yè)務(wù)方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Spring 應(yīng)用中集成 Apache Shiro的方法

    Spring 應(yīng)用中集成 Apache Shiro的方法

    這篇文章主要介紹了Spring 應(yīng)用中集成 Apache Shiro的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • java編程學(xué)習(xí)輸入輸出詳解看完快速上手

    java編程學(xué)習(xí)輸入輸出詳解看完快速上手

    這篇文章主要介紹了java編程學(xué)習(xí)輸入輸出到控制臺的知識詳解,看完就可以快速上手了,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • 淺析java貪心算法

    淺析java貪心算法

    這篇文章簡單主要介紹了java貪心算法,包含貪心算法的基本思路,性質(zhì),以及實現(xiàn)示例,有需要的小伙伴參考下
    2015-02-02
  • Spring的@ComponentScan注解用法介紹

    Spring的@ComponentScan注解用法介紹

    這篇文章主要介紹了Spring的@ComponentScan注解用法介紹,@ComponentScan注解一般和@Configuration注解一起使用,主要的作用就是定義包掃描的規(guī)則,然后根據(jù)定義的規(guī)則找出哪些需類需要自動裝配到spring的bean容器中,然后交由spring進(jìn)行統(tǒng)一管理,需要的朋友可以參考下
    2023-11-11
  • java文件對話框過濾特定文件類型示例

    java文件對話框過濾特定文件類型示例

    文件作為存儲數(shù)據(jù)的單元,會根據(jù)數(shù)據(jù)類型產(chǎn)生很多分類,也就是所謂的文件類型。在對數(shù)據(jù)文件進(jìn)行操作時,常常需要根據(jù)不同的文件類型來作不同的處理。本實例實現(xiàn)的是讀取文件夾指定類型的文件并顯示到表格控件中
    2014-02-02
  • Spring集成webSocket頁面訪問404問題的解決方法

    Spring集成webSocket頁面訪問404問題的解決方法

    這篇文章主要介紹了Spring集成webSocket頁面訪問404問題的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12

最新評論