概念
- 主节点: 一个集群中,必须要有一个主节点,一个主节点管理着新建或者删除索引和增加和删除节点等。主节点是不参与文档级别的变更和搜索的。
- 分片: 最小级别的工作单元,一个分片就是一个Lucene
- 索引: 用来指向一个或者多个分片
- 主分片: 每个文档只属于一个主分片,所以一个索引里的所有文档分散在不同的主分片上,由此可知,主分片才是限制数据存储的能力
- 复制分片: 主分片的副本,一般一个主分片至少一个副本,在多节点的情况下,单节点的情况下,复制分片可能不能使用
- 索引与分片: 一旦我们的索引建立,那么主分片就的数量就确定了,是不能修改的,但是复制分片是可以修改的,修改复制分片不能提高存储能力,只是降低了丢数据的风险
- 横向扩展: 当我们想扩容的时候,可以向集群中加入节点即可,然后增改主分片数。以前创建的索引已经分配过分片数,此时扩容后,主分片数是不能改变的。
- 平衡负载: 分片会在不同节点上自动进行调整的,尽量会让所有的节点都均匀的分配分片
/索引
查看该索引信息
我们可以通过直接请求索引的方式来查看,例如:GET /megacorp
....
"settings": {
"index": {
"creation_date": "1522479960689",
"number_of_shards": "5",
"number_of_replicas": "1",
"uuid": "QjN3Rv5rQOex_E5V_y-bpQ",
"version": {
"created": "6020299"
},
"provided_name": "megacorp"
}
}
这里我们重点关注两个参数:
-
number_of_shards
: 主分片数,上面表示有5个主分片 -
number_of_replicas
: 复制分片数,上面的数字是1,表示每个主分片有1个分片,也就是说复制分片总共有 5*1=5,5片
集群部署
步骤(打开config/elasticsearch.yml文件):
-
cluster.name
: 集群中的节点,保持该属性名一样 -
node.name
: 修改该属性跟其他节点不一样 -
http.port
: 修改该端口,注意:9200是默认端口,一般是提供服务的端口。我们同时对应的是es内部服务之间也有一个端口是9300,这个端口每次会去检测是否被占用过,有被占用,就会自动++1直到能够可用 -
network.host: 0.0.0.0
: 打开这个设置,否则会导致远程无法访问,只能本地访问,一般会关闭这个访问,只能局域网内部访问 -
discovery.zen.ping.unicast.hosts
: 设置自己集群主机地址,如:discovery.zen.ping.unicast.hosts: ["103.6.222.47", "103.6.222.41"]
注意:
- 我们每次向集群中加入新的节点的时候,一定要是一个干净的es,否则残留的数据导致加入集群失败。
- 物理机上一定要开放9200以及9300,还有多的节点第二个端口是默认加1来增加,这里就会是9301.
处理冲突
在关系性数据中,我们经常会用一些各种锁来保障数据的冲突问题,es一般用查询,更新操作很少,所以大部分情况下,不会有冲突问题,但是在一个极端的使用情况下依然会出现冲突。es采用的是乐观并发控制。
- 悲观并发控制:用户在读取的数据时候就锁定数据,然后紧接着更新依然是同一个线程,线程安全,数据也是安全的,不会出现冲突问题。(悲观:生怕数据被其他的线程改动,所以读的时候就锁住该行记录)
- 乐观并发控制:用户在读取的时候不锁定该表,只有更新的时候锁定,但是在真正更新的时候,会先比较数据跟之前读取的数据是否一样,如果不一样的话就直接更新失败。更新失败就需要程序自己来做错误处理,或者回滚操作。(乐观:认为没有人恰好更新这条记录,就不用管,等到有冲突就直接失败)
乐观并发控制例子
-
增加数据
PUT /website/blog/1 { "title": "Java demo", "text": """Sout("HelloWorl");""" }
-
更新数据,指定只有
_version
为1的时候就更新,否则不更新PUT /website/blog/1?version=1 { "title": "Java demo", "text": """Sout("HelloWorld dsdsd");""" }
会发现上面的更新是成功的,返回结果为:
{ "_index": "website", "_type": "blog", "_id": "1", "_version": 2, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 2, "_primary_term": 1 }
此时我们仔细观察,
_version
会发生变化,增加到了2。 -
继续以
_version
为1来进行更新,发现更新报错。所以这里就是采用乐观锁,在更新的时候,比较下之前读取的 version和更新时候的_version
是否一样。
网友评论