美文网首页
Elasticsearch入门(三)—— 提高查询效率

Elasticsearch入门(三)—— 提高查询效率

作者: 樂浩beyond | 来源:发表于2020-02-23 22:07 被阅读0次

    数据写入过程

    image.png
    1. 数据写入到内存buffer
    2. 同时写入到数据到translog buffer,这是为了防止数据不会丢失
    3. 每隔1s数据从buffer中refresh到FileSystemCache中,生成segment文件,这是因为写入磁盘的过程相对耗时,借助FileSystemCache,一旦生成segment文件,就能通过索引查询到了
    4. refresh完,memory buffer就清空了, 但是translog并不会被清空。
    5. 每隔5s中,translog 从buffer flush到磁盘中(6.0开始每次请求translog都会落盘)
    6. 定期/定量从FileSystemCache中,结合translog内容flush index到磁盘中。做增量flush的。
    7. 当translog达到一定程度的时候会出发一次commit操作, 也叫flush操作(默认情况下30分钟或者512M执行一次flush)。可以用index.translog.flush_threshold_periodindex.translog.flush_threshold_size修改默认配置。
      commit(flush)程分为以下几步:
      7.1 Memory buffer清空并且Refresh
      7.2 调用fsync, 将FileSystemCache中的Segments写入磁盘
      7.3 清空删除translog重启一个新的translog

    ES利用这个commit point来决定哪些Segments属于当前shard。 Commit point和Segments的关系如下:


    image.png

    这里有两个知识点

    1、Buffer(缓冲区)是系统两端处理速度平衡(从长时间尺度上看)时使用的。它的引入是为了减小短期内突发I/O的影响,起到流量整形的作用。比如生产者——消费者问题,他们产生和消耗资源的速度大体接近,加一个buffer可以抵消掉资源刚产生/消耗时的突然变化。
    2、Cache(缓存)则是系统两端处理速度不匹配时的一种折衷策略。因为CPU和memory之间的速度差异越来越大,所以人们充分利用数据的局部性(locality)特征,通过使用存储系统分级(memory hierarchy)的策略来减小这种差异带来的影响。

    数据查找过程

    image.png

    1、Query阶段
    ⽤用户发出搜索请求到 ES 节点。节点收到请求 后, 会以 Coordinating 节点的身份,在 6 个 主副分⽚片中随机选择 3 个分片,发送查询请求。
    被选中的分⽚执⾏行查询,进行排序。然后,每 个分片都会返回 From + Size 个排序后的⽂文 档 Id 和排序值 给 Coordinating 节点。
    2、Fetch阶段
    Coordinating Node 会将 Query 阶段,从 从每个分⽚片获取的排序后的文档 Id 列表, 重新进行排序。选取 From 到 From + Size 个⽂文档的 Id。最后以 multi get 请求的⽅方式,到相应的分⽚片获 取详细的⽂文档数据

    提高读取效率

    杀手锏FileSystemCache

    根据之前数据写入过程分析我们可以看到,如果数据已经写入了Filesystem cache, 那么数据就能被搜索到了,所以如果给Filesystem cache更多的内存, 让内存容纳所有的Segment file索引文件, 性能会很高。有人做过测试,走磁盘的搜索性能是秒级的,纯走内存基本是毫秒级别,从几毫秒到几百毫秒不等。
    怎样才能尽量把数据都存在FileSystem cache里?可以采用ES+ Mysql/Hbase的架构。举个例子, 假如你有一行数据差不多有30个字段,如:id, name, age...。ES中仅仅存储用来检索的少数几个字段。其他字段都存在HBase中。从ES中根据name和age进行检索,拿到doc id, 然后根据doc id去Hbase中查询doc id对应的完整数据,返回给前端。写入ES的数据量最好小于等于Filesystem cache的内容容量。采用这种方式,从ES检索花费20ms, 去查询HBase花费30m,总共也就50ms, 相比于把1T数据都放在ES中检索花费5~10s, 性能提升很大

    数据预热

    虽然FileSystem cache是杀手锏,但是难免会有机器配置不高,ES的数据量还是远远大于Filesystem cache的情况, 这种情况下可以做数据预热。举个例子,对于电商平台来说,iphone是比较热门的商铺,可以自己搞一个后端程序,每隔一段时间访问一下iphone, 就能把数据刷到filesystem cache中。所以最好做一个专门的缓存预热子系统, 让数据进入到FileSystem cache中。

    冷热分离

    类似mysql的水平拆分,对于大量的访问频率比较少的数据,单独建一个索引存储,和热数据区分开。假设你有 6 台机器,2 个索引,一个放冷数据,一个放热数据。热数据可能就占总数据量的 10%,此时数据量很少,几乎全都保留在 filesystem cache 里面了,就可以确保热数据的访问性能是很高的。但是对于冷数据而言,是在别的 index 里的,跟热数据 index 不在相同的机器上,大家互相之间都没什么联系了。

    分页性能优化

    如果每页有10条数据,你现在要查询第100页,实际会把每个shard上存储的前1000条数据查到协调节点,有5个shard就有5000条数据,然后协调节点再进行合并处理,最终获得第100页的10条数据。可能翻到第10页就要5到10秒的时间了。

    • 和产品经理协商不允许深度翻页
    • 采用类似微博下拉加载新数据的交互,参考Scroll API

    数据建模

    提高写入效率

    客户端

    • 每个bulk请求体数据量不要太大,官方建议5-15MB
    • bulk请求超时时长可以大一点,建议60s
    • 写入端尽量将数据打到不同的节点

    服务端

    • 降低IO操作
    • 使用ES自动生成的文档ID,修改ES相关配置,比如提高Refresh inveral时间
    • 降低CPU和存储开销
    • 减少没有必要的分词,避免不必要的doc_values(可以节省磁盘空间), 文档字段每次写入的时候保证相同顺序,提高文档压缩率
    • 尽可能做到写入和分片的负载均衡
    • 调整Bulk线程池和队列

    Elasticsearch的默认配置不要盲目修改高质量的数据建模是关键

    关闭没必要的功能

    下面是设置mapping的例子

    {
        "english":{
            "_source": {
             "enabled": false
          },
           "properties": {
             "content":{
                "type":"text",
                "store":true,
                "index":false
            },
             "title":{
                 "type":"text",
                "store":true,
                "index":false
            }
          }
        }
    }
    

    1、只需要聚合不需要搜索, index设置成false,比如上面的titleindex
    2、不要对字符串使用默认的dynamic mapping, 比如text类型会默认额外生成keywords, 字符串数量过多时,会对性能产生影响
    3、index_options可以控制在创建倒排索引的时候,哪些内容可以被加入到倒排索引中,可以节省CPU
    4、关闭_source, 比如上面的english。这样可以减少IO操作,适合指标型数据

    针对性能的取舍

    如果追求极致的写入速度,可以牺牲数据可靠性和搜索的实时性换取性能。

    • 牺牲可靠性:将副本分片设置为0,写入完毕再调整回去
    • 牺牲搜索实时性:增加Refresh interval的时间
    • 牺牲可靠性:修改Translog的配置, 如下请求,可以增大间隔时间,同时改成了异步写的方式
    PUT /my_index/_settings
    {
        "index.translog.durability": "async",
        "index.translog.sync_interval": "60s"
    }
    

    下图是一个索引优化的例子


    image.png

    相关文章

      网友评论

          本文标题:Elasticsearch入门(三)—— 提高查询效率

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