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ū)懭耄虼俗x取的時(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除重新開(kāi)始一個(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)文章
java使用dom4j解析xml配置文件實(shí)現(xiàn)抽象工廠反射示例
本文主要介紹了java使用dom4j讀取配置文件實(shí)現(xiàn)抽象工廠和反射的示例,在Java中也可以同Donet一樣,將差異配置在配置文件里面。另外,我們采用下面的方式實(shí)現(xiàn),將會(huì)更加便捷2014-01-01Java面試崗常見(jiàn)問(wèn)題之ArrayList和LinkedList的區(qū)別
ArrayList和LinkedList作為我們Java中最常使用的集合類,很多人在被問(wèn)到他們的區(qū)別時(shí),憋了半天僅僅冒出一句:一個(gè)是數(shù)組一個(gè)是鏈表。這樣回答簡(jiǎn)直讓面試官吐血。為了讓兄弟們打好基礎(chǔ),我們通過(guò)實(shí)際的使用測(cè)試,好好說(shuō)一下ArrayList和LinkedList的區(qū)別這道經(jīng)典的面試題2022-01-01mybatis逆向工程與分頁(yè)在springboot中的應(yīng)用及遇到坑
最近在項(xiàng)目中應(yīng)用到springboot與mybatis,在進(jìn)行整合過(guò)程中遇到一些坑,在此將其整理出來(lái),分享到腳本之家平臺(tái)供大家參考下2018-09-09實(shí)例解決Java異常之OutOfMemoryError的問(wèn)題
在本篇文章中,我們給大家分享了關(guān)于解決Java異常之OutOfMemoryError的問(wèn)題的方法,有此需要的朋友們學(xué)習(xí)下。2019-02-02