es 3期 第18节-分页查询使用避坑的一些事
#### 1.Elasticsearch是数据库,不是普通的Java应用程序,传统数据库需要的硬件资源同样需要,提升性能最有效的就是升级硬件。
#### 2.Elasticsearch是文档型数据库,不是关系型数据库,不具备严格的ACID事务特性,任何企图直接替代严格事务性场景的应用项目都会失败!!!
##### 索引字段与属性都属于静态设置,若后期变更历史数据需要重建索引才可生效
##### 对历史数据无效!!!!
##### 一定要重建索引!!!!
### 1、分页查询原理概要
## 分页查询需求
# 分页需求海量数据:动辄数据量千万级别、亿级别,无法在一页内展示
# 数据排序:查询数据需要排序,按顺序展示
## 分页查询过程
# 按条件扫描数据
# 按条件排列数据
# 取回数据
## ES分片查询阶段
# ES是分布式的,相比传统数据库多了分片机制,查询一次,要查询多个分片;
# 分页查询相比传统数据库增加了复杂度。
## ES分片合并阶段
# 服务端协调节点从各分片取回数据ID按照条件排序合并得到最终的数据ID列表
## 分页查询问题
# 分页查询大小,决定了查询的响应
# 分页查询深度,决定了查询的效率
# 分页查询体验,决定了鱼与熊掌兼得
## 查询便利
# 查询优点
# 查询数据时,可同时返回数据量总条数与分页的明细数据;避免了传统数据库查询2次的问题,大大提升了查询效率
## 数据准备
POST _reindex
{
"source": {
"index": "kibana_sample_data_logs"
},
"dest": {
"index": "kibana_sample_data_logs_page"
}
}
## From Size查询
# 起始页查询介绍
# from:设定起始数据位置
# size:设定单页数据量大小
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":10,
"size":20
}
## 查询限制
# 查询窗口大小限制
# From+size<=10000,默认不能超过此值,es的安全限制,会报错
# Window=10000,重排序窗口不能超过此值
# 查询超过10000的语句,报错
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":10000,
"size":20
}
## 但是实际场景中还是会有深分页需求,可以通过修改配置实现
# 修改索引配置
PUT kibana_sample_data_logs_page/_settings
{
"index":{
"max_result_window":20000
}
}
# 再次查询,不报错了
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":10000,
"size":20
}
## 单页大小设置
# 单页大小
# Size设置多大合适,不同的大小性能不一
# _source控制在1kb以内
# 每次查询返回数据控制在1M以内
# 尽量不要深分页和大页数
# 分片数也不要过多,请求会分发到所有分片在做聚合
### 3、Search After查询实战
## 参照点分页查询
# 概念介绍
# Search after,基于排序字段,查询下一页,基于上一页最后一条数据的排序字段值,作为参照可以保证数据查询量大大减少
## 注意事项
# 1.分页会导致数据跳跃
# 2.数据新增或者变更refresh造成错误
# 查询根据timestamp 倒序,使用的数据离散度要高,否则容易跳页
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":0,
"size":20,
"query":{
"match_all": {}
},
"sort":{
"timestamp":{
"order":"desc"
}
}
}
# 跳过第一条数据的sort值,原第二条数据变成了现在的第一条
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":0,
"size":20,
"query":{
"match_all": {}
},
"sort":{
"timestamp":{
"order":"desc"
}
},
// 跳过第一条数据的sort值
"search_after":[
"1721339126749"
]
}
# 查询数据离散度低的排序跳页
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":0,
"size":20,
"query":{
"term": {
"response": {
"value": "200"
}
}
}
}
# 跳过200没有数据了
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":0,
"size":20,
"query":{
"match_all": {}
},
"sort":[{
"response":{
"order":"desc"
}
}
],
// 跳过第一条数据的sort值
"search_after":[
"200"
]
}
# 可以使用多个字段排序,方式跳页
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":0,
"size":20,
"query":{
"match_all": {}
},
"sort":[{
"response":{
"order":"desc"
}
},
{
"timestamp":{
"order":"desc"
}
}
],
// 跳过第一条数据的sort值
"search_after":[
"200","1721339126749"
]
}
## search_after 与 from 一起使用会报错,不支持
GET kibana_sample_data_logs_page/_search
{
"track_total_hits":true,
"from":10,
"size":20,
"query":{
"match_all": {}
},
"sort":[{
"response":{
"order":"desc"
}
}
],
// 跳过第一条数据的sort值
"search_after":[
"200"
]
}
### 4、Point in time查询实战
## Point in time查询
# 概念介绍
# Search after,基于排序字段,查询下一页,基于上一页最后一条数据的排序字段值,作为参照,可以保证数据查询量大大减少
# 注意事项
# 1.分页会导致数据跳跃
# 2.数据新增或者变更refresh造成错误
# 业务上数据是在不停的新增的,找不到原来的数据,这里相当于一个快照
# 生成分钟的快照
POST kibana_sample_data_logs_page/_pit?keep_alive=1m
# 使用pit id查询,不能显示的指定索引名称,因为pit中带了索引信息
GET _search
{
"track_total_hits":true,
"from":10,
"size":20,
"query":{
"match_all": {}
},
"pit":{
"id": "i_vrAwEca2liYW5hX3NhbXBsZV9kYXRhX2xvZ3NfcGFnZRZ0MnRXYnZrc1RacWdoUjJBWFdpazJ3ABZDZnVtY0x0QlI0Ry13VUNoZ3BwOU53AAAAAAAABazOFkNtYjBkU0E5VGF5Q3hBOFJuMHh6QVEAARZ0MnRXYnZrc1RacWdoUjJBWFdpazJ3AAA="
},
"sort":[
{
"timestamp":{
"order":"desc"
}
}
]
}
### 5、Search Scroll 查询实战
## scroll快照查询
# 概念解释
# 快照查询基于缓存机制,将查询的所有数据ID缓存起来,下次查询,从缓存中直接找寻,避免重复执行查询,是目前业界做深度查询最佳的方式;
# 注意事项
# 局限性也明显,实时性支持弱;
# 不支持修改页数,不支持跳页
# 占用内存,使用完要清理掉
# 查询条件,并生成1分钟的快照
# 同时预设查询条数和条件
POST kibana_sample_data_logs_page/_search?scroll=1m
{
"track_total_hits":true,
// 预设每次查100条
"size":100,
// 预设查询条件
"query":{
"term": {
"response": {
"value": "503"
}
}
}
}
# 使用scroll id查询,不能显示的指定索引名称,因为scroll id中带了索引信息和条件
# 数据一共有441条,查询5次就没结果了
GET _search/scroll
{
"scroll_id":"FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkNtYjBkU0E5VGF5Q3hBOFJuMHh6QVEAAAAAAAY4TRZDZnVtY0x0QlI0Ry13VUNoZ3BwOU53",
"scroll":"1m"
}
### 6、分页查询建议与经验分享
# 技术尽量满足业务需求
# 技术不能无限制满足业务
# 平衡业务与技术
# 深度翻页真的需要这么多吗?有十万条数据的时候,真是场景下用户不会每页100条翻到最后一页
# 分页性能问题?from和size,size大了性能就不会高,数据量大了从es取出来快,但是带宽不行
# 查询DSL语法
# https://www.elastic.co/guide/en/elasticsearch/reference/7.11/search-search.html
# 分⻚查询
# https://www.elastic.co/guide/en/elasticsearch/reference/7.11/paginate-search-results.html
# scroll-api
# https://www.elastic.co/guide/en/elasticsearch/reference/7.11/scroll-api.html
# point-in-time-api
# https://www.elastic.co/guide/en/elasticsearch/reference/7.11/point-in-time-api.html
# # time-units 时间参数
# https://www.elastic.co/guide/en/elasticsearch/reference/7.11/common-options.html#time-units