数据写入过程:




 


es数据写入、删除和更新_海量数据


写入过程


注:一个数据不会写入多个主分片




 


es数据写入、删除和更新_商业_02


底层逻辑


注:数据先写入Buffer,同时写入Translog(用于极端情况下的数据恢复),Buffer缓存数据达到阈值会批量刷到磁盘(中间有个文件系统缓冲),所以说es的数据写入是一个近实时的(存才延时默认是1秒)

单条写入put/post:

1、put,需要设定数据ID(同一条数据首次插入是created,再次插入会updated)

2、post,可选择设定数据ID(不指定id情况下:同一条数据首次插入是created,再次插入还是created,但_id会变;指定id若id不变第二次插入失败)

_doc:同一条数据首次插入是created,再次插入会updated

_create:同一条数据首次插入是created,再次插入会报错



PUT compyan-starff-001/_doc/1
{
...
}
PUT compyan-starff-001/_create/1
{
...
}


result,created/updated,新增或更新

req请求参数解读:

op_type,操作类型

refresh,刷新策略



PUT compyan-starff-001/_doc/1?routing=1 #路由到第一个主分片
{
...
}


routing,路由策略

Wait_for_active_shards,等待写入分片数量



GET company-staff-001/_doc/1  #通过这种方式可以立即获取到插入的数据,因为这种GET方式会直接
#从Buffer中回去数据(实时)
GET company-staff-001/_search?routing=1 #_search需要路由到指定的分段从磁盘中获取数据(这种是非实时)
#PUT数据时可以通过&refresh=true强制实时(也是近实时)


批量写入_bulk:



POST _bulk
{index:{"_index":"company-staff-001", "_id": "1"}}
...
{index:{"_index":"company-staff-001", "_id": "2"}}
...
{index:{"_index":"company-staff-001", "_id": "3"}}
...


数据删除:

删除的路由机制和写入的路由机制相同




 


es数据写入、删除和更新_版本号_03


删除内部机制



DELETE company-staff-001/_doc/1
#如插入数据时_version为1,删除是版本号为_version为2,原因:标记删除先更新了数据版本发生变化,默认情况编辑删除的数据能保存24小时


条件删除:_delete_by_query



POST kibana_sample_data_logs_delete/_delete_by_query?requests_per_second
{
"slice":{ #手动分片删除
"id":1, #两次删除需要修改id
"max":2 #分为两批次删除
}
"query": {
"match_all": {}
}
}



POST kibana_sample_data_logs_delete/_delete_by_query?slice=2&scroll_size=1000&requests_per_second=100    
#自动分片删除,最大的片数不能超过自己的分片数


requests_per_second:每秒删除多少条数据

注:一般需要加上requests_per_second来控制删除;若不加,在条件删除海量数据时,可能执行时间比较长,造成es瞬间io巨大,属于危险操作

scroll_size:每次从es遍历多少条数据存储到Buffer中

requests_per_second:每秒多少条



GET _cat/tasks  #查询所有任务
GET _tasks?detailed=true&actions=*/delete/byquery #查询上面的删除任务


批量删除:



POST _bulk?refresh=true  #刷新
{"delete":{"_index":"company-staff-001", "_id":"1"}}
{"delete":{"_index":"company-staff-001", "_id":"2"}}
{"delete":{"_index":"company-staff-001", "_id":"3"}}


mysql数据库批量导入数据到es可以使用logstash,原理就是使用了"_bulk"命令

思考:批量输出数据,当数据量过大时,不如直接删除索引,再重新导入数据

更新

1、全量更新



#第二次put会全量更新
POST compyan-starff-001/_doc/1
{
...
}


2、局部更新



POST compyan-starff-001/_update/1
{
"_doc":{
"companyName":"xx公司"
}
#重要:false当id为1的记录不存在时会更新报错,true当id为1的记录不存在时会创建索引并插入记录
"doc_as_upset":true
}


3、脚本更新



只更新记录中companyName字段内容
POST compyan-starff-001/_update/1?refresh=true
{
"script":{
"source":"""
ctx._source. companyName="aaa公司";
""",
"lang":"painless",
"params":{}
}
}

POST compyan-starff-001/_update/1?refresh=true
{
"script":{
"source":"""
ctx._source. companyName=params.cName;
""",
"lang":"painless",
"params":{
"cName":"aaa公司"
}
}
}

POST compyan-starff-001/_update/1?refresh=true
{
"upsert":{
"companyName"="aaa公司"
}
}


批量更新_bulk:



POST _bulk?refresh=true
{"upadte":{"_index":"compyan-starff-001","_id":"1"}}
{"_doc":{"compaynId":"2020","userId":"1234"}}
{"upadte":{"_index":"compyan-starff-001","_id":"2"}}
{"_doc":{"compaynId":"2021","userId":"12345"}}
{"upadte":{"_index":"compyan-starff-001","_id":"3"}}
{"_doc":{"compaynId":"2022","userId":"123456"}}


"result":"noop"表示跟进前后数据相同,es没有做操作,(es会先做检查)

"_version"当更新不成功时,版本号依然会加1,若要指定版本号,可以外部设置,但是版本号必须必目前版本号大,否则报错

条件更新:

"_update_by_query"和条件删除类似



作者:奋斗的韭菜汪