如何保证数据写入过程中不丢

数据写入请求达到时,以需要的数据格式组织并写入磁盘的过程叫做数据提交,对应es就是创建倒排索引,维护segment文件

如果我们同步的方式,来处理上述过程,那么系统的吞吐量将很低

如果我们以异步的方式,先写入内存,然后再异步提交到磁盘,则有可能因为机器故障而而丢失还未写入到磁盘中的数据

为了解决这个问题,一般的存储系统都会设计transag log (事务日志)或这write ahead log(预写式日志)。它的作用时,将最近的写入数据或操作以日志的形式直接落盘,从而使得即便系统崩溃后,依然可以基于这些磁盘日志进行数据恢复。

Mysql有redo undo log ,而HBASE、LevelDB,RockDB等采用的LSM tree则提供了write ahead log 这样的设计,来保证数据的不丢失

直接落盘的 translog 为什么不怕降低写入吞吐量?

上述论述中,数据以同步方式落盘会有性能问题,为什么将translog和wal直接落盘不影响性能?原因如下:

  • 写的日志不需要维护复杂的数据结构,它仅用于记录还未真正提交的业务数据。所以体量小
  • 并且以顺序方式写盘,速度快

es默认是每个请求都会同步落盘translog ,即配置index.translog.durabilityrequest。当然对于一些可以丢数据的场景,我们可以将index.translog.durability配置为async 来提升写入translog的性能,该配置会异步写入translog到磁盘。具体多长时间写一次磁盘,则通过index.translog.sync_interval来控制

前面说了,为了保证translog足够小,所以translog不能无限扩张,需要在一定量后,将其对应的真实业务数据以其最终数据结构(es是倒排索引)提交到磁盘,这个动作称为flush ,它会实际的对底层Lucene 进行一次commit。我们可以通过index.translog.flush_threshold_size 来配置translog多大时,触发一次flush。每一次flush后,原translog将被删除,重新创建一个新的translog

elasticsearch本身也提供了flush api来触发上述commit动作,但无特殊需求,尽量不要手动触发

如何保证已写数据在集群中不丢

对每个shard采用副本机制。保证写入每个shard的数据不丢

in-memory buffer

前述translog只是保证数据不丢,为了其记录的高效性,其本身并不维护复杂的数据结构。 实际的业务数据的会先写入到in-memory buffer中,当调用refresh后,该buffer中的数据会被清空,转而reopen一个segment,使得其数据对查询可见。但这个segment本身也还是在内存中,如果系统宕机,数据依然会丢失。需要通过translog进行恢复

其实这跟lsm tree非常相似,新写入内存的业务数据存放在内存的MemTable(对应es的in-memory buffer),它对应热数据的写入,当达到一定量并维护好数据结构后,将其转成内存中的ImmutableMemTable(对应es的内存segment),它变得可查询。

总结

  • refresh 用于将写入内存in-memory buffer数据,转为查询可见的segment

  • 每次一次写入除了写入内存外in-memory buffer,还会默认的落盘translog

  • translog 达到一定量后,触发in-memory buffer落盘,并清空自己,这个动作叫做flush

  • 如遇当前写入的shard宕机,则可以通过磁盘中的translog进行数据恢复

LSM Tree的详细介绍

https://www.cnblogs.com/niceshot/p/14321372.html

参考资料

https://ezlippi.com/blog/2018/04/elasticsearch-translog.html

https://stackoverflow.com/questions/19963406/refresh-vs-flush

https://qbox.io/blog/refresh-flush-operations-elasticsearch-guide/

https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-translog.html#index-modules-translog-retention

https://www.elastic.co/guide/cn/elasticsearch/guide/current/translog.html

欢迎关注我的个人公众号"西北偏北UP",记录代码人生,行业思考,科技评论

