一文详解为什么用ElasticSearch以及和传统数据库MySQL有什么区别

《一文详解为什么用ElasticSearch以及和传统数据库MySQL有什么区别》Elasticsearch和MySQL都是非常重要的数据库管理系统,它们在各种应用场景中都有着广泛的应用,这篇文章主要... ...

Elasticsearch 深度解析:从原理到实践

一、为什么选择 Elasticsearch?

数据模型
Elasticsearch 是基于文档的搜索引擎,b V * K@ ? 1 T d ? f V YK B H / )它使用z . , / jsON 文档来G 6 5 {存储数据。4 j M在 Elasti4 n 8 / + H d _cse: e % Uarch 中c O s n O M y (,相关的数据通常存储在B S r+ { a F S ~ +一个文档中,7 @ I V Q而不是分L | X w N %散在多个表中。

myJ 8 qsql 是一个关系^ $ $ n @ S B \型数据Y 5 C vQ q # g o g H N =库管理系统,w R K v它使用表、行) H x :^ v G 9 G v ] K W 1和列的结构来组织数据。数据通过9 l # z Z w |外键关系分散在多个表中。F 2 L o | q i

查询* E o n语言
Elastin ) ^ E `c$ ` A hm [ _ | B k Y wsR z W C # N \ \earch 使用 Query DSL(DomG 1 9 R 9 0ain Spm $ \ecifu ; ._ i 2 }J T ^ % 2 G 2 N v } ? +Y T O O [ ) 3 Qic Lan6 R 0guaged @ 8 ^ %,这是一种非常灵活的查询语言,基于 JS\ x m C M rON@ – r,支持全文) R Y % $ I i4 z R ` O 6 k n `搜索、复合查询、过0 QL h f { u ; x s\ R Q / @ o ]滤以及聚合等。

MySQ! l c / Q CL 使用 SQ\ ` F 4 n oL(StruO / + R Jct\ ~ \s tA ^ l 3 { 5 / i m =S ] O x 3 2ureA D / V R ; fd Query Lq / z o n qanguap m i rge),这6 L ! E是一种强类型和非常成熟的语言,专$ z L ;门用于查询和管S Y ` B 0 4 U0 H Q理关系数据库。

全文搜索
Elast3 . _ 9 [ ( =icsearch 的核心功能是v q g [ Y Q r T全文搜索。
3 ; n 5 z * { T ew y T对数据进行索引g L ; – O N时会自动建立全文搜索索引,使其在搜K h 4 ^ } ? . t V索大量0 z U u F P C \文本* , / E w Y y数据时表+ i k Q u 0现优异q + A e E 4 H

MySQq – ! u S e 6 1 tL8 X @ O [ o 虽然也提供了基本的全文搜索功\ p j . ) U能,但其主f u 0 3 . %要设计目标是处理结构化数据的h Y 1 u存储和查Z } x ]B \ e,对全文搜索的支持不如 ElasticsO 8 b I ! 0ea# ( r1 k Z | ! 3 H I 3 yrch 那样强大A g ig h 5

事务支持
ElastiR S ^ P / t 9. / U J q 5 ycse~ z _arch 不支持P 4 J传统的 ACr S s =ID(原子n ( \ :f % ] V\ I m p % U 4 g ] h、一致性、隔离性、持久性)C l # J ^ I ; k事务。虽然它确保了单个文档操作的原子~ N v F % f j 2I ^ 3 2 I .,但不适用于v T g L , q跨多个文档的复杂事v | W 4 {务。虽然 Elas: 5 7 8 S [ rticsearch1 t 1 N T 1] h J S v G z支持传统的W ` 7 Z x # Z *事务,但是他U M Jd A , e I [ Z K { v e ZA l x | . f q u {% ( 5 4 ` ? \ g以确7 : f P ) q _ jV xq # + h I .保单个: M 3 1 =文档的更改(如创建、更新、删除K _ d p G ) %v 0 ; JE R = l y% H % – \ # K H是原子性的。这意味着任何文档级的操作都完T V # \ D |整地成功或n . R B完整地失败,o L ^ a c Z * f但不保证跨多个文档\ K P \ N或操作的一致性。

M2 } i@ + | = { ; 2ySQL 支持Q M Z $ ] 9 C ACID 事务,这使得它非常适合需4 e I要严格M G z { ` +数据一致性% A H的应用,如金融服务和其他} : y \ o商业数据处理。

支持乐观_ N Q i H ) w %\ ` : +锁:\ . o ^ ( x Y – ^

E4 z Lla^ q /W E ? \ J : h b 8sticsearch 支持通过使用文档版本控_ a X / 6 ~ ; h制来实现乐观锁。

6.7p | \ f之前。在 ES 中,每个文档n Ne I 1 B \ T U存储时% 9 $ 7 $都有一个 _ver, \ ? c 6st ] _ , ? 1ion 字段,这r D J i3 y P个版本号% Q L U h在每次文档t { V 9 –z { y j , Y `更新时9 j Z自动增加。当我们执行g U A K+ l e e ! M ? _ \ \更新、删除或者使n f h用脚本处理文] rx l O ^ K档时,可以指定这个版本号来确保u ? ; j n )正在操作的文档是预期中的版本。& z E k a . A m r如果操作中的版本号与存& T = D o X 4 AZ T o 2 = x n 6储在索~ w b u (引中的文档版本号不0 p a x * #一致,说明文f 9 ] W ,档已被其他操作更改( . U N p m,当前操作将8 7 K \ J . [ \会失败。(CAS)

为什么_versiI : _ 6 U + [ von在后续版本被抛弃

_version 机r _ i * C制是基于单一递增整数[ O s 3 A Z H,它主要适用于简单的冲突检测,但在复杂的分布式系统中3 @ R,仅依靠版本号可能无法准确地} l h 1 3反映数据的% & $ q历史和R ( & (复制状态。} . f – 2 @ | ?尤其是在发生网络分区或节点故障时,0 0 – E 0 M =仅凭 _L WH w 0 t = Z E / I U } ^ _versi + R ` ~io0 T 9 un 可能导致数据丢c v f ~ P r – M, B l y B k =失或过C O p 2 r z时的数据被错误o H B Z3 b ` X l v ;写入。

主要还^ ~ H g 6 @ 8 x X高并发t O r i y) c ~ ^ I \ 0 E #和高可用{ # :o I , | l !环境下,单一的-veg 3 C 2rsion不足以处理因节点故$ ? t 5 \g : { n U [ S X C ; wC \ d络问题导致的多个副U / 2 ] r | T { a本之间的u Uo | U ~ ( + = @ ^数据不一y – u )致问题。

然而if_seqn/ 7 @ b W | 3_no 和 ifC g f 3 | 4 6 X .– z : M Y w \_pW U { e W B d 8rim(. p Z S R V g p & Ga) n \t F 4 r B $ ( Nry_term这两个参数可以? nz L ? \ a C W R ( H p L H u ~更准确RC 3 ] h ~ $ ^ 6Q H : : 5 P l Gfxn0 q g, p : x Q : y l B N 8 ? p SzYwmx地确定– 6 V _ / 2 7操作是否应当被执行,可以D 5 _ 9 zO \ e o _ C & d跟踪5 h F R w + c 5每个文档H ` 7 X A变更的y e b % y @ O –序列号主分u C T K ~ q W片的n 1 $ p 8 f f E期限。这种机制帮助确保| S t ` _ Q p n 0即使在集群状态发生变化(f Gc 7 a Y : J \ j R S如分片重X W m 3 ( ? e新分配到新的节点)的情况下,A 1 % d也不会应用基于过时副本的更新t – @ ) # 0 R { ,。它有效地防止了脑裂. m m i | c 5 P问题

6o ? V ~.7之后,使用 _versio7C E 5 S @ 9 e jn 关键; t V | { &1 O ) 2 p字进行乐观锁已经被废弃U [ q | P U N m{ ` q 4 # $ Q了,替代方法l; S 4 \ ? s – G A d c是使用

if_seq_no (2 ? 1 \ E ] Z 9e u i } . K \ 9 a是一个I 5 .递增的F \ ~ : j l 5序列号,表示文档的每次b 0 x l , n 5修改)和M h N [ = / t L

if_primary_term(表示主分片q t F & q k的当# ] – e 9 x t @ ]前任期,每当主[ v 6 ; 4D t ( B 1片发生变化时z H T j o ! s,这个值会增加。

来指定版本。

1. 核心优W & /势()

维度 Elasticsearch MySQL
数据模型 文档型(? x [ ! L LJSON),动态映射 关系型(严格Schema): X 8 c 1 X 6
搜索能力 全文检索A { &9 , o` D = R 2 3 ) + o 6} A v / { \ } u 6 ` W ^ } F7 : f i O匹配、语义分析 仅支持& A D ) c = \ – K精确查询和简单LIKE
~ { X w O \ 0 c :展性 分布式架构,自动分片@ x ~ _ M/副本 分库分n P x 6 J` H A复杂
吞吐量 单集n J 3 ~ u o zs y ; , , \ N群支持每秒1\ 8 F , @ U (k E G 4 N :0万+查询 高并发写入更优
一致性 最终F c J i $ / k 6一致性(近I v X w 9 0 q实时Q , s 6 P u Q 强一致性(ACID1 _ h m & d u E b

Elasticsearch是一个开源的分布式搜索和分析引擎] `L L k q R – : { p ] _! X + F Om + h 9 ( f # %主要适用于以下场景? 2 L : V [

1:搜索引擎:用于快速检索文档、商品C t ) U k M、新闻等。

2:日P W ; e Z Q ; p志分析:通过分析日志数据,帮助企业了解其1 V | l业务的性能情况。

3:数据分析:帮助数[ T [ g I = ^ r y, v K k m , 2 / k科学家和数据分析师进行f 4 [ [ n I T 2数据分析,以/ ` _ G b a ^获取有价O ! 4 K ? \ l Q M值的信息。

4E R # H H h c:商业智能:帮助i , 6 / s e B企业T 6 p ] g J y制定% \ M . @ J数据驱动的决| k & PB r \策,以实现商业上的Y 4 * _ N a成功。

5:实时监控:3 f0 q \ {2 cP _ ` A K (助企业实B 0 g C I时监测系统性能、监控F 4 W J % b数据变化,以保证系统正常K d 6 8 T tI = \ U D 0运行。

6:安& F ) j 7 q K : m全性:帮助A % ? X ( l ] 6 Hn + \ ( w A V u |业保证数据的安全性,保证数据不被非法/ @ T _窃取D } q g

7:应用程B r 4 E 3 A序开发:帮助开发人员开? * G U r j q * W发基于搜索的应用程序,以B ~e a L _ | Z FA Z S f MpythonF F z q aG H z c a r增加用户体a y d 1 f A验。

Elasticsej E Ha9 F zrch具有以下几( V e ] 5 :个优势:

1:高性能:Elasticsearch$ ) VE r * G j l p d j具有高性能的搜索和分% W a k ` f +析能力,g t k J v f I n @其中涵盖h = nw h u u # 0 b Q o = 8 m了多种查询语言和数据结构E D T ! k E

2:可扩展, 0 A jm j n RElast4 m $ 4icsearch是分布式的I _% g G P a F ,,可以通过增加节点数量扩展搜索和分析能[ = 7 ; Z 2力。

3:l K \ $灵活性:Elasticj g v F , E \search支持多种a G :} : – S数据类型,支持多种语言,? i f K 1 3 % c i支持动态映射q 6 G ^j f T允许快2 – t 6 b速地调整模型以适应不同的j } K i m需求。a ? o \

4:实时分析:Elastic: : iseg f s 4 xarch支持r % P 8u . t l实时分析,可以对数据进行z N p r实时查b d x u M 6 4 g询,这对于快速检索数据非常[ $ W @ * 8有用。

5:可靠: [ py 4 \ F k L * ^ d:Elast^ U r m^ g [ H | S b /icseV T + + . P V Yarcs } 5 h P 5h具有可靠性_ U [ K和高可用性,支持数据Q 8 v 4 f备份和恢复R \ T r i e 4 \ Q\ j [ ] v A ] 4 |

ES为什么块:

1:分布式^ ^ \ o u \\ J f H Z ^ R { @存储:Ela$ [ Usticsearch使e u { ^用分布式存储技术,将数据存储在多个节点上,从e ! M ; {而减少单个节w p n ` c点的压力,提高整体性能。

2:索引分片:Eld 1 C ] 0 Z Y IasR a + eti7 K d u a X \csea+ \ mrch把^ k z每个x ~ 7索引划分成] I m 0 B w !_ S d } y 8 =个分片,这样可以让查询操作并行化,从` H I ? x A 5 ~而提高查询速度。

3:@ w q T s . 9. C _ { S ? /文索引% H M g 9 l ) N:Elastics0 E wearch使用了高效的全文索引技* l 8 v \ (术,把文档转化成可搜索的结构化数据,使得c ) s 5 ~ Eg w \ i . = z 5索操作快速高效。

4:倒排索引:ED U Jlasj Ds M m ~ B _ P u . g Yticsearch支持倒排k P : E e T 4索引这K ( v I = LL\ ` i G D 8 v 9 @ I I {数据结构,倒排索引将v I # g .文档中的每个词与该词出现在哪些文档中进行/ n ) 0 | Q * * V映射,并\ E – s U / q |存储这些信息。当搜索d : b请求Y b U ^ X发生时,ES9 & 5 ~ j h Q 9可以快速查找包含所有搜索词的W W O # – \文档,从Mn G i U n _ Q H O P而返回结果。: 9 + –8 y e 3 S n +

5:索引优化:E, G ~ D 3 # $las= _ t 9 g ) ^tics3 { ! _ Dearch通过索引优化技术Q z M d ~,可以使查询速zP 5 & T 7度更快。I 0 –例如,它支u 6 # s # R持索引U 4 l覆盖、索引下推等优化技术i ? l ? 4 1,使得查询速度更. R % =快。

6:+ \ 1 X b预存储结果:ElastX # I NicX 0 j \ y Y |search在J g ? b w qF ; & m r . j R入数K q} ~ \ k f B u 8据时,对数据进行预处理,K O [ n $把结果预存储到索引中,从L – z而在查z z X : 8 Y x z~ $ z |时不需要再重新计算,提高a F o ( B E W l查询速N }{ P p K v S X m f j |度。.U V r # h } 1 s n 0 .v s g ( V O m

7:高效的查询引擎:Elasticsearch使用了x 9 v X ` G高效的查询引擎,支持各种{ k ` y Z |类型Y & 7 K i ! [的查询,并对复杂查询提供了优化策略,从而提高H W k , * * !查询速度。

8w 0 B % M H:异步\ ? v \ !请求处f O a $ 9 h # | c:ES使用了异步请O m S Q T b X *求处理7 Q z A P X {机制,能够在请求到达时立即返回,避免长时间的等待,提高用户体验。

9:内存存储h j x z W #; I LESK c N 7 Z Y n使用了内r S i – T 1 /存存e X m f C %储技术,能够在读写数据时大大\ X g ! 5 * \减少{ [ /) h t s n f ! u磁盘访问次数,提高数据存储和f I J 2 Q (查询效率。

我觉得l v 4 V q $ s . \最重要就是倒排索引了:它用于快速搜* * p @ # $索文档s Z { – [ R中的某个词汇。. N s

假设我们有一Z b \ X o \ H个原始文档:

文档ID 文档内容| ( o
Doc1 &quoC Z z pt;R@ Y . y ) 0 v c ) B Zi \ 4 3 3 & k `ElasE o I OV i 1 $ Y @ticsearg _ G T 9 j _ch in ! /s fasto P G g # )"R a _ }
Doc2 &qu` x y 3 M p lot;Red2 z – o x 6 ] Eis is fast too&quoA F kt;
Doc3z + 4

&quot& | W;Ez U d (\ W : 7 / F + f c _lastiF l F b scseM u _ 4 P g p Darch ak j , d b ~ 7nd RediC Y\ K u z @ r x ( \ is"

主要分为俩个过程:E V F Q p L b . Q

分词(Toket S U ` ] ` I 0 xM ) l – [ EnizationK t \ D N o @

  • Doc6 k r l c1 &y p S & ! W @rarr; ["elasticsearch", "is", "fast"]

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

  • Doc3 &rarrm [ v ! R Y `; ["elasticsearch", "and", "redis"]

生成= – 9 q词项-文档映射

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

2. 倒排索v ~ m {引的核心h E S / # / D )组件

组件 作用 示例
词项字典* Y k L # G E V t(Term DictionaryR * . / 9 0 p pq ! Z! g : ; ^ 9 & n \ a v 存储s hx # P 5 K 6 d所有唯一词项,通常用FSB * F P R h ; tT(有j . = I A h限状态转换器)压缩存储 "elaW & o fsticseo 7 p o f 5 ; narch&quoz 0 a Z k ; Qt;, "redis"
倒排列表(PG u i R + S . A tosting, 7 J A \ Cs List) 记录包含该% 0 r K 8词项的文档ID及位置信息(E __ l L { | ~支持快速跳表Sk# g F ) O p G B \{ / R 8 t ^ 6 &iP? Z M D W l d NpL7 | 9 Z @ist优化遍历q o ) C + lY 9 k L 1 L ( B Doc1:[pos1,pos2], DT k y J 0 l soc3:[pos1]
词频(TF) 词项在qG X ( + t o ] a 3 E f 4文档中的U g / b 4 ) : g :k 0 J出现次数R 1 5 R d r ](用, ( 4 R ^于相关性评分k 7 z b 6 \ W H "fast"在Do% w 8 v B 3 ; B yc1中TF=9 k 9 x L y G z |1
文档频= * K率(DP v a | XF) 包含该o – :词项的文档数(用于IDF计算) &qr ~ _uot;elasti

倒排索引的优化技术

  1. 压缩存储

    • FST:压缩词项字典,减T { i * R少内存占用。

    • DeZ L K D ) 7 i xlta– * + Encoding:对文档IDe L E , 0 Z s W差值编码(如[100, 102, 105]&raO 1 a H B wrr;[100, +2, +3])。

  2. 跳表(SkipW ; Q m Y ] @ &List)

    • 加速倒排列表的合{ v ^ A W并操作O u z $s ] r h G(如AND查询)。

  3. 多级索引i ? { s ~ 6 J ]

    • 内存( ` _ M U中保) ( | 3 Q 1 $ R 3留热6 Z 4 * * G 9 w{ O ^ e { e 7# X B 0 l O 0 6词项,磁盘存全量数据。

二、Elasta _ lics+ 6 a m C & 4 6earch 核心技术细节

1. 分词器(v y w N p m 7 : 7Analyzer9 J x 7 ]

分词器类型 * 3 I能说明 示例
StD D A _ # h w % .andarG 6 *d 8 p 6 } s认分词器,按空格/标点切t % S A # U &/ o & rquot;Elastictq t 3 6 S js_ { pearc= d z z – s # hh+ ; /"` ] J * @ 7 → ["elasticsearch"]
IKH u N I W J Analyzer 中文– w^ q g 0 \ H T K x D分词(社区版+扩展词Q ( I典)

Is I 2 * +K分T i h l 8 J C 4词器有几种模式?

  • ik_sma) A # j ? 2 }rtd ] N h S z F:智能切分,粗粒度
  • ik_max_wor5 N Od:最细切k \ ~ v & g ) Y s分,细粒@ R iD o 1 y ) }

IK分词器如何拓展词Y u ? ?条?如何停用词条?

  • 利用config目8 . N ; Tw V ^ L录的| f s _ J * eIk; _ !Analyzer.cfg.XML文件添加拓展词典和停用词典+ X O ^ y – {
  • 9 B j # N q词典中添加拓展词条或者停用词条4 R 0 ^ _ g
&qu} + , – T f l 5 dot;华为手机&quott m @ D u 1 $ A L; →J } v ; i d T q ["华为", "手机"]
Pinyin 中文转拼音0 l b ) ] M Z x搜索 &quoy h Z e ct` S _ @ u q l;北京; , J B Q f 8 4&q^ b s F r $ R F $uot;w X S &: q a ; 2 e O F Mrarr; ["beijing", "bj"]
WhitespaZ p H m D r ) `ce 仅按空格切分 "hello work O j e K w * Pld&qd ] n quot; &raZ & I K 2 ~ 3 D wrr; ["hello", "world"]
Keyword 不分词= & k j v X,整体* ( 9 \2 c \ w作为TermJO = Y f o 9 \ CK W V : 8 2 Z t + "202{ 3 } ,3-08-8 P F15&o , W [W b ; X 7 kquot9 * 9; &re E T a T –arr; ["2023-08-15"]

自定义分词器

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

2. 底层原理

  • 倒排索/ C ! | : 7 2 j引(H O i ` + , 4 ,Inverted\ C % ~ ~ / e c l Id l t X +ndQ ) F – E } R Zex)9 b S s W

    • Term &s g mrarr; Doq l : l gcument Ih } d ; ? Q o e hD的映射(& ) x f . k如&ld] N J C b qquo;手机&rdquo6 O C ! 6 S }; &rarX k !r; [Doc1, Doc3]); m j

    • 通过* C h zFST(8 ~ H q b S ^ \ {Finite Statn 9 l Qe Tr] = Ke 9 n W 4 C 2 B z L ( Sans[ N # l p wducer)压缩存储,减h I ` r v 4少内存占用。

  • 分片(g 9 $ & h _Shard)机制

    • i v B o Q k _引自动拆分为多个分片# ; *Q L 7 d W 3 H \(默认5个),分散O R 2到不同节点。

    • 每个分片有1个主副本U + Q 4 ) 6 I和N个从副本(通过_settingsj \ y 3 v U调整)。

  • 近实时(NRT: 2 k . 9 , r c R

    • : ) w : g据写入后默认( F1 M 8 b e 6 / N1秒(r_ = f 5 o : ) U lem s Mf@ ) $resh_intervaDb ; . I | Z F @ . Al)可被搜[ } , 1 `索,通过tran? M @ P Z ` B F vslog保证持久化。

3.J # ? [ s b 8 1 # 查询高效的原l p 7E m w

  • 分布式计F x a

    • 查询并行发送5 Q # N到所有分片,结果聚合(ScatX g 3 ster-Gather` x E h j 5 y模式)。

  • 缓存优化

    • Query Cache:缓P 2 m0 ~ = $ 0 @ (存过滤条件结果。S t y x

    • Fi5 V\ S y R A , f P ; 0 Y fep E w / F g# pV l X 7 v b V n E ek k S O B h , n 1 k B zlddN G e ;ata:文本字段~ ( y S % n A i启用内存缓存(慎q w 7 9 S C s F 1用,易OOM)。

  • 列式P E I h * c? \ ] f K q储(D, h $ \ S 8 #oc!U n 7 = R 3 [ n f 4 – Values)

    • 对排序、聚合P o y u字段预先+ _ / j O J c构建磁盘数据结构,避免实时计算。

4. 增删改操作

  • 写入流程

    1. 请求发8 ] n o F [ M d送到协调节] ? z – % $ A i点。

    2. q g d x 5 A由到# J X对应分片的主副本。

    3. 写入Lucene内存BufV F z d C E _ U [fer和translo1 , = 9 _ 1 H jgR r ?

    4. 定期g W C s I / `刷新(Refresh)生成新SegmeQ ! |Y ( !nt(可E b F M . 9 r搜索)。

    5. ^ \ 7 O (C G U b台合并(Merge)SegmenF v AZ M C z zt优化存储。

  • 删除

    • [ 8 H M Y , fs; & Z u % ! J Ub \ 6 6 \ i = ? @ w: z = o 1 L Q $记文档为deleted,MeQ 0 L 2 C g Arge时物理删} v !除。

  • 更新y z L @ : A _

    • 先删除旧文档,再写入新文档`_ / 4 { V ( Lc C j Y X ; P –(版本号* ! M a l_version递增)。

三、关键问t _ ! S G e \ Y F题解决方案v \ n ` ~ : J

1. 深度分页优化

  • 问题from 10000, sizeY h - a \ ( 5 O 10需遍历所有分片的10010条pe T r s R l K记录。在d Z , l F kElasticsearch中进行{ 8 a Q分页查询通常使用from和size参数。当我们对Q q h F b g T \EaO 3 M P d P 2 _ ElastL \ 2 % E ?icso ~ 5 N c y t V `earch发起一个带有分页参H ~ ( [ N u { p数的查询(如使用fro@ * S L pm和size参[ X k E `数)时,ES需要遍历所有匹配的` W v t e |o b 2文档直到达s 3 W ) 3 v Q &到指定的O K ? _ U q 6起始& J (点(fromvw 8 z % , s z . w g3 m 6 m ) + 1 ) o | & c 8),K e F然后返回从这一点开始0 R \ E f * D m的size个文档。跟M$ X [ ) c J EySQ8 t ? g # % 5 E e} ^ E xL的M * N深度分页原因差不多,

  • 方案

    • Ses – w +arch After:sek s g { ( J 6 : 4arch_aa 7 d k T + ~ v `fter 是 E: Q Y T x I , Llasticsearch 中; R } D t用于实现深Z B @ ? p度分页的一种机制。与传统的分页\ G X C b Q h )方法(使用 fr. C $ 5 3 7 K e eom? S 9 s v Z ~ R 和 size 参数0 _ _ R)不同,search_aftK k $7 _ F 3 Ae^ . – p ] – Wr 允许你基于上一z 0 . o , ; ` ~ F次查| $ Y n ^ T W a询的结js[ } 5 ^ v e r来获取下一批数据,这在` p b y k I处理大量数据时特别有效。

      在第一次查询时M 7 ^ P ~ h y 8 F,你需要b D l s定义一个排序规则。不需要指定 sear{ p 7ch_y P 6 1 t ; _after 参数:

      {
      "query": { "match_all": {} },
      "size": 10,
      "sort": [{"_id": "asc"}],//在第一次查询时,你需要定义一个排序规则。
      "search_after": [last_id]
      //第一次查询不要定义,在后续的查询中,使用上一次查询结果中最后一条记录的排序值
      //search_after包含timestamp和last_id 的值,对应上一次查询结果的最后一条记录。
      }

      searc\, w q N L x C _h_aft\ l 4 y Qer 可以有n , u H 5 * @效解决深度m 1 d l c ; [分页问题Y D Q \n I _ r M y . 9 ` GZ e t 4 d c W,原因~ O 1 { ] V如下:
      避免重复处g x = & a { r O C理数据:? 8 6 2 Q [与传统的分页方式不同– ] z Kr i ! _ Y g E Ssearch_after 不需要o \ a @ m } o T w处理每个分页请求中/ 8 K ~ ] E b M所有先前页面上的数据。这8 9 / k大大减少了处9 # x理数X t # C Z O ( nN& p ) z i F h 2 5的工作量。

      U T X ^ B ? : x h高查询效率7 ( g c 2z q i G l j V O于不需要重复计算和跳过大量先前页面上的数据,search_aft! m a . @ 1 O @er 方法能显著提高查询? 0 X c S / ! A效率,尤其是在访问数据g V – O Y X &集靠后v = )q u (O F 9 p A ) k Y 4分的数据时。

      但是这个方案有一些局限,一方面需要有一个全局唯一的字段用来排序s y B g y _ 58 f t n _ M u , ;,另外虽然一次分页查询时不需要处理先{ E O k !前页面中的数据,但实际需要依赖上一个_ I ^ h Z $页面中的查询结果. k Y k ! .

    • f r I用于深度分页和大数据集的遍历+ E y f = + =l 34 P ] e / + + +I ) 5 P (

    • ScrB Q R g % @ = Boll API:Scroll API在~ 9 q K g T yElasticsearch中的主要目的是为了能够遍历大量的数U ^ F _ h = J Y h据,它通常用于v * o 0数据导出或者进~ i 6 C行大规模的数据Q & , k分析。可以f % i =\ F g T 2 ? J } 7 i . 2 L Gm ( j \ / D 1 ! ^– F O , w Y于处理大量数据的深度分页问题。

  • POST /_search/scroll { "scroll": "1m", "scroll_id": "DXF1ZXJ5QW..." }
    //如上方式初始化一个带有scroll参数的搜索请求。这个请求返回一个scroll ID,用于后续的滚动。Scroll参数指定了scroll的有效期,例如1m表示一分钟。
    //接下来就可以使用返回的scroll ID来获取下一批数据。每次请求也会更新scroll ID的有效期。
    • 业务妥协:限制最大页码m @ } v(如只展示前` N W a $ : P w100页)。

    • 6 cG A : s | { n h ` 1 u K k | W免重复排序:在传统的4 ] 5 Y z &分页方式中,每次分页请求t _ z g I g z都需O \ j N u J 1 R要对所有匹配的数据进行排序; : u 8 P J 1 b `,以确e ? @ U W定分页的起点。Scroll避免V 4 f m r &了这种重复r 0 g排序,因为它保持了一个0 ! M h i游标。

    • H T U r q| y M o \ q iJ @ % a h . C v A视图, 7 @% p V v 7 ] oScrO 9 f ) { L { & uoll提供了对s v m A N数据! 2 P e的&ldq: [ ^ s K @uo;稳定视图”# d F p } 6 x @ ]当你开始一个sl } N CW – T 2 Y _ 9 mcroll时z \ j g C { 6,Elasticsearch会保k * R ` X g 2持搜索时刻~ Y v 3 w y k =的数据快照,这E – d ) + ;意味着即使数据随后被修改,返回的结果仍然是一6 p { n o i K致的。

    • 减少z v R #资源消耗:
      由于不需要重复排序,Sc4 B B v | ;z ; 2 F N 3 yrollp $ ; T s 6 ~ : N少了对CPU和内存的消耗,特别是对于大数据集。

    • Scroll非常适合于处理需要访问E 7 P大量数据但J k ? H a n U不需要快速响应的场景,如数据o w 4 o 9 z f k y导出、备份或大规模数据分析。

      但是,需要知道,使用ScrolN I ^ { @ ( pl API进行分页并不高效,因为你需要先j ^ k l u EA v * W 7 G U gb W $ m = ; G O y取所有前面页的数据。Scroll API主z o P 8 ! ^ u要用于遍历整M M O个索引或大量数据,而不是用于a R v S @ )快速访问\ L y R 7 k z V特定页P A 8 Q数的数据。

2.^ \ c . 7 G i , 数据一致性

第一种v @ O方法:双写一致性& ! i ] 1 X

对MySQL} \ v = F ]和Ex $ ( 6 Q o r f 2S进行双写,先: V ]更新数据库,再更& L 2 R y新ES,放在一个事务里面,需要保证事务e C w 4 \ 8 4{ H o的一致性。有数据不一致的风险,比如MySQL写入成功,但是Ei g ! U e { + 2 hS发生了写入成功但因为5 , \超时抛异常了就J \ 5 K L X N BW { R | d会出3 z G l a 8 # ^d h e & Y现数据不v $ ? G tn $ + # = 6 u X A Hx R c一致的情况。

第二p M : . N J I种方法:y l d * U D$ L [ | 4 W u & 5使用消息= ; e \ ^ j 8 $ t队列MQ进行处理R Gk J [ g d @ W \ y

在更新数据库时,发送一个U 6 5 j消息到MQx ) * T B e D中,然后数% ? \ } 0 /据库和ES各设置一个监听者,监听消息之后各自去做v G t数据变g F [ 1 V S s更,~ iw = T B w C r , h \ c !如果失败了c j _ Y Q 7 B T就基于消息的重n f h – m s z s g! } Q .在重新执行。

好处是$ T –o 7 ` 5 D 4 o 1LD 4 V C l 3 ( [ s l行了异步解耦,性能8 k a . e y + L稍后,但是有延迟

第三种方法:定时E _ G | 2 3| % m r p& k @ T : S! [ Y m 5扫描MySQL

如果ES中的数据变更的实时性要求不高,可以考} F 2 \androj | ` 2 pidD ? E I % O \ &定时N Q v $任务扫表? i [ – ?来批量i x p更新ES。

这个方案优e ~ 0 T b k点是没有侵4^ j 8 H j m 1 V @ – f – qP t m O { $入性,c * $ X数据库的写操作处不需要改0 L $ k S ;代码。

缺点是实时性很差,并且f S q b v X f % –轮询可能存在z I( _ O W 3 B –性能问题q M K d\ { L k \ B \ ] wX [ &效率问题以及给数[ B R ! u @ L ? *据库G / \ ! d k Yb 8 p t B O m带来压力。

第四种方C u H S法:监听binlog日志(基于canal做数据同步的/ = U N方案)

, ! U a业务代H l E V码完9 CF 5 | { r R X全没有侵入性,业务也非E ( {常解耦,不需x / N 9d *C P # I 4 N # E要关心这个ES的; + / 5 A_ d b T } p更新操] = ; $ / E | s作。

缺点就s L s y f是需要基J w a f 6 : p *于binlog监听f z 4 Q,需要Z $ n /引入第三, s ! # $ P o m S方框– ; 1 G b C ;架。存在一定的l b o K I n `延迟。l : 7 ` G

一致性级别 实现方s 6 m + d B ( ^d I ? R #\ F D \ ^ – d 1 M Y缺点
强一致性 写入后立I b % + . 4 d 9 KrefK O rreshR I + g A i7 – I性能差) 数据\ c S \ [ : q F最新,吞吐量下降C ) 0 (
最终一致性 默认1秒刷^ K 0 & X x新 + 手动_refreT - y ! l 8 & =sh(平衡选择) 性能高,短| c Z $ % d a暂延迟r I a B y +

与Canal集成:主要的过程

  1. MQ 4 M x x w _ v fySQK \ K d }L Binlog&O 1 : l !rarr;Ca& l z m LI 5 ( { a [ Bnal ServY ) U % = ( oer解析变更。

  2. Canal ClientKafka发送变更事件。1 v – M / M ; LX ( k h * b

  3. LogstashH o c – ;/自定义CoP V \ [ a n Cns) T $ 2 #umer写入ES~ j mg t G S V S D 8 x, t e # F

关于Logst8 A $ = ? {ash和自定义ConsumeS 9 V 5 J W D ir

. L[ ) S | c 4ogstashy 8 + $ e 是什_ X } % D么?

  • 定位:开源的数据处理管道vu 2 Z | S N [ D H工具,x` A H % S~ ~ m W | R x n( b + q于 ElaJ + 4 q – v } e ystil x ) = ?c_ C S @ F t S4 p y |tack(ELK)的一/ / Y部分。

  • 核心k ! F ) [ 2 M m功能

    • Y $ 5H f V U c } V $ Q A6 l W n J 9v 1 H h * b据输入* Y S RInput):从 Kal * 4 O { 7 bfka、MySd ` ! ] W sr 9 nC J A _ A FQL、文件等y u O * y d K T aJ 2 y V s 0取数5 E ? k I r Vw q ~ a [ u A V据。

    • 数据过滤(Filter):清洗、转换、丰富数据(s Z R U K 2 C如字段重( u Q命名、类型转换)v V k S

    • 数据输出(OutpuP ~ { v r e . y xt):将处` t F \ ] A理后的数据g \ 6 # c T ` % /写入 ES、Myr : 8 % n z h xSQL、文件等。

  • 特点

    • 配置驱动:通过配置文件定义数据处理流程,~ ` [ 9 + x无需编– ; g . H码。

    • 插件: v E:支持\ # C a $ m \ } 2 200+ 官方, S t U w }/社区插件(如kU S %i d N } eafkaelast + f n U \ U Ytics1 @B H A 7 2 [ \ . \ ~ Xearchgrd 9 ?okP F Tq Q X @ W

Canal → ES 场景中的R ] , ? # 5 F z ,用途

将 Canal 发送到s ^ i j Kafka 的 My1 Q ,SQL BinC \ * %loQ Y H H s h L cg 数据转换为 ES 所需X ! d / . V c A p的格式,http://www.cp* C n u w ] rpc& J Q % _ns.c, q @ I n M & a !om并写入 ES^^ n d W 2 S F =4 v x 7 , f ) s t R i 4

r } M \ 3 e T j X定义 Consumer 是什么2 @ V I Y 4 ! f x

  • 定位:用户自行编写的程序(L 3W i P E q 6 R \ + up p ! U b W 6 Q j常用6 \ 8 ] m [ ? X Java/python/Go),用于消费 Kafka 消息并) @ ] + o W处理。

  • 核心功能

    • 从 Kafka 拉取 CanP V $al 生成的& ^ = S N n U Binlo? 8 [ C n x f 7 #g 消息。

    • 解析u – p 9 7 5 + 7消息并转& $ . K , # Y换为f T 4 6 6 ; a 2 ; ES 支持的格: b V = q式(如k a C \ 1 JS} n i jON)。

    • } 4 C 9 5 O n 4用 ES 的 API 写入数据。

  • 特点

    • o \ b m @ g @活可控Q k ! { n # & – \:可自定义业* B T务逻辑(如特殊字段处理、错误重试)O f ` M x

    • 高性能:通过批s 9 ; I 3 N g量写入、异步请求等优化吞吐量。

整体架构流程:

一文详解为什么用ElasticSearch以及和传统数据库MySQL有什么区别

3. ES支% I K [ _ V a g持的? 3 L b数据结构

  • 核心类型$ | m w & } I 4

    • Te/ 7 4 LxtO p B / J用于存储全文文本数据W r C 3

    • Keyw^ C J / 3 yord:用于存储文本值,通常用于索引W K D –p r – m !结构化内M S B g @ c c E0 ` p Y容,如邮件地址、标0 ~ j Jr T 6 # Z签或任何需要精确匹C 3 6 h @ q 1 l r配的内容。

    • Ne0 } xsted:类似于J L O e $ K D ; Obj@ L @ S ~ n u fect 类型,P l n l v但用于存储数组列表4 I A E z H a – X,其中列表中的每个元素都是完全独立且d K C ? ! |可搜索的。

    • Long, Integer, S3 r ,] J L r 6 4 /hort, Bw ( K z \ , |C i @ j 5 E K dyte, Double, Float: 这些是数值类型,d P L 1 G i P D: E 6 I 4于存储各种形式的数字。

    • Date: 存储日期或日期和时间。

    • Booleans U ; 7 7 a @ k E: 存储 true 或 fj u 7 `al: X ] a X ^ t #se 值。9 k 8 f ? 4 9

    • BinT , & y _U E + { M R 8 ( eary] ~ ] o s ^ |: 用于存储3 ~ U ~ t 9 i 9 o二进制数据。

    • Object: 用于嵌套文档A z o uI 1 P J e b T j ? ),即文档内部可以包含文档。

  • ] u / u 2 _ /殊类型

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

    • JoiF N E _n:父子文档$ b N ( b 1(性能较差,慎用! o m8 K X [ e ^ k U E j ~ _)。

  • text 和 keyword 有啥区别?7 1 8 =

    tE f Q m Q 1 Bext 类型{ o N 3 6 t被设计用于全文搜) H j / P g ` @ ,索。这意味着. B 4 7 mQ ? r P 7 } ~ h 0当文本被存储为 text 类型时,ElastY S ( R / | Fi# S }cseas * LrG s `ch 会对其进行分词,C OR 6 + e E He H 1 p {把文本分解成单独u ? P { : b的词或短语,便于搜Q ! Z 0 u A索引擎进行全文搜索。因为 tee Z Vxt 字段{ ar f [ r a W j G经过分词! } y,它不适合\ , )用于排序或聚合查询。

    texth g m c x b ` – G适用于存储需要进行全文搜索的内容,比如新闻文L f o章、` ^ + I ~ Y –产品描述等。

    keM L [ A V v 5 2 Myw7 ? O = rordw t 6 q Z 类型用于精确值匹配,不& J K S &进行分词处理。这意味着7 K u存储在 keyword 字段的文本会f D v u : = J被当作一个完整不可分割的o 5 – y z +单元进行b n u O 5 u处理] c ! ` w wy ( { /因为 keyw& d K cord 类型字段是作为整0 \ W j 7 L ! A 0a 9C ! ? 2} | ^ ( X # C A存储,它们非常适合用于聚合(如G l m D @ = |计数、@ B % 5 \ \ , ( w求和、过滤唯一值等)和排序操L D tr U . k l $ A V F mR A + 1 f . – T 1 –Z 9 L A ) M |作。由于不进行分词,z L ! c )keyword 类型字段不支持全文搜B C !% s } / x (索,但可以进行精确匹配查= = q { T | b t询。xv B Z s = ~ 9 G R ~x C ) 7 n / j M U

    keyword适用于P e B需要进行= }g P h G T J 6 u 8 S \ _ J b }精确搜索B ` z 9 Z H Y的场景,比如标签、ID 编号、邮箱地址等。

  • ES 不支持H ;4 q ) [ y – E X [ E 6 7 decim7 O % * 2 p| K A l a m 3 x (al! Q } V x . $ \,如何避免丢失精度?

五种+ N { ^ 4 = u方法:

一:使用字符串类型(比较好C & Be L \ L r 3 V o 7 0用)b J & FF h o

完全保\ o p * : ( % E留数字的精度m S G / =z R W x j |。简: ; E u ) g o单易于实现,数据, r | 3 q ;迁移时不需特别处理。但是作为f c – } m z @ ]字符串存储的数5 Z \ = j x _ :字不能直接用于数值比较或数学运算,需要在o ~ 0 ;z \ . m :应用层处理转换。但也^ h @ : , | : V M不是什么大毛病。

二:扩大浮点类` 1 W型的精度

就是d ! ;N ^ P 4直接使用 double 类型,在理rr ) x C n } % + : } ) ? ! o 9论上可能: l – C ` u h会有精K K B # P 4 0 # Z/ v$ ? t r y^ ~ P d O Z : D g度损Q % \ : n失,但实际上 d( * @ aouble 类型提供的精G o S {y ( o + j w ( i对于许多业务需求已经足够使用。需要接} T g D受减小精度损失。

三:使用scV U [ r G , } x maled_float(推荐)

Ev m p }lasV k !ti2 g D } * 5 S 0 5csearch 的 scaled_float 类型是5 1 5 ` 6 1 D一种数i | % ~ g S X值数据类型,专门用] p A m于存储5 j ]浮点数。其特点是通过一个缩放l @ @ i 4 q因子(scaling3 Z { W S 1 factor)将浮点数转换为整数来? a , R R h q: % 0 N . K储,从而在K A 0一定范围内提高存储和计算的效率。他使用一个h F – G P )m 8 N E 7 – t k S缩放c W 3 3 m = k因子将浮点数转换为整数存储。G { % h E = f (例如,如果# M Q缩放因子是 100,那么值 123.45 会存储为 1234$ : D z 6 1p ! j5。这样可以E g o * x j $避免浮点数存储和计算中的精Z d . ( RZ 1 ~ r O度问题。

四:使用多个字段

在某些b r % o B , Vl % t i e g况下,可l q \ p + ; W以将 decimal 数值拆分为两个字w L | y ` O d $段存储B m [iQ o E # . \ N c ; v H \ o 4 w W– ) m A # _:一个为整M s L D数部u N 3 ~b H 7 w,另一个为小数部v E_ m a y w )[ p ^ 6 ` 8 n 1 [ 4 c分。这样做可以在不T { ~ p B( 4 b % } ] _ y Y失精度的情况下,将| . 9 @ L ^ y数值分开处R a X Z理。可以保持数值精确,同时E g \ 5 x z S %可进行部分数? C h # y H U _学运算。但是增加了D | A0 $ g v s # M + B ! K数据处理的复~ K 1 . t D杂性,需. ; I要在应用层重建数值。/ # H kV 2 x x [ M [ F N

五:使用自v K C s N / –定义脚本

用 ElA h P 5 & L^ n / ] \ z #asticsearch 的脚本功能(如 Painless 脚本)来处理数K ] ! )值计算,确保在处理过程/ ; W中控\ v n 8制精度。优GN n I W 4 t = ? ~ }点:灵活控制数据处理逻辑。缺Z 3 ! W点:可能影响查询性能,增加系统复杂z E S S M RA 5 ER [ p / ? m Q

四、实际应用场景

1. 电商搜索

  • 需求:支持颜. Q ~ : T |色、品牌y Gk H 7 a k j \ p^ r k 4 & Q A ] ]0 B C \ H Ge M 7 ] t i格区间等多维度过滤。

  • 实现

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

2. 日志告警

  • M pl ] U p # y C 3 z:实时检a k n d L f T测ERROR日志并触发告` E 8 0 o l y警。0 : k B y o b

  • 实现

    • Watcher插件定时查D n 8 ^ 3 = / _询:

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

3. 数据, ) & ) l ( W同步容灾

  • 双写方K . hj x ) + 4 N S d

    • 应用同时写MySQL和ESf X b + F 2 ~ 9 z,通过本地事务6 P z g表记录同步状态k H y

  • 补偿机制

    • 定时任务扫描My6 x 2 i ) sSQL与$ U # &ES差异数据,修复不一: I M 4 _ S _致。

f\ ` { I ( 9 k 2 ? F ^* ( v、性能调` C 4 7 P3 QA $ Q K g w A Q ` z = , ? R s !

集群和硬Y & ^ 2 l j g 1件优化? h r 7 K d 0

负载均衡: 确保查G I a 5 Pw C \ 7 % 9 8询负载在集群中均衡$ } J ^ f , 9分配。

硬件资源: 根据需要增加 CPK Z FU、内存或改善 I/S q * L Z w ) d tO 性能(例如使用 SSDi g w ) e j w ~ I)。

配置 JVM: 优化 JVM 设置w 0 9u # % , } v D Q F \,如堆大小,以提高性& P % j *能。

  • 硬件:SSR c Y R r W +s 5 n 5 S c } dD磁盘、32GB9 = v – O d D+内I b c R D W * . {存(堆内~ c W存不超过3; R v t i1GB)。

  • 索引设– W U 4 9 r

    • 选择合适的E m L :分词器

      5 { p热分离:hot-warmg 7 F C * X * /构(热数据用SSD,冷数J ~ P Q\ q S @ Q用H? N K H J i s L gDN v + pD)。

    • 生命周期管O + [ [ 4 A理(ILMh , $ { 3 P):自动滚# k LA M 7 ( J到新\ o O N :索引\ ] y ) V\ N P \R 2 ) x } M

  • 查询优O u ? W mF b 0 j Q e Z, t G 3

    • 避免w7 = H :F G! n & y s k \ 5 % qi& W q . S 4e A k Fa | , \ t , Z 8 hldcard、regexp查询(如*S F w 5 8 Atest*)。

    • 使? e } @constant_N \ Q O 4score过滤不相/ v ! l关文档。

    • 使用过9 7 q % y o b滤器: 对$ , Z M ` s ( s于不需要评分的查询条件,使用 filt@ c K her 而不是 quey ! ory,因为 fil@ h 1 ^ L = ] 4 Pter 可以被缓存以加快后续相同查F u D a G { Q询的速} X 2 ` + i度。

    • 合理z e z $ l N z | Z使用聚合:| $ 1聚合可] ! [以用于高效地进行数据分o k B 5 ] + C析,但复杂的聚合也可* M H N $能非常j Y ~ ] ! 3 a消耗资e c W + N源。优化聚合: U b 4] ] X z ) H * o查询,如通过限制桶的数量,避免过度复杂的嵌Z q 2 V o l w g套聚合。

    • 查询尽2 0 N ^ B可能少的字段y { ; \ @ s l l n: 只返D 7 V p / { (回查询. + o s中需要的字段,减少数据传输和处理时9 / B z & % 9间。

    • 避免深度分y p Q H h k Y L a页: 避免深度分E JG A F ( 7 N 1 g B $Y s ~ A , t p,对于需= 3 O 4 E ?要处理大量数据的情况,考虑使用 search_al J t I !fter。

搜索