ES 各数据量的查询耗时与大数据量分索引方案

在新的客户搜索改版时,我们把es从1.7的版本升级到了5.4 ,并打算采用ssd的硬盘,为了看效果,我们测试了es的性能,从而来考量新的ES数据该如何存储,现在常用的一个索引总数据已经达到20亿的体量,在业务数据还不断增长的情况下,我们该如何重构。每个公司的业务不一样,就会采用不同的技术方案,这篇文章肯定不适合所有的公司,只是希望能给大家带来启发,大概讲下我们的业务,用来理解下文,我们有很多店铺,每个店铺有很多的用户,有的店铺发展很好,如逻辑思维,他就有很多的用户,有的发展不好,它这个店铺下的数据就很少,所以按店铺纬度的数据量并不平衡,我们的业务都是按店铺来查询,而新的索引就是以店铺纬度一对多的数据存储,一个businessId对应多个customerId这样一条一条的数据。

一开始测试我们使用es默认的配置 一个索引 5个shard,导入了8亿条数据,hit(影响行数)在2亿的语句平均响应时间 在4秒左右,这个肯定不行,测试姿势也不太对,线上真实的大店铺在几千万级别的,于是还是考虑分索引的方案,什么是分索引,分索引就像mysql的cobar 用一定的hash规则分库一样,但是对外暴露还是一个索引名称,于是我们打算分100个索引,并且对数据落盘的hash规则进行了优化,让数据尽量平衡分散,不能一个索引几千万,另外一个几十万,一个搜索过来后分别会在不同的索引查询,最后再聚合数据,原理用es的别名,最后测试结果也比较喜人。

索引状况:分了100个索引 ,索引入库算法: 索引名称 + ((business_id + murmur3_32(customer_id) % 3) % 100) ,这个算法只是适合我们公司的业务,这样一个店铺下的客户平均分散到3个索引内。于此同时需要设置别名,一个别名对应三个索引,别名算法列子:scrm_customer_new_par_1 ,1就是 bid % 100 = 1 ,对应上面三个索引名称。
未聚合前查询:3000
万的数据直接调用es 接口的话 hit 1000万的数据 首次查询耗时 300毫秒平均耗时130毫秒,现在一个businessid大号是分到3个索引内的所以3000万的量分到一个索引内 hit只有1000

聚合后查询:可以直接让es聚合,一个别名对应三个索引,别名算法列子:scrm_customer_new_par_1 ,后面的1就是 bid % 100 = 1 ,聚合后 3000万的量 首次500毫秒平均190毫秒,为什么会有首次查询与多次查询的区别,因为在语句上我们进行了filter的优化,filter语句es会走缓存。
测试语句如下:

{
   "query": {
      "bool": {
         "filter": {
            "bool": {
               "must": [
                  {
                     "term": {
                        "business_id": 123423
                     }
                  },
                  {
                     "exists": {
                        "field": "card_ids"
                     }
                  }
               ]
            }
         },
         "must_not": [
            {
               "bool": {
                  "must": [
                     {
                        "term": {
                           "is_member": 0
                        }
                     },
                     {
                        "term": {
                           "points": 0
                        }
                     },
                     {
                        "term": {
                           "total_trade_count": 0
                        }
                     },
                     {
                        "term": {
                           "mobile": ""
                        }
                     }
                  ],
                  "must_not": [
                     {
                        "range": {
                           "nickname": {
                              "from": ""
                           }
                        }
                     }
                  ]
               }
            }
         ]
      }
   },
   "sort": [
      {
         "be_customer_time": {
            "order": "desc"
         }
      }
   ],
   "from": 0,
   "size": 20,
   "_source": []
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注