elasticsearch索引index之engine读写控制结构实现

作者:zziawan 时间:2021-12-22 00:08:07 

engine的实现结构

elasticsearch对于索引中的数据操作如读写get等接口都封装在engine中,同时engine还封装了索引的读写控制,如流量、错误处理等。engine是离lucene最近的一部分。

engine的实现结构如下所示:

elasticsearch索引index之engine读写控制结构实现

engine接口有三个实现类,主要逻辑都在InternalEngine中。

ShadowEngine之实现了engine接口的部分读方法,主要用于对于索引的读操作。

shardFSEngine在InternalEngine的基础上实现了recovery方法,它的功能跟InternalEngine基本相同只是它的recovery过程有区别,不会对Translog和index进行快照存储。

Engine类定义了一些index操作的主要方法和内部类,方法如create,index等。内部类如index,delete等。这些方法的实现是在子类中,这些方法的参数是这些内部类。

Engine类的方法:

public abstract void create(Create create) throws EngineException;
   public abstract void index(Index index) throws EngineException;
   public abstract void delete(Delete delete) throws EngineException;
   public abstract void delete(DeleteByQuery delete) throws EngineException;

这些抽象方法都在子类中实现,它们的参数都是一类,这些都是Engine的内部类,这些内部类类似于实体类,没有相关逻辑只是由很多filed及get方法构成。如Create和Index都继承自IndexOperation,它们所有信息都存储到IndexOperation的相关Field中,IndexOperation如下所示:

public static abstract class IndexingOperation implements Operation {
       private final DocumentMapper docMapper;
       private final Term uid;
       private final ParsedDocument doc;
       private long version;
       private final VersionType versionType;
       private final Origin origin;
       private final boolean canHaveDuplicates;
       private final long startTime;
       private long endTime;
   ………………
}

无论是Index还是Create,相关数据和配置都在doc中,根据doc和docMapper就能够获取本次操作的所有信息,另外的一些字段如version,uid都是在类初始化时构建。这样传给实际方法的是一个class,在方法内部根据需求获取到相应的数据

如index方法的实现:

private void innerIndex(Index index) throws IOException {
       synchronized (dirtyLock(index.uid())) {
           final long currentVersion;
           VersionValue versionValue = versionMap.getUnderLock(index.uid().bytes());
           if (versionValue == null) {
               currentVersion = loadCurrentVersionFromIndex(index.uid());
           } else {
               if (engineConfig.isEnableGcDeletes() && versionValue.delete() && (engineConfig.getThreadPool().estimatedTimeInMillis() - versionValue.time()) > engineConfig.getGcDeletesInMillis()) {
                   currentVersion = Versions.NOT_FOUND; // deleted, and GC
               } else {
                   currentVersion = versionValue.version();
               }
           }
           long updatedVersion;
           long expectedVersion = index.version();
           if (index.versionType().isVersionConflictForWrites(currentVersion, expectedVersion)) {
               if (index.origin() == Operation.Origin.RECOVERY) {
                   return;
               } else {
                   throw new VersionConflictEngineException(shardId, index.type(), index.id(), currentVersion, expectedVersion);
               }
           }
           updatedVersion = index.versionType().updateVersion(currentVersion, expectedVersion);
           index.updateVersion(updatedVersion);
           if (currentVersion == Versions.NOT_FOUND) {
               // document does not exists, we can optimize for create
               index.created(true);
               if (index.docs().size() > 1) {
                   indexWriter.addDocuments(index.docs(), index.analyzer());
               } else {
                   indexWriter.addDocument(index.docs().get(0), index.analyzer());
               }
           } else {
               if (versionValue != null) {
                   index.created(versionValue.delete()); // we have a delete which is not GC'ed...
               }
               if (index.docs().size() > 1) {
                   indexWriter.updateDocuments(index.uid(), index.docs(), index.analyzer());//获取IndexOperation中doc中字段更新索引
               } else {
                   indexWriter.updateDocument(index.uid(), index.docs().get(0), index.analyzer());
               }
           }
           Translog.Location translogLocation = translog.add(new Translog.Index(index));//写translog
           versionMap.putUnderLock(index.uid().bytes(), new VersionValue(updatedVersion, translogLocation));
           indexingService.postIndexUnderLock(index);
       }
   }

这就是Engine中create、index这些方法的实现方式。后面分析索引过程中会有更加详细说明。Engine中还有获取索引状态(元数据)及索引操作的方法如merge。这些方法也是在子类中调用lucene的相关接口,跟create,index,get很类似。因为没有深入Engine的方法实现,因此这里的分析比较简单,后面的分析会涉及这里面很多方法。

来源:https://www.cnblogs.com/zziawanblog/p/6798964.html

标签:elasticsearch,index,engine,读写控制,索引
0
投稿

猜你喜欢

  • SpringBoot返回多种格式的数据的实现示例

    2023-11-24 14:22:52
  • Java的封装类和装箱拆箱详解

    2023-09-20 22:41:22
  • Android实现摇一摇功能

    2023-07-23 20:21:11
  • 详解Mybatis通用Mapper介绍与使用

    2023-11-29 08:49:08
  • SSH原理及两种登录方法图文详解

    2023-11-14 11:10:53
  • Android kotlin使用注解实现防按钮连点功能的示例

    2023-07-02 11:58:06
  • java实现List中对象排序的方法

    2023-11-08 21:36:29
  • Java多线程Atomic包操作原子变量与原子类详解

    2023-08-18 07:46:25
  • SpringBoot之如何指定配置文件启动

    2023-11-17 15:17:48
  • Springboot项目快速实现过滤器功能

    2023-08-11 18:30:02
  • 教你怎么用SpringBoot+Mybati-Plus快速搭建代码

    2023-08-07 12:42:10
  • Spring Security前后分离校验token的实现方法

    2023-06-26 17:00:30
  • 一篇文章超详细的介绍Java继承

    2023-11-23 08:30:12
  • Android SharedPreferences实现记住密码和自动登录界面

    2023-06-15 20:07:00
  • Java常用类String的面试题汇总(java面试题)

    2023-11-23 20:40:45
  • 基于Java文件输入输出流实现文件上传下载功能

    2023-08-10 11:50:32
  • Java魔法堂之调用外部程序的方法

    2023-11-09 07:14:16
  • Spring Cloud Ribbon配置详解

    2023-11-25 01:32:50
  • 深入解析Spring Cloud内置的Zuul过滤器

    2022-05-16 12:49:04
  • SpringBoot配置shiro安全框架的实现

    2023-09-07 19:55:38
  • asp之家 软件编程 m.aspxhome.com