Elasticsearch如何保证数据不丢失?的更多相关文章

  1. Spark Streaming使用Kafka保证数据零丢失

    来自: https://community.qingcloud.com/topic/344/spark-streaming使用kafka保证数据零丢失 spark streaming从1.2开始提供了 ...

  2. Kafka如何保证数据不丢失

    Kafka如何保证数据不丢失 1.生产者数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到,其中状态有0,1,-1. 如果是 ...

  3. [转帖]kafka 如何保证数据不丢失

    kafka 如何保证数据不丢失 https://www.cnblogs.com/MrRightZhao/p/11498952.html   一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数 ...

  4. kafka 如何保证数据不丢失

    一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会问到相关的问题.但凡遇到这种问题,是指3个方面的数据不丢失,即:producer consumer 端数据不丢失  b ...

  5. Spark Streaming和Kafka整合保证数据零丢失

    当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.为了体验这个关键的特性,你需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源 ...

  6. rabbitmq保证数据不丢失方案

    rabbitmq如何保证消息的可靠性 1.保证消息不丢失 1.1.开启事务(不推荐) 1.2.开启confirm(推荐) 1.3.开启RabbitMQ的持久化(交换机.队列.消息) 1.4.关闭Rab ...

  7. kafka保证数据不丢失机制

    kafka如何保证数据的不丢失 1.生产者如何保证数据的不丢失:消息的确认机制,使用ack机制我们可以配置我们的消息不丢失机制为-1,保证我们的partition的leader与follower都保存 ...

  8. Spark Streaming和Kafka整合是如何保证数据零丢失

    转载:https://www.iteblog.com/archives/1591.html 当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢 ...

  9. 23 mysql怎么保证数据不丢失?

    MySQL的wal机制,得到的结论是:只要redo log和binlog 持久化到磁盘,就能确保mysql异常重新启动后,数据是可以恢复的. binlog的写入机制 其实,binlog的写入逻辑比较简 ...

随机推荐

  1. Redis在存取序列化和反序列化性能问题

    1. 问题场景 我们在使用Redis的时候经常会将对象序列化存储到Redis中,在取出的时候进行反序列化,如果对象过大在进行序列化和反序列化的时候会有一定性能问题.今天查看了CSRedis源码发现在S ...

  2. web前台界面的两种验证方式

    JSON的全称是"JavaScript Object Notation",意思是JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式. 第一种: 用户体 ...

  3. 关于BackTop按钮的实现

    今天在处理,首页面的制作的时候,在实现backtop按键的时候,有些思路,作为记录. 功能为,点击backtop即可,立马跳到首页的最上面,且backtop只有在页面后1/2处才显示出来. 首先,我们 ...

  4. Linux下Oracle19c离线rpm安装

    一.基础环境配置 1.关闭系统防火墙 systemctl stop firewalld syustemctl disable firewalld 2.关闭selinux vim /etc/selinu ...

  5. Linux sed 命令总结

    一.sed格式命令 sed 命令行格式为:sed [选项] 'command' 输入文本 二.sed命令的选项 sed [选项] [动作] 选项与参数: -n :使用安静(silent)模式.在一般 ...

  6. Spring源码深度解析之数据库连接JDBC

    Spring源码深度解析之数据库连接JDBC JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...

  7. .NET Core 中的日志与分布式链路追踪

    目录 .NET Core 中的日志与分布式链路追踪 .NET Core 中的日志 控制台输出 非侵入式日志 Microsoft.Extensions.Logging ILoggerFactory IL ...

  8. ORACLE的还原表空间UNDO写满磁盘空间,解决该问题的具体步骤

    产生问题的原因主要以下两点:1. 有较大的事务量让Oracle Undo自动扩展,产生过度占用磁盘空间的情况:2. 有较大事务没有收缩或者没有提交所导制:说明:本问题在ORACLE系统管理中属于比较正 ...

  9. python -c 妙用

    前言 python -c 命令还是有用的哈 正文 python的 -c 可以在命令行中调用 python 代码, 实际上 -c 就是 command 的意思 官方文档中解释为(节选自: python ...

  10. ajax跨域访问http服务--jsonp

    在前面一篇文章<Spring Cloud 前后端分离后引起的跨域访问解决方案>里我们提到使用ajax跨域请求其他应用的http服务,使用的是后台增加注解@CrossOrigin或者增加Co ...