目标:如何设置elasticsearch集群、节点和分片,方便以后的集群扩展,保障硬件损坏下的数据安全?
一:概念:
空集群:一个只有一个空节点的集群
节点:一个elasticsearch运行实例
集群:由一个或多个具有相同的cluster.name属性节点组成
主节点:管理集群变化。例如创建和删除一个索引,添加和移除node
二:
每个节点了解文档存储在位置,将请求直接发送到我们感兴趣的数据节点;由对话节点负责收集结果并返回最终结果到客户端;
集群健康检查:
GET /_cluster/health
状态:
green:主要和复制分片活动状态
yellow:主要和复制分片活动状态,但不是所有复制分片都处于活动状态
red: 没有主要分片处于活动状态
新增Index:
先决条件:存储相关数据的位置,Index只是一个逻辑名称空间,用来指向一个或多个物理分片
概念:
分片(shards):低级别的工作单元,保持Index中所有数据切,只是一个Lucene实例;应用直接对话Index而不是分片
Index中每个document属于某个primary shard,所以primary shards的数量决定了Index可以存储数据的最大值;
replica shard只是primary shard的复制,提供冗余备份,提供搜索和检索document的服务;
案例:
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
primary shards的默认值是5;
数据in, 数据out:
相同类型的实体存在差异,当处理这些差异数据的时候带来了困难:
面向对象编程的好处:可以处理潜在的复杂数据结构。
概念:
对象:特定语言,在内存的数据结构;
网络传输问题:
通过标准的格式展现数据。JSON一个理想的数据结构;
Elasticsearch是分布式文档存储器,通过JSON document数据结构实现复杂数据的存储和检查;
每个field中的所有数据默认被index,每个field都有相应的方向的Index,实现快速检索。
document APIs:
创建:
创建
index APIs:
PUT /{index}/{type}/{id}
{
"field" : "value",
}
每个Document有一个version数值,每次对Document的修改都导致version增加。
自动生成ID:
如果不特别执行id,则Elasticsearch为Document自动生成一个ID,请求由PUT变成POST请求
POST /website/blog/
{
"title": "My Second blog entry",
"text": "Still trying this out...",
"date": "2016/01/10"
}
检索:
针对单个document的检索:
GET /website/blog/123?pretty
应答中的found字段值为true,表示document被找到,false表示document不存在;
检索document的局部内容:
GET /website/blog/125?_source=title,text
不返回document元信息的检索
GET /website/blog/123/_source
检索多个Documents
get /_mget
{
"docs" : {
{
"_index" : "website",
"_type" : "blog",
"_id" : 2
},
{
"_index" : "website",
"_type" : "pageviews",
"_id" : 1
"_source": "views"
}
}
}
如果检索的多个document在相同的_index下的简洁写法:/_index或/_index/_type
// 相同的_index
GET /website/blog/_mget
{
"docs" : [
{"_id" : 2},
{"_type" : "pageviews", "_id": 1}
]
}
//相同的_index和_type
GET /website/blog/_mget
{
"ids" : ["1", "2"]
}
更新:
更新整个document
PUT /website/blog/123
// 更新的内容
{
"title": "My first blog entry",
"text": "Sticky to the technology",
"date": "2018/10/09"
}
应答中_version的值发生改变,Elasticsearch的内部机制是删除老的document,新增新的document,
但不是立即删除,即使你再也无法访问它了。Elasticsearch在后台进行删除操作
更新document局部内容
POST /website/blog/123/_update
{
"doc": {
"views": 0,
"tags" : ["testing"]
}
}
使用脚本更新
POST /website/blog/1/_update
{
"script": "ctx._source.view+=1"
}
POST /website/blog/1_update
{
"script" : {
"lang" : "painless",
"inline" : "ctx._source.tags.add(params.tags)",
"params": {
"tags" : "search"
}
}
}
根据条件进行操作
POST /website/blog/1/_update
{
"script" : "ctx.op = ctx._source.views == count" ? 'delete' : 'none'",
"params": {
"count": 1
}
}
更新时存在冲突:
POST /website/pageviews/1/_update?retry_on_conflict=5
{
"script": "ctx._source.views+=1",
"upsert": {
"views" : 0
}
}
retry_on_conflict参数指定失败重试次数;
新建一个新的Document
如果确认当在Index文档中时候?到底是更新了文档还是覆盖存在的文档
(1)使用elasticsearch自生成的ID,
(2)处理已经存在的id情况:
一: 通过op_type参数指定
PUT /website/blog/123?_op_type=create
{ ... }
二:在URL的最后使用/_create
PUT /website/blog/123/_create
{ ... }
通过response code值确定操作是否成功, 201 Created表示创建成功,status字段值为409表示失败
删除:
DELETE /website/blog/123
Document:
概念:
Document: key-value数据,key式属性,value可以是字符串、数组、布尔类型和其他对象,数组类型以及其他的
特殊类型;
object:JSON对象;
Document:被序列化成JSON,并由唯一的ID的根对象
Document元数据:
_index: document存储位置
_type: document代表的对象的类型
_id: 唯一标识
Index是document的集合,按照相同的原因被圈在一起。Index的命名必须小写,不能以下划线开始,不包含逗号。
在Index中的数据松散聚合,文档共享schema.
解决冲突:
不同人同时对document进行更改,导致数据丢失问题?
(2)悲观锁
_version的作用:解决冲突,elasticsearch确保按照正确的顺序改变,如果一个老的版本在新的版本后到来,则
被忽略,
PUT /website/blog/1?version=1
批量处理:
Bulk API允许一个步骤内执行多个请求,例如create, index, update, delete.
格式:
{action: {metadata}} \n
{request body} \n
{action: {metadata}} \n
{request body} \n
每行必须以\n结束,禁止包含非转义的换行符。
action/metadata 中定义将对document执行的动作
action包含如下:
create
index
update
delete
metadata包含_index, _type, _id
案例:
{"delete" : {"_index" : "website", "_type": "blog", "_id": "123" }}
request body由_source组成(字段名和值等)
{"create": {"_index": "website", "_type" : "blog", "_id" : "123"}}
{"title": "My first blog post" }
完整案例:
POST /_bulk
{ "delete": {"_index": "website", "_type": "blog", "_id": "123"}}
{"create" : {"_index" : "website", "_type": "blog", "_id": "123"}}
{"title" : "My first blog post"}
{"index" : {"_index": "website", "_type": "blog"}}
{"title" : "My second blog post"}
{"update" : {"_index" : "website", "_type" : "blog", "_id" : "124", "_retry_on_conflict": 3}}
{"doc" : {"title" : "My updated blog post"}}
bulk请求需要装载节点到内存,如果请求太大,处理其他请求的空间变少,
bulk的最优大小:根据硬件条件调整,没有一个固定值,1000到5000文档大小;
分布式Document存储:
路由文档到分片:
如何确认document属于哪个分片?如何确认是否存储在分片1还是分片2上;
shard = hash(routing) % number_of_primary_shards
routing是一个任意字符传,默认是document的ID,但允许其他来源
解释了为什么在primary shard数值只能在创建index的时候指定,并不允许更改;
所有的Document API可接收routing擦书。
Primary和Replica分片如何交互:
master节点根据id定位document存储在shard 0上,shard0在节点3上,,请求被转发到节点2上,则节点3在priamry shard执行request,如果操作成功,则将请求转发到备份节点1和2上,一旦节点1和2报告操作执行成功,节点3
将master节点报告,再由master节点返回给客户端
可选参数:
consistency: 默认情况下,primary分片需要达到法定人数以确保系统的可用性,这样确保数据不会被写道网络分区
错误的一边
法定人数计算公式:
int ((primary + number_of_replica)/2) + 1
对于consistency的允许的值是one,all或者默认的法定人数,
timeout:
如果发生可用的分片拷贝不足,Elasticsearch处于等待状态,默认的时间是1分钟;
如果你需要,可用将timeout参数设置更短,如30s