美文网首页python相关
python-ES即时刷新file system cache

python-ES即时刷新file system cache

作者: 红尘丶 | 来源:发表于2020-01-15 18:04 被阅读0次

    作者:祈雨v
    链接:https://juejin.im/post/5d1b35a1e51d45775746b990

    概要

    elasticsearch被称为准实时搜索,原因是对es的写入操作成功后,写入的数据需要1秒钟后才能被搜索到,因此es搜索是准实时或者又称为近实时(near real time)。

    elasticsearch底层使用的Lucene,而Lucene的写入是实时的。但Lucene的实时写入意味着每一次写入请求都直接将数据写入硬盘,因此频繁的I/O操作会导致很大的性能问题。

    原理

    image.png

    当一个写请求发送到es后,es将数据写入memory buffer中,并添加事务日志(translog)。如果每次一条数据写入内存后立即写到硬盘文件上,由于写入的数据肯定是离散的,因此写入硬盘的操作也就是随机写入了。硬盘随机写入的效率相当低,会严重降低es的性能。

    因此es在设计时在memory buffer和硬盘间加入了Linux的页面高速缓存(File system cache)来提高es的写效率。
    当写请求发送到es后,es将数据暂时写入memory buffer中,此时写入的数据还不能被查询到。默认设置下,es每1秒钟将memory buffer中的数据refresh到Linux的File system cache,并清空memory buffer,此时写入的数据就可以被查询到了。
    但File system cache依然是内存数据,一旦断电,则File system cache中的数据全部丢失。默认设置下,es每30分钟调用fsync将File system cache中的数据flush到硬盘。因此需要通过translog来保证即使因为断电File system cache数据丢失,es重启后也能通过日志回放找回丢失的数据。

    translog默认设置下,每一个index、delete、update或bulk请求都会直接fsync写入硬盘。为了保证translog不丢失数据,在每一次请求之后执行fsync确实会带来一些性能问题。对于一些允许丢失几秒钟数据的场景下,可以通过设置index.translog.durability和index.translog.sync_interval参数让translog每隔一段时间才调用fsync将事务日志数据写入硬盘。

    解决
    对于需要写入后实时查询的数据,可以通过手动refresh操作将memory buffer的数据立即写入到File system cache。当然,该解决方案的代价就是降低了ES的写性能。

    1. 单个文档更新后立即refresh
    PUT /test/_doc/1?refresh
    {"test": "test"}
    PUT /test/_doc/2?refresh=true
    {"test": "test"} 
    
    1. refresh整个索引的memory buffer
    POST /test/_refresh
    

    python实现

    源码提供的方法支持refresh参数,默认False,可传True,wait_for。
    wait_for:只影响当前用户处理的请求,其他用户并发的操作并不影响;
    true:影响所有用户正在处理的请求,会更新所有分片,效率最低;
    false:更新数据之后不立刻刷新,在返回结果之后的某个时间点会自动刷新,也就是随机的;

    image.png
    delete_res  = es.delete(index=ind, doc_type=tp, id=idd, params={'refresh':'true'})
    

    实时性要求较高,牺牲效率满足。
    应用场景,根据自己项目需求来。

    相关文章

      网友评论

        本文标题:python-ES即时刷新file system cache

        本文链接:https://www.haomeiwen.com/subject/yuntzctx.html