【现象】
3月1日10:02、10:52用户反馈部分查询变慢,超过预设超时时间(6000 ms)
【排查进展】
- refresh queue增长到619,原因待分析
- Cpu load明显增高,达到10/16(load值/核数,未达到理论瓶颈)
- Io明显增高,达到600(未达到理论瓶颈)
- Search queue明显增高,达到10(未达到理论瓶颈)
- 用户反馈业务量由平时每分钟3.5万左右增长到每分钟7万左右
【可能原因分析(非最终结论)】
业务查询语句中涉及到检索和排序,通过监控看到索引每秒有大约100左右的文档写入,会潜在更新每个分片中的segment,进而需要频繁读取段文件来更新排序树,内存有限的情况下,就会引起磁盘io增大,因此cpu和load都会增高,随着查询流量增高(达到1166 qps,几乎比正常流量翻一番),可能会出现部分查询耗时较长情况。
【短期解决方案】
- 扩展CPU,提高集群整体算力(由于集群所在基础设施资源不足,暂时未完成)
- 扩展内存,尽可能降低磁盘io(已完成)
【3月2日排查方向建议】
- 紧跟开发同事反馈,同时密切观察集群级和节点级相关指标,例如cpu load、search queue、磁盘io等
- 当负载较高或者用户反馈存在超时现象时,查看慢查语句,同时针对DSL进行profile分析,定位耗时根因;结合jstack、arthas分析高耗或等待的线程,进一步确定资源瓶颈点
【后续可以考虑的优化点】
- 针对排序的优化:index sorting实现写入预排序,提高包含排序的并发查询效率
- 其他优化点待分析
一、集群层面
GET _all 查询集群所有信息
GET _search 查询集群中所有documents
GET _cat/count 查询集群documents数量
GET _cat/indices?v&pretty 查询集群中存在的所有索引
GET /index 查询某个索引
DELETE /index 删除单个索引
DELETE /index1,index2或index* 删除多个索引
DELETE /_all或DELETE /* 删除所有索引
二、索引层面
GET index/…
GET index/_mapping
GET index/type/_mapping
GET index/type/_search 查询该索引中所有documents
GET index/type/_count 查询该索引中documents数量
GET index/type/_mapping 查询该索引各个字段的数据类型
GET index/type/id 查询某条特定的document
GET index/type/id?routing=rid 查询某条特定的document,带路由规则
查询所有文档
POST index/type/_search
{
“query”: {
“match_all”: {}
}
}
删除所有文档
DELETE index/type/_delete_by_query
{
“query”: {
“match_all”: {}
}
}
三、query-context通用非结构化子查询
查询匹配单个字段值的文档
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”:{
“match”:{
“trx_nbr”:“123456”
}
}
}
查询匹配多个字段值的文档
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”:{
“multi_match”:{
“query”: “人民币”,
“fields”:[“fuzzy_search”,“fuzzy_search2”]
}
}
}
查询匹配习语的文档
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”:{
“match_phrase”:{
“fuzzy_search”:“人民币 手机银行”
}
}
}
语法查询,AND OR NOT
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“query_string”: {
“query”: “人民币 AND (0131 OR 555)”
}
}
}
语法查询多字段
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“query_string”:{
“query”: “(人民币 AND 本人资金往来)”,
“fields”: [“fuzzy_search”,“fuzzy_search2”]
}
}
}
四、query-context通用结构化子查询
特定字段进行查询
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“term”:{
“trx_nbr”:“C911338448501”
}
}
}
范围查询
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“range”:{
“trx_tim”:{
“gte”: “2019-04-19 00:00:00”,
“lte”: “2019-04-19 14:19:03”
}
}
}
}
五、filter-context通用子查询
过滤出某个字段的值
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“bool”:{
“filter”:{
“term”: {
“crd_nbr”: “1111111111111111”
}
}
}
}
}
布尔计算查询should,must,must_not
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“bool”:{
“should”:[{
“match”: {
“crd_nbr”: “111111111111111”
}
},{
“match”: {
“trx_nbr”:“C911338448501”
}
}]
}
}
}
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“bool”:{
“must_not”:[{
“term”: {
“crd_nbr”: “111111111111111”
}
}]
}
}
}
六、组合查询
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“query”: {
“bool”:{
“should”:[{
“match”: {
“crd_nbr”: “111111111111111”
}
},{
“match”: {
“trx_nbr”:“C911338448501”
}
}]
, “filter”: [
{
“term”: {
“usr_id”: “012377316192”
}
}
]
}
},
“_source”: [“usr_id”,“fuzzy_search”,“trx_tim”],
“size”: 20,
“from”: 0,
“sort”: [
{
“trx_tim”: {
“order”: “desc”
}
}
]
}
七、聚合查询
分组计数:
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“aggs”: {
“group_by_usr_id”: {
“terms”: {
“field”: “usr_id”
}
},
“group_by_dat_mon”: {
“terms”: {
“field”: “dat_mon”
}
}
}
}
统计:stats,min,max,avg,sum
POST szjy_lst_dtl_wrt/szjy_lst_dtl_wrt/_search
{
“aggs”: {
“grades_rmb_amt”: {
“stats”: {
“field”: “rmb_amt”
}
}
}
}
代码优化:
terms 应该改成should filter term