對比 elasticsearch 和 mysql

2023-03-24 18:00:19

最近閱讀了elasticsearch的官方檔案,學習了它的很多特性,發現elasticsearch和mysql有很多地方類似,也有很多地方不同。這裡做一個對比,幫助大家加深對elasticsearch的理解。

特性 elasticsearch mysql 備註
場景 全文搜尋,紀錄檔處理,空間資料分析 表結構儲存 es 不適合做join操作,mysql 不適合做全文檢索
擴充套件性 動態擴充套件,能夠通過新增node快速提升效能 mysql cluster  
master 選舉 bully 演演算法,比較id選出master master-slave結構,無需選舉 es中master選舉可能會出現腦裂問題,設定

minimum_master_nodes引數確保過半選舉決定機制

路由演演算法
routing_factor = num_routing_shards / num_primary_shards
shard_num = (hash(_routing) % num_routing_shards) / routing_factor

 指定路由分片:

my-index-000001/_doc/1?routing=user1&refresh=true
手動路由,或者使用路由元件sharding-jdbc  
可靠性 Cross-cluster replication (CCR), 雙叢集設計 主從複製,雙資料中心  
記憶體設定 heap size 推薦 32g,但不要超過記憶體的一半, 其他需要用到堆外記憶體的地方,網路,檔案快取,jvm的棧 實體記憶體的80% 單獨的伺服器
快取

filesystem cache, request cahce, query cache

所有cache都是基於node

query cache (deprecated)  
資料塊大小

分片大小 幾g ~ 幾十g, time based data, 20g ~ 40g

分片數量,每g記憶體小於20分片

shard越多,維護索引成本越高

shard越大,rebalance越慢

單表資料不超過2kw,3層b+樹能儲存的資料大概是2kw,如果b+層級變高,查詢速度會顯著降低  
資料結構 json,底層是lucene table,底層是b+ tree  
索引

倒排表,fst

正向檔案,分塊 + 壓縮

DocValues, 對映檔案 + 壓縮

b+數,聚簇/非聚簇索引  
定義資料結構的方式 mapping (dynamic mapping & static mapping) schema  
支援自動建立資料結構  
事務 near real-time,需要refresh才可以查詢到 reaptable read,高階事務  
Index blocks,比如 index.blocks.read_only,索引唯讀 豐富的鎖機制,表鎖,行鎖,間隙鎖  
檔案系統

預設mmapfs,採用記憶體對映方式存取檔案,也支援其他的檔案系統,比如fs, niofs, hybirdfs

fs  
資料恢復

es在寫入之前會先將資料寫入到translog,用來對異常情況進恢復

flush,lucene 進行提交,並且同時重新開啟一段 translog

index.translog.sync_interval,持久化translog 間隔,5s

index.translog.flush_threshold_size, flush translog閾值大小,512m

redo log採用的是WAL(Write-ahead logging,預寫式紀錄檔),所有修改先寫入紀錄檔,再更新到Buffer Pool,保證了資料不會因MySQL宕機而丟失,從而滿足了永續性要求

es 和 mysql 處理資料恢復的模式基本一致
flush機制

從記憶體快取寫入磁碟快取memorybuffer -> filesystem cache(refresh)

刷盤,filesystem cache -> disk ( flush)

定時觸發或者 translog > 512M

buffer pool -> disk

當redo log滿了,或者buffer pool空間不足

es 和 mysql 刷盤模式基本一致
備份

snapshot

mysqldump -u root -h host -p --all-databases > backdb.sql

 
慢紀錄檔

比如 index.search.slowlog.threshold.query.warn: 10s

long_query_time=10  
服務呼叫方式 rest api mysql connection + sql  
資料型別 較為豐富的資料型別,boolean, keyword, long, data, object, nested, range, ip, text, arrays

int, data, varchar

es 提供了非常多的資料型別,一些是為了支援全文檢索,一些能夠方便查詢,比如range,ip
資料屬性

analyzer,分詞器

index,是否被索引,沒有被索引的欄位不可查詢

fielddata,如果想對text型別的欄位進行聚合,排序,或者執行指令碼,就必須設定fielddata屬性

doc_values,將_source 轉化為表結構放在磁碟上,方便聚合,排序,或者指令碼操作,預設支援除了text型別的所有型別

...

主鍵索引, 可空,唯一值,自增,預設值

es的資料屬性更復雜
查詢超時

設定 query timeout

set wait_timeout = 10

 
context

es查詢需要區分query context, 還是 filter context,前者會進行打分,後者只進行過濾

不需要區分

 
打分查詢

比如match,match_phrase

不支援

 
runtime field

使用script 建立臨時欄位

語法支援 select concat (a, b) as c

script更靈活,但是效能會降低
精確查詢

比如term, terms, ids, exists

語法支援

mysql使用起來更方便
分組聚合查詢

比如histogram aggs,terms aggs

group by

es支援的型別稍微豐富一些,方便開發
指標聚合查詢

avg, max, min, sum ,count, cardinality aggs,percentile aggs

語法支援, count(*), distinct es是分散式的,聚合的時候存在一些精度問題
分頁

from + size (不適合深分頁,有去重問題)

search_after + PIT (推薦)

scroll (不適合深分頁)

limit + size

或者進行條件關聯,書籤

在深分頁上的處理方案上基本一致
profile  
{
  "profile": true,
  "query" : {
    "match" : { "message" : "GET /search" }
  }
}
 explain  
script支援 painless script 不支援