一、 写操作
a)宏观:由协调节点确定路由,并将写请求发送至具体的primary shard上,在primary shard执行完写操作后,在多个replica shard上完成同步写操作
b)微观:每一个shard在执行写请求的时候,会分成并行的两部分:写数据和写日志。
-
写数据:先将需要写的数据写入内存buffer缓冲区,每隔一秒,数据会从buffer写入新的segment file并持久化到磁盘中。如果buffer快满了,也会将里面的数据存储到segment file中,清空buffer。segment file会先将数据写到os cache当中去,同时建立倒排索引,这时候客户端已经可以搜索这些新数据了,然后再写到磁盘当中。
-
写日志:每写入一条数据,就会在日志文件(Transaction log)中添加一条日志,每隔5s会持久化一次日志文件到磁盘中去。每30min或者日志文件变得过大时,会执行flush操作,将segment file持久化到磁盘上,并清空日志文件
二、读操作
读操作可以分为查询和搜索两种:
- 查询:根据ID去GET一条doc
在写入某个doc的时候,这个doc会自动分配一个docID,当然这个docID也可以在写入时由客户端手动指定。在查询的时候,会对docID进行hash路由到一个随机的节点上,这个节点作为协调节点。
协调节点会找到doc存放在哪些节点上,包括该节点的主分片和副本分片。对于这些分片,将采取轮询的策略,从中随机选取一个读取,并由协调节点对数据进行返回
- 搜索:根据一个单词或一段文本内容进行全文检索或精确匹配
客户端发送一个搜索请求到一个节点上,该节点成为协调节点,并将请求广播到索引所有的的shard上。然后每个shard将搜索自己的所有doc,进行匹配、排序,将符合的结果集返回给协调节点。
协调节点拉取这些docID对应的完整doc,然后全局的排序,分页等操作,产生最终的结果,并返回给客户端
三、 排序
在上述搜索过程中,提到了每个shard会执行匹配、排序操作。排序的具体流程如下:
- 每个shard建立小顶堆,用于保存score最大的n个Doc ID,n为from + size
- 通过倒排索引拿到满足查询条件的doc ID
- 将获取的doc ID及对应的score值,依次放入小顶堆,进行筛选
- 遍历完所有doc ID后,小顶堆中保存的doc ID即满足条件,返回给协调节点
tips:score是指词与文档的相关度评分。其计算方法涉及复杂的数学计算,这里不作展开,具体参考:ES相关度评分背后的理论