ES里有一个叫作gateway的东西,今天抽空理一下,前面翻译ES的一篇博文叫作“搜索引擎与时间机器”,既然里面谈到了时间机器,就免不了须要穿越时空的的门咯,I guess,也许gateway这名字就是这么来的,其实在ES里面,gateway的主要职责是用来对数据进行长持久化(持久化了以后加上版本信息,不就能够自由的往还于过去将来之间了吗?),另外,整个集群重启以后能够经过gateway从新恢复数据。
因为ElasticSearch是专为分布式环境而设计的,因此怎么去对全部节点的索引信息进行持久化是个问题,除了索引信息以外,还有ClusterState(集群信息),mapping,索引碎片信息,以及transaction log等信息也是须要进行持久化的,0.11以后的版本新加了LocalGateway(而且是默认配置),加上以前的fs(使用共享文件系统)、hdfs(hadoop 分布式文件系统)、cloud(ec2之类的云存储),0.11以前默认的是None,也就是不进行持久化,这样的话若是服务器都挂了,就会形成数据丢失,local gateway这种模式顾名思义就是节点各自保存其状态,节点直接从本地存储来恢复节点状态和索引信息,localgateway有以下几个选项:node
gateway.recover_after_nodes: 1 (or gateway.recovery_after_master_nodes) gateway.recover_after_time: 5m (m分钟、s秒) gateway.expected_nodes: 2
当你的节点出现故障或者集群重启的时候,这些配置很重要,你应该尽可能保证有了足够多的节点来执行故障恢复,确保获得最终的集群状态,可能存放最新版本的状态信息的节点还未起来,不然可能会丢失数据。json
至于索引碎片的恢复则只需用达到足够恢复的数目便可,若是你没有设置备份,或者恰好某个碎片恰恰都丢了,那估计只能是没戏咯,服务器
另外,在个人测试中,2台机器,其中一台网络不稳定,常常断开,(ip冲突形成),形成集群中的节点各类为战,这里有一些参数可配:网络
discovery.zen.fd.connect_on_network_disconnect : true discovery.zen.initial_ping_timeout : 10s discovery.zen.fd.ping_interval : 2s discovery.zen.fd.ping_retries : 10
若是使用是共享文件系统的gateway,默认是每隔10s将数据异步的复制到共享的文件系统中(这是ES里一个叫gateway snapshot的概念),想一想若是集群很大,共享文件系统就须要保存很大的数据量,而且维护以及设备自己成本都很高,而使用local方式则能够作到各个节点自治,确实很方便啊。app
有关存储异步
说了这么半天,还有一个问题就是es工做的存储目录,具体来讲就是es服务的索引工做目录,gateway只是作持久化和恢复,不会直接使用,因此还有一个工做目录是用来查询操做的,具体来讲就是经过Store模块来完成的(es的每一个功能都是一个模块,结构很是好),es的存储设置是per index级别的,因此你能够为每一个index指定它存储的位置,既然持久化的工做已经完毕了,本地操做的索引通常只放在两个地方:内存和本地文件系统,主要是性能上考虑的,若是内存很大,那就所有放内存咯,值得一提的是,在ES里,全部存放work目录下(或内存)的东西假定能被丢失的和临时性的,另外你有多个副本存放在不一样的节点上,每一个索引又拆成了多个碎片位于不一样的节点上,假设一台节点上的数据丢了,那也只是整个索引少了其中的一个碎片的一个副本而已,而且es会立刻进行碎片的从新分配(allocate),确保数据的完整。jvm
还有一个重要特色就是es能够直接使用jvmheap以外的内存。
下面是一个配置inex使用内存来进行存储的例子(更多配置细节):elasticsearch
index : store: fs: memory: enabled: true
还有一个就是关于索引碎片数和副本数的配置问题,你不可以对已经存在的索引修改碎片数,也就是有了数据以后就不能修改了,由于目前es只是简单的哈希取模[hash(_id) MOD number_of_shards],若是之后支持一致性哈希,那就很好了,不过副本数目是能够随时动态更改的,若是你要对全局进行设置,参照以下:分布式
gateway: type: local index: gateawy: snapshot_interval: 30s number_of_shards: 3 number_of_replicas: 2 path: logs: /path/to/logs
新建立一个索引并设置:
PUT http://localhost:9200/myindex/oop
{ "index" : { "number_of_replicas" :3, "number_of_shards" :7 } }
动态设置索引副本数量:
PUT: http://localhost:9200/myindex/_settings
{ "index" : { "numberOfReplicas" :2 } }