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

engine的实现结构如下所示:

engine接口有三个实现类,主要逻辑都在InternalEngine中。ShadowEngine之实现了engine接口的部分读方法,主要用于对于索引的读操作。shardFSEngine在InternalEngine的基础上实现了recovery方法,它的功能跟InternalEngine基本相同只是它的recovery过程有区别,不会对Translog和index进行快照存储。

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

 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的方法实现,因此这里的分析比较简单,后面的分析会涉及这里面很多方法。

总结:这里只是从结构上对indexEngine进行了简单说明,它里面的方法是es对lucene索引操作方法的封装,只是增加了一下处理方面的逻辑如写translog,异常处理等。它的操作对象是shard,es所有对shard的写操作都是通过Engine来实现,后面的分析会有所体现。

最新文章

  1. [MetaHook] Quake FMOD function
  2. 常见的百度蜘蛛IP
  3. nutch 采集效率问题
  4. 游戏开发设计模式之状态模式 & 有限状态机 & c#委托事件(unity3d 示例实现)
  5. Tomcat闪退的问题
  6. Java进阶(三十一) Web服务调用
  7. Android开发常用网站汇总
  8. CentOS 7.4上安装mysql 8.0
  9. 【原创】大叔经验分享(9)yarn重要配置yarn.nodemanager.local-dirs
  10. python Excel数据导出
  11. iPhone手机怎么投屏到电脑 airplay在哪里设置
  12. java 中数据的强制转换 和计算的补码运算
  13. CentOS 7.x编译安装Nginx1.10.3+MySQL5.7.16+PHP5.2 5.3 5.4 5.5 5.6 7.0 7.1多版本全能环境
  14. C# 数据结构基础-实现循环队列
  15. 在Asp.Net MVC中使用Repeater控件
  16. 在ListView中添加EditText丢失光标问题解决
  17. boost-使用说明
  18. 【Nodejs】使用request批量下载MP3,文件数量内容都没问题
  19. centos7安装MySQL5.7无法设置密码问题
  20. iptables进行DNAT(目标地址转换)

热门文章

  1. HBase的体系结构
  2. sql索引碎片产生的原理 解决碎片的办法(sql碎片整理)
  3. JTable表格案例
  4. caffe for python (官方翻译)
  5. 【Git 一】Linux安装Git
  6. 求第区间第k大数 TLE归并树
  7. spring-data-jpa 新增 修改 删除 查询 分页
  8. Markdown编辑器 常用语法
  9. JS几种遍历方式比较
  10. 【SRM 717 div2 B】LexmaxReplace