ES分布式架构
ES底层是基于lucene的,核心思想是在多台服务器上启动多个es进程实例,组成一个es集群
建立一个索引时,将索引拆分成多个shard,每个shard存储部分数据,然后这个shard有多个备份,每个shard都有一个primary shard,负责写入数据,但是还有几个replica shard,每个primary shard写入数据之后就会同步到其他几个replica shard上去
通过这个replica的方案,每个shard有多个备份,如果某个机器宕机了,还有别的数据副本备份在其他机器,从而实现了高可用
es集群有多个节点,会自动选举出一个master的节点,这个master节点主要是管理维护索引元数据,负责切换primary shard和replica shard身份,如果master节点宕机了,就会重新选举出一个节点为master;如果其他节点宕机了,就会由master节点将那台机器的primary shard的身份转移到其他机器的replica shard,接着如果修复了那台机器,master节点会控制将缺失的replica shard分配过去,同步修改数据,让集群恢复正常
ES的结构
es中存储数据的基本单位是索引(index),索引相当于mysql的一个数据库,索引之后是类型(type)(mysql数据库里的表),一个索引可以有多个type,每个type的字段差不多,但是会略有一点区别;type之后是mapping,mapping代表这个type的结构定义,每个type会有一个mapping,定义表里面有哪些字段和类型;之后是document,类似于mysql的一条记录,往index的type里面插入一条数据,就是指插入一条document;每个document有多个field,每个field代表这个document的一个字段的值,类似mysql的一个字段
ES写数据过程
客户端选择一个node发送请求,这个node这时被称作coordinating node(协调节点),coordinating node对document进行路由,将请求转发给对应的带有primary shard的node,coordinating node 如果发现primary node和所有的replica node都写完之后,会返回响应结果给客户端
ES读数据过程
可以通过doc id来查询,会根据doc id进行hash,判断doc id被分配到那个shard上去,从那个shard去查询
- 客户端发送一个请求到任意一个node,这个node这时被称作coordinating node(协调节点)
- coordinating node对doc id进行hash,并将请求转发给对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有的replica shard里面随机选一个,让读请求负载均衡
- 接受请求的node返回document给coordinating node,coordinating node 返回document给客户端
ES搜索数据过程
- 客户端发送请求到一个node,这个node这时被称作coordinating node(协调节点)
- coordinating node会将搜索请求转发到所有的shard对应的primary shard和replica node
- query phrase:每个shard将自己的的搜索结果返回给coordinating node,由coordinating node对结果进行合并,排序,分页等,产出最终结果
- fetch Phrase:coordinating node根据doc id去各个节点拉取实际的document数据,最终返回给客户端
ES写数据底层原理
- coordinating node将document路由之后,实际写数据的primary shard会先将document写入内存buffer,在buffer里的时候数据是搜索不到的,同时将数据写入translog日志文件。如果buffer快满了,或者到一定时间,就会将buffer数据refresh到一个新的segment file,但是此时数据不是直接进入segment file磁盘文件,而是先进入os cache。
- 每隔1s,es将buffer写入一个新的segment file,每秒钟会产生一个新的磁盘文件segment file,这个segment file就存储着最近1s内buffer写入的数据
- 如果buffer没有数据,不会执行refresh操作;如果有,默认是1s1次refresh
- 只要buffer被写进了os cache,就可以被检索到,所以写入的数据默认是1s后能看到,所以es被称作准实时的
- 当重复上述步骤时,translog会越来越大,当translog大到一定长度时,就会触发commit操作
- commit第一步,会将buffer数据refresh到os cache中去,然后清空buffer,然后将一个commit point写入磁盘,里面标识着这个commit point对应的所有的segment file
- 同时强行将os cache中的数据fsync到磁盘文件中去
- 最后清空translog日志,重启一个translog
- 这个commit叫flush,默认是30分钟一次
translog:在执行commit之前,数据要么在buffer,要么在os cache,都属于内存区域,一旦机器宕机,数据就会丢失,所以translog日志能够帮助在宕机的时候恢复数据
translog其实也是先写入 os cache 的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有 5 秒的数据会仅仅停留在 buffer 或者 translog 文件的 os cache 中,如果此时机器挂了,会丢失 5 秒钟的数据。
删除/更新底层原理
如果是删除操作,commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了
如果是更新操作,就是将原来的doc标识为deleted状态,然后重新写入一条数据
buffer 每次 refresh 一次,就会产生一个 segment file,所以默认情况下是 1 秒钟一个 segment file,这样下来 segment file会越来越多,此时会定期执行merge。每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开 segment file供搜索使用,同时删除旧的segment file。
倒排索引
- 在搜索引擎中,每个文档都有一个对应的文档ID,文档内容被表示为一系列关键词的集合
倒排索引就是关键词到文档ID的映射,每个关键词都对应这一系列的文件,这些文件中都出现了关键词
DocID | Doc |
---|---|
1 | 谷歌地图之父跳槽 Facebook |
2 | 谷歌地图之父加盟 Facebook |
3 | 谷歌地图创始人拉斯离开谷歌加盟 Facebook |
4 | 谷歌地图之父跳槽 Facebook 与 Wave 项目取消有关 |
5 | 谷歌地图之父拉斯加盟社交网站 Facebook |
对文档进行分词之后,得到以下倒排索引
WordId | Word | DocIds |
---|---|---|
1 | 谷歌 | 1,2,3,4,5 |
2 | 地图 | 1,2,3,4,5 |
3 | 之父 | 1,2,4,5 |
4 | 跳槽 | 1,4 |
5 | 1,2,3,4,5 | |
6 | 加盟 | 2,3,5 |
7 | 创始人 | 3 |
8 | 拉斯 | 3,5 |
9 | 离开 | 3 |
10 | 与 | 4 |
.. | .. | .. |
另外,实用的倒排索引还可以记录更多的信息,比如文档频率信息,表示在文档集合中有多少个文档包含某个单词。
那么,有了倒排索引,搜索引擎可以很方便地响应用户的查询。比如用户输入查询 Facebook,搜索系统查找倒排索引,从中读出包含这个单词的文档,这些文档就是提供给用户的搜索结果。
网友评论