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

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

每一個translogFile都會有一個唯一Id,兩個非常重要的方法add和write。add是添加對應的操作,這些操作都是在translog中定義,這里寫入的只是byte類型的文件,不關注是何種操作。所有的操作都是順序?qū)懭耄虼俗x取的時候需要一個位置信息。add方法代碼如下所示:
public Translog.Location add(BytesReference data) throws IOException {
rwl.writeLock().lock();//獲取讀寫鎖,每個文件的寫入都是順序的。
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,位置及長度確定的操作位置信息。
}
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寫入邏輯基本相同,只是它不會立刻寫入到硬盤,先進行緩存。
TranslogFile快照的方法
另外TranslogFile還提供了一個快照的方法,該方法返回一個FileChannelSnapshot,可以通過它next方法將translogFile中所有的操作都讀出來,寫入到一個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是具體文件的抽象,它只是負責寫入和讀取,并不關心讀取和寫入的操作類型。各種操作的定義及對TransLogFile的定義到在Translog中。它的接口如下所示:

這里的寫入(add)就是一個具體的操作,這是一個外部調(diào)用接口,索引、刪除等修改索引的操作都會構(gòu)造一個對應的Operation在對索引進行相關操作的同時調(diào)用該方法。這里還要著重說明一下makeTransientCurrent方法。操作的寫入時刻進行,但是根據(jù)配置TransLogFile超過限度時需要刪除重新開始一個新的文件。因此在transLog中存在兩個TransLogFile,current和transient。當需要更換時需要通過讀寫鎖確保單線程操作,將current切換到transient上來,然后刪除之前的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四種操作它們都繼承自Operation。這四種操作也是四種能夠改變索引數(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ù)據(jù)不丟失,因此它的實現(xiàn)上不上非常復雜。
總結(jié)
TransLog主要作用是實時記錄對于索引的修改操作,確保在索引寫入磁盤前出現(xiàn)系統(tǒng)故障不丟失數(shù)據(jù)。tanslog的主要作用就是索引恢復,正常情況下需要恢復索引的時候非常少,它以stream的形式順序?qū)懭?,不會消耗太多資源,不會成為性能瓶頸。它的實現(xiàn)上,translog提供了對外的接口,translogFile是具體的文件抽象,提供了對于文件的具體操作。
以上就是elasticsearch索引index之Translog數(shù)據(jù)功能分析的詳細內(nèi)容,更多關于elasticsearch索引index Translog數(shù)據(jù)功能的資料請關注腳本之家其它相關文章!
- elasticsearch索引創(chuàng)建create?index集群matedata更新
- elasticsearch索引的創(chuàng)建過程index?create邏輯分析
- elasticsearch索引index之merge底層機制的合并講解
- elasticsearch索引index之Mapping實現(xiàn)關系結(jié)構(gòu)示例
- elasticsearch索引index之engine讀寫控制結(jié)構(gòu)實現(xiàn)
- elasticsearch索引index數(shù)據(jù)功能源碼示例
- elasticsearch源碼分析index?action實現(xiàn)方式
- elasticsearch索引index之put?mapping的設置分析
相關文章
java使用dom4j解析xml配置文件實現(xiàn)抽象工廠反射示例
本文主要介紹了java使用dom4j讀取配置文件實現(xiàn)抽象工廠和反射的示例,在Java中也可以同Donet一樣,將差異配置在配置文件里面。另外,我們采用下面的方式實現(xiàn),將會更加便捷2014-01-01
Java面試崗常見問題之ArrayList和LinkedList的區(qū)別
ArrayList和LinkedList作為我們Java中最常使用的集合類,很多人在被問到他們的區(qū)別時,憋了半天僅僅冒出一句:一個是數(shù)組一個是鏈表。這樣回答簡直讓面試官吐血。為了讓兄弟們打好基礎,我們通過實際的使用測試,好好說一下ArrayList和LinkedList的區(qū)別這道經(jīng)典的面試題2022-01-01
mybatis逆向工程與分頁在springboot中的應用及遇到坑
最近在項目中應用到springboot與mybatis,在進行整合過程中遇到一些坑,在此將其整理出來,分享到腳本之家平臺供大家參考下2018-09-09
實例解決Java異常之OutOfMemoryError的問題
在本篇文章中,我們給大家分享了關于解決Java異常之OutOfMemoryError的問題的方法,有此需要的朋友們學習下。2019-02-02

