elasticsearch索引index之Translog數(shù)據(jù)功能分析
translog的結(jié)構(gòu)及寫入方式
跟大多數(shù)分布式系統(tǒng)一樣,es也通過(guò)臨時(shí)寫入寫操作來(lái)保證數(shù)據(jù)安全。因?yàn)閘ucene索引過(guò)程中,數(shù)據(jù)會(huì)首先據(jù)緩存在內(nèi)存中直到達(dá)到一個(gè)量(文檔數(shù)或是占用空間大?。┎艜?huì)寫入到磁盤。這就會(huì)帶來(lái)一個(gè)風(fēng)險(xiǎn),如果在寫入磁盤前系統(tǒng)崩潰,那么這些緩存數(shù)據(jù)就會(huì)丟失。es通過(guò)translog解決了這個(gè)問(wèn)題,每次寫操作都會(huì)寫入一個(gè)臨時(shí)文件translog中,這樣如果系統(tǒng)需要恢復(fù)數(shù)據(jù)可以從translog中讀取。本篇就主要分析translog的結(jié)構(gòu)及寫入方式。
這一部分主要包括兩部分translog和tanslogFile,前者對(duì)外提供了對(duì)translogFile操作的相關(guān)接口,后者則是具體的translogFile,它是具體的文件。
translogFile的繼承關(guān)系
如下圖所示:

實(shí)現(xiàn)了兩種translogFile,它們的最大區(qū)別如名字所示就是寫入時(shí)是否緩存。FsTranslogFile的接口如下所示:

每一個(gè)translogFile都會(huì)有一個(gè)唯一Id,兩個(gè)非常重要的方法add和write。add是添加對(duì)應(yīng)的操作,這些操作都是在translog中定義,這里寫入的只是byte類型的文件,不關(guān)注是何種操作。所有的操作都是順序?qū)懭?,因此讀取的時(shí)候需要一個(gè)位置信息。add方法代碼如下所示:
public Translog.Location add(BytesReference data) throws IOException {
rwl.writeLock().lock();//獲取讀寫鎖,每個(gè)文件的寫入都是順序的。
try {
operationCounter++;
long position = lastPosition;
if (data.length() >= buffer.length) {
flushBuffer();
// we use the channel to write, since on windows, writing to the RAF might not be reflected
// when reading through the channel
data.writeTo(raf.channel());//寫入數(shù)據(jù)
lastWrittenPosition += data.length();
lastPosition += data.length();//記錄位置
return new Translog.Location(id, position, data.length());//返回由id,位置及長(zhǎng)度確定的操作位置信息。
}
if (data.length() > buffer.length - bufferCount) {
flushBuffer();
}
data.writeTo(bufferOs);
lastPosition += data.length();
return new Translog.Location(id, position, data.length());
} finally {
rwl.writeLock().unlock();
}
}這是SimpleTranslogFile寫入操作,BufferedTransLogFile寫入邏輯基本相同,只是它不會(huì)立刻寫入到硬盤,先進(jìn)行緩存。
TranslogFile快照的方法
另外TranslogFile還提供了一個(gè)快照的方法,該方法返回一個(gè)FileChannelSnapshot,可以通過(guò)它next方法將translogFile中所有的操作都讀出來(lái),寫入到一個(gè)shapshot文件中。代碼如下:
public FsChannelSnapshot snapshot() throws TranslogException {
if (raf.increaseRefCount()) {
boolean success = false;
try {
rwl.writeLock().lock();
try {
FsChannelSnapshot snapshot = new FsChannelSnapshot(this.id, raf, lastWrittenPosition, operationCounter);
snapshot.seekTo(this.headsuccess = true;
returnerSize);
snapshot;
} finally {
rwl.writeLock().unlock();
}
} catch (FileNotFoundException e) {
throw new TranslogException(shardId, "failed to create snapshot", e);
} finally {
if (!success) {
raf.decreaseRefCount(false);
}
}
}
return null;
}TransLogFile是具體文件的抽象,它只是負(fù)責(zé)寫入和讀取,并不關(guān)心讀取和寫入的操作類型。各種操作的定義及對(duì)TransLogFile的定義到在Translog中。它的接口如下所示:

