elasticsearch索引index之Translog數(shù)據(jù)功能分析
translog的結構及寫入方式
跟大多數(shù)分布式系統(tǒng)一樣,es也通過臨時寫入寫操作來保證數(shù)據(jù)安全。因為lucene索引過程中,數(shù)據(jù)會首先據(jù)緩存在內存中直到達到一個量(文檔數(shù)或是占用空間大?。┎艜懭氲酱疟P。這就會帶來一個風險,如果在寫入磁盤前系統(tǒng)崩潰,那么這些緩存數(shù)據(jù)就會丟失。es通過translog解決了這個問題,每次寫操作都會寫入一個臨時文件translog中,這樣如果系統(tǒng)需要恢復數(shù)據(jù)可以從translog中讀取。本篇就主要分析translog的結構及寫入方式。
這一部分主要包括兩部分translog和tanslogFile,前者對外提供了對translogFile操作的相關接口,后者則是具體的translogFile,它是具體的文件。
translogFile的繼承關系
如下圖所示:
實現(xiàn)了兩種translogFile,它們的最大區(qū)別如名字所示就是寫入時是否緩存。FsTranslogFile的接口如下所示:
每一個translogFile都會有一個唯一Id,兩個非常重要的方法add和write。add是添加對應的操作,這些操作都是在translog中定義,這里寫入的只是byte類型的文件,不關注是何種操作。所有的操作都是順序寫入,因此讀取的時候需要一個位置信息。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)就是一個具體的操作,這是一個外部調用接口,索引、刪除等修改索引的操作都會構造一個對應的Operation在對索引進行相關操作的同時調用該方法。這里還要著重說明一下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)上不上非常復雜。
總結
TransLog主要作用是實時記錄對于索引的修改操作,確保在索引寫入磁盤前出現(xiàn)系統(tǒng)故障不丟失數(shù)據(jù)。tanslog的主要作用就是索引恢復,正常情況下需要恢復索引的時候非常少,它以stream的形式順序寫入,不會消耗太多資源,不會成為性能瓶頸。它的實現(xiàn)上,translog提供了對外的接口,translogFile是具體的文件抽象,提供了對于文件的具體操作。
以上就是elasticsearch索引index之Translog數(shù)據(jù)功能分析的詳細內容,更多關于elasticsearch索引index Translog數(shù)據(jù)功能的資料請關注腳本之家其它相關文章!
- elasticsearch索引創(chuàng)建create?index集群matedata更新
- elasticsearch索引的創(chuàng)建過程index?create邏輯分析
- elasticsearch索引index之merge底層機制的合并講解
- elasticsearch索引index之Mapping實現(xiàn)關系結構示例
- elasticsearch索引index之engine讀寫控制結構實現(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-01Java面試崗常見問題之ArrayList和LinkedList的區(qū)別
ArrayList和LinkedList作為我們Java中最常使用的集合類,很多人在被問到他們的區(qū)別時,憋了半天僅僅冒出一句:一個是數(shù)組一個是鏈表。這樣回答簡直讓面試官吐血。為了讓兄弟們打好基礎,我們通過實際的使用測試,好好說一下ArrayList和LinkedList的區(qū)別這道經(jīng)典的面試題2022-01-01mybatis逆向工程與分頁在springboot中的應用及遇到坑
最近在項目中應用到springboot與mybatis,在進行整合過程中遇到一些坑,在此將其整理出來,分享到腳本之家平臺供大家參考下2018-09-09實例解決Java異常之OutOfMemoryError的問題
在本篇文章中,我們給大家分享了關于解決Java異常之OutOfMemoryError的問題的方法,有此需要的朋友們學習下。2019-02-02