elasticsearch索引index之Translog数据功能分析

 更新时间:2022年04月22日 09:55:24   作者:zziawan  
这篇文章主要为大家介绍了elasticsearch索引index之Translog数据功能分析,主要分析translog的结构及写入方式,有需要的朋友可以借鉴参考下

translog的结构及写入方式

跟大多数分布式系统一样,es也通过临时写入写操作来保证数据安全。因为lucene索引过程中,数据会首先据缓存在内存中直到达到一个量(文档数或是占用空间大小)才会写入到磁盘。这就会带来一个风险,如果在写入磁盘前系统崩溃,那么这些缓存数据就会丢失。es通过translog解决了这个问题,每次写操作都会写入一个临时文件translog中,这样如果系统需要恢复数据可以从translog中读取。本篇就主要分析translog的结构及写入方式。

这一部分主要包括两部分translog和tanslogFile,前者对外提供了对translogFile操作的相关接口,后者则是具体的translogFile,它是具体的文件。

translogFile的继承关系

如下图所示:

实现了两种translogFile,它们的最大区别如名字所示就是写入时是否缓存。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());//写入数据
                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方法。操作的写入时刻进行,但是根据配置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。这四种操作也是四种能够改变索引数据的操作。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部分就是实时记录所有的修改索引操作确保数据不丢失,因此它的实现上不上非常复杂。

总结

TransLog主要作用是实时记录对于索引的修改操作,确保在索引写入磁盘前出现系统故障不丢失数据。tanslog的主要作用就是索引恢复,正常情况下需要恢复索引的时候非常少,它以stream的形式顺序写入,不会消耗太多资源,不会成为性能瓶颈。它的实现上,translog提供了对外的接口,translogFile是具体的文件抽象,提供了对于文件的具体操作。

以上就是elasticsearch索引index之Translog数据功能分析的详细内容,更多关于elasticsearch索引index Translog数据功能的资料请关注脚本之家其它相关文章!

相关文章

  • java使用dom4j解析xml配置文件实现抽象工厂反射示例

    java使用dom4j解析xml配置文件实现抽象工厂反射示例

    本文主要介绍了java使用dom4j读取配置文件实现抽象工厂和反射的示例,在Java中也可以同Donet一样,将差异配置在配置文件里面。另外,我们采用下面的方式实现,将会更加便捷
    2014-01-01
  • Java中的static--静态变量你了解吗

    Java中的static--静态变量你了解吗

    Java 中被 static 修饰的成员称为静态成员或类成员。它属于整个类所有,而不是某个对象所有,即被类的所有对象所共享。静态成员可以使用类名直接访问,也可以使用对象名进行访问,.下面我们来详细了解一下吧
    2021-09-09
  • java用扑克牌计算24点

    java用扑克牌计算24点

    这篇文章主要为大家详细介绍了java实现24点扑克牌游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • Javadoc 具体使用详解

    Javadoc 具体使用详解

    这篇文章主要介绍了Javadoc 具体使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Spring Boot跨域问题详解

    Spring Boot跨域问题详解

    在Spring Boot中处理跨域问题非常简单,你可以通过全局配置、注解或自定义过滤器的方式来控制跨域请求的行为,本文给大家介绍Spring Boot跨域问题简介,感兴趣的朋友跟随小编一起看看吧
    2023-09-09
  • Java面试岗常见问题之ArrayList和LinkedList的区别

    Java面试岗常见问题之ArrayList和LinkedList的区别

    ArrayList和LinkedList作为我们Java中最常使用的集合类,很多人在被问到他们的区别时,憋了半天仅仅冒出一句:一个是数组一个是链表。这样回答简直让面试官吐血。为了让兄弟们打好基础,我们通过实际的使用测试,好好说一下ArrayList和LinkedList的区别这道经典的面试题
    2022-01-01
  • mybatis逆向工程与分页在springboot中的应用及遇到坑

    mybatis逆向工程与分页在springboot中的应用及遇到坑

    最近在项目中应用到springboot与mybatis,在进行整合过程中遇到一些坑,在此将其整理出来,分享到脚本之家平台供大家参考下
    2018-09-09
  • 详解Log4j 日志文件存放位置设置

    详解Log4j 日志文件存放位置设置

    这篇文章主要介绍了详解Log4j 日志文件存放位置设置,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 实例解决Java异常之OutOfMemoryError的问题

    实例解决Java异常之OutOfMemoryError的问题

    在本篇文章中,我们给大家分享了关于解决Java异常之OutOfMemoryError的问题的方法,有此需要的朋友们学习下。
    2019-02-02
  • mybatis中的limit参数解读

    mybatis中的limit参数解读

    这篇文章主要介绍了mybatis中的limit参数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11

最新评论