這里的寫入(add)就是一個(gè)具體的操作,這是一個(gè)外部調(diào)用接口,索引、刪除等修改索引的操作都會(huì)構(gòu)造一個(gè)對(duì)應(yīng)的Operation在對(duì)索引進(jìn)行相關(guān)操作的同時(shí)調(diào)用該方法。這里還要著重說(shuō)明一下makeTransientCurrent方法。操作的寫入時(shí)刻進(jìn)行,但是根據(jù)配置TransLogFile超過(guò)限度時(shí)需要?jiǎng)h除重新開始一個(gè)新的文件。因此在transLog中存在兩個(gè)TransLogFile,current和transient。當(dāng)需要更換時(shí)需要通過(guò)讀寫鎖確保單線程操作,將current切換到transient上來(lái),然后刪除之前的current。代碼如下所示:
public void revertTransient() {
FsTranslogFile tmpTransient;
rwl.writeLock().lock();
try {
tmpTransient = trans;//交換
this.trans = null;
} finally {
rwl.writeLock().unlock();
}
logger.trace("revert transient {}", tmpTransient);
// previous transient might be null because it was failed on its creation
// for example
if (tmpTransient != null) {
tmpTransient.close(true);
}
}translog中定義了index,create,delete及deletebyquery四種操作它們都繼承自O(shè)peration。這四種操作也是四種能夠改變索引數(shù)據(jù)的操作。operation代碼如下所示:
static interface Operation extends Streamable {
static enum Type {
CREATE((byte) 1),
SAVE((byte) 2),
DELETE((byte) 3),
DELETE_BY_QUERY((byte) 4);
private final byte id;
private Type(byte id) {
this.id = id;
}
public byte id() {
return this.id;
}
public static Type fromId(byte id) {
switch (id) {
case 1:
return CREATE;
case 2:
return SAVE;
case 3:
return DELETE;
case 4:
return DELETE_BY_QUERY;
default:
throw new ElasticsearchIllegalArgumentException("No type mapped for [" + id + "]");
}
}
}
Type opType();
long estimateSize();
Source getSource();
}tanslog部分就是實(shí)時(shí)記錄所有的修改索引操作確保數(shù)據(jù)不丟失,因此它的實(shí)現(xiàn)上不上非常復(fù)雜。
總結(jié)
TransLog主要作用是實(shí)時(shí)記錄對(duì)于索引的修改操作,確保在索引寫入磁盤前出現(xiàn)系統(tǒng)故障不丟失數(shù)據(jù)。tanslog的主要作用就是索引恢復(fù),正常情況下需要恢復(fù)索引的時(shí)候非常少,它以stream的形式順序?qū)懭?,不?huì)消耗太多資源,不會(huì)成為性能瓶頸。它的實(shí)現(xiàn)上,translog提供了對(duì)外的接口,translogFile是具體的文件抽象,提供了對(duì)于文件的具體操作。
以上就是elasticsearch索引index之Translog數(shù)據(jù)功能分析的詳細(xì)內(nèi)容,更多關(guān)于elasticsearch索引index Translog數(shù)據(jù)功能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- elasticsearch索引創(chuàng)建create?index集群matedata更新
- elasticsearch索引的創(chuàng)建過(guò)程index?create邏輯分析
- elasticsearch索引index之merge底層機(jī)制的合并講解
- elasticsearch索引index之Mapping實(shí)現(xiàn)關(guān)系結(jié)構(gòu)示例
- elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實(shí)現(xiàn)
- elasticsearch索引index數(shù)據(jù)功能源碼示例
- elasticsearch源碼分析index?action實(shí)現(xiàn)方式
- elasticsearch索引index之put?mapping的設(shè)置分析
相關(guān)文章
Spring中TransactionSynchronizationManager的使用詳解
這篇文章主要介紹了Spring中TransactionSynchronizationManager的使用詳解,TransactionSynchronizationManager是事務(wù)同步管理器,監(jiān)聽(tīng)事務(wù)的操作,來(lái)實(shí)現(xiàn)在事務(wù)前后可以添加一些指定操作,需要的朋友可以參考下2023-09-09
SpringMVC靜態(tài)資源訪問(wèn)問(wèn)題如何解決
這篇文章主要介紹了SpringMVC靜態(tài)資源訪問(wèn)問(wèn)題如何解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
java?JUC信號(hào)量Semaphore原理及使用介紹
這篇文章主要為大家介紹了java?JUC信號(hào)量Semaphore原理及使用介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
SpringBoot2.3.0配置JPA的實(shí)現(xiàn)示例
這篇文章主要介紹了SpringBoot2.3.0配置JPA的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
IDEA下使用MyBatisCodeHelper插件的方法詳解
這篇文章主要介紹了IDEA下使用MyBatisCodeHelper插件的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09

