elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實(shí)現(xiàn)
engine的實(shí)現(xiàn)結(jié)構(gòu)
elasticsearch對(duì)于索引中的數(shù)據(jù)操作如讀寫get等接口都封裝在engine中,同時(shí)engine還封裝了索引的讀寫控制,如流量、錯(cuò)誤處理等。engine是離lucene最近的一部分。
engine的實(shí)現(xiàn)結(jié)構(gòu)如下所示:

engine接口有三個(gè)實(shí)現(xiàn)類,主要邏輯都在InternalEngine中。
ShadowEngine之實(shí)現(xiàn)了engine接口的部分讀方法,主要用于對(duì)于索引的讀操作。
shardFSEngine在InternalEngine的基礎(chǔ)上實(shí)現(xiàn)了recovery方法,它的功能跟InternalEngine基本相同只是它的recovery過程有區(qū)別,不會(huì)對(duì)Translog和index進(jìn)行快照存儲(chǔ)。
Engine類定義了一些index操作的主要方法和內(nèi)部類,方法如create,index等。內(nèi)部類如index,delete等。這些方法的實(shí)現(xiàn)是在子類中,這些方法的參數(shù)是這些內(nèi)部類。
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;這些抽象方法都在子類中實(shí)現(xiàn),它們的參數(shù)都是一類,這些都是Engine的內(nèi)部類,這些內(nèi)部類類似于實(shí)體類,沒有相關(guān)邏輯只是由很多filed及get方法構(gòu)成。如Create和Index都繼承自IndexOperation,它們所有信息都存儲(chǔ)到IndexOperation的相關(guān)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,相關(guān)數(shù)據(jù)和配置都在doc中,根據(jù)doc和docMapper就能夠獲取本次操作的所有信息,另外的一些字段如version,uid都是在類初始化時(shí)構(gòu)建。這樣傳給實(shí)際方法的是一個(gè)class,在方法內(nèi)部根據(jù)需求獲取到相應(yīng)的數(shù)據(jù)
如index方法的實(shí)現(xiàn):
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這些方法的實(shí)現(xiàn)方式。后面分析索引過程中會(huì)有更加詳細(xì)說明。Engine中還有獲取索引狀態(tài)(元數(shù)據(jù))及索引操作的方法如merge。這些方法也是在子類中調(diào)用lucene的相關(guān)接口,跟create,index,get很類似。因?yàn)闆]有深入Engine的方法實(shí)現(xiàn),因此這里的分析比較簡單,后面的分析會(huì)涉及這里面很多方法。
總結(jié)
這里只是從結(jié)構(gòu)上對(duì)indexEngine進(jìn)行了簡單說明,它里面的方法是es對(duì)lucene索引操作方法的封裝,只是增加了一下處理方面的邏輯如寫translog,異常處理等。它的操作對(duì)象是shard,es所有對(duì)shard的寫操作都是通過Engine來實(shí)現(xiàn),后面的分析會(huì)有所體現(xiàn)。
以上就是elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于elasticsearch索引index engine讀寫控制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java 對(duì) Properties 文件的操作詳解及簡單實(shí)例
這篇文章主要介紹了Java 對(duì) Properties 文件的操作詳解及簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02
Java多線程之ReentrantReadWriteLock源碼解析
這篇文章主要介紹了Java多線程之ReentrantReadWriteLock源碼解析,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-05-05
Mybatis中${param}與#{param}的區(qū)別說明
這篇文章主要介紹了Mybatis中${param}與#{param}的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
PowerJob的TransportServiceAware工作流程源碼解讀
這篇文章主要介紹了PowerJob的TransportServiceAware工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Java并發(fā)編程之ConcurrentLinkedQueue解讀
這篇文章主要介紹了Java并發(fā)編程之ConcurrentLinkedQueue解讀,非阻塞的實(shí)現(xiàn)方式則可以使用循環(huán)CAS的方式來實(shí)現(xiàn),而ConcurrentLinkedQueue就是juc包中自帶的經(jīng)典非堵塞方式實(shí)現(xiàn)的工具類,需要的朋友可以參考下2023-12-12
Java中的 FilterInputStream簡介_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
FilterInputStream 的作用是用來“封裝其它的輸入流,并為它們提供額外的功能”。接下來通過本文給大家分享Java中的 FilterInputStream簡介,感興趣的朋友一起學(xué)習(xí)吧2017-05-05
Java生成10個(gè)1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出
這篇文章主要介紹了Java生成10個(gè)1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出,需要的朋友可以參考下2015-10-10

