elasticsearch

more usable articles:1. http://www.elasticsearch.org/blog/
2. http://www.elasticsearch.org/guide/ all the sub links
3. http://log.medcl.net/item/tag/die/

from: http://log.medcl.net/item/2010/09/translation-search-engine-and-the-time-machine/

link:http://www.elasticsearch.com/blog/2010/02/16/searchengine_time_machine.html
构建一个高可用的产品需要一些创新的想法,当我们谈论一个高可用的产品的时候,我们一般会从两个方面去衡量,一个是部分集群的故障处理(其中包括如何做到加新节点自动扩展),还一个就是整个集群都出故障都down掉情况的处理(怎样保证整个系统可以重新跑起来,恢复到down掉之前的状态,并且还不能丢失数据)。
接下来将要说说一个分布式系统(尤其是在云计算环境里)是如何解决上面提到的那两个问题的以及ElasticSearch是怎么做的。
部分群集故障  partial cluster failure

部分群集故障就是说一个集群里面的一个或多个节点down掉了(这个貌似很常见啊),而我们的分布式系统应该能够保证我们的数据不能丢,并且当这种情况发生的时候,要保证脸不红心不跳,习以为然,因为这种事情是经常会发生的,尤其是在云端,一旦你服务器里的某台机器(不管好坏)已经不听使唤了,那么是不是意味着上面的那些数据节点已经不受你控制了呢,基本上来说就是他们想干嘛干嘛,已经没你什么事了。诸如一些NB的云计算提供商都会搞出一些创新的新想法,如亚马逊的spot instances(现买现卖),计算能力也可以搞拍卖。
这里有一个关于节点状态和存到哪里的问题,当节点状态保持到本地时,就是说如果你的节点down了,也就是说你丢失了这个节点的数据,还有一点非常重要的就是,不管是什么系统本地存储(包括本地文件系统、内存)永远要比网络存储快(如NFS),同样,当不只一个节点需要去访问同一个共享状态的时候,一般来说我们需要锁的机制来保证数据的一致性,但是这又会影响我们系统的可伸缩性。
最通用的解放方案就是对失败节点的数据进行复制,通过控制复制的份数可以保证集群有很高的可用性,复制这个方案的精髓主要是保证操作的时候没有单点,对一个节点的操作会同步到其他的复制节点上去。
以ElasticSearch为例,一个索引会拆分成多个碎片,每个碎片可以拥有一个或多个副本(创建索引的时候可以配置),这里有个例子,每个索引分成3个碎片,每个碎片有2个副本:

$ curl -XPUT http://localhost:9200/twitter/ -d '
index :
    number_of_shards : 3
    number_of_replicas : 2
'

每个操作会自动路由主碎片所在的节点,在上面执行操作,并且同步到其他复制节点,通过使用“non blocking IO”模式所有复制的操作都是并行执行的,也就是说如果你的节点的副本越多,你网络上的流量消耗也会越大。
复制节点同样接受来自外面的读操作,意义就是你的复制节点越多,你的索引的可用性就越强,对搜索的可伸缩行就更好,能够承载更多的操作!
一旦我们工作在假定所有的节点都是不可靠的前提下,也就意味着我们可以让我们的索引保存在更快的介质上,本地文件系统,或是ssd,更可以是内存(堆里面、堆外面、本地内存)都可以,并且ElasticSearch里索引的存储也是可以配置的:

$ curl -XPUT http://localhost:9200/twitter/ -d '
index :
    store:
        type : memory
'

但是,如果我们的节点的存储只是瞬时的,那我们还考虑索引的长期持久化干嘛?答案请看后面。
整个集群故障/长持久化 Full Cluster Failure / Long Term Persistency
处理整个集群的故障失败与整个集群的关闭意味着整个集群的状态(以elasticsearch为例,那些索引被创建了,每个索引的设置信息,映射mapping定义等等)以及各个索引实际的内容数据都需要被保存进行长持久化。
有一个解决方案类似于苹果的时间机器(Time Machine),我们需要保存我们的状态信息到持久化设备中,这个方案和网格里面的延迟写(Write Behind)也有些许相似。
它的思想就是短期通过复制保证高可用,同时异步进行状态的增量持久化操作,优点是实时的操作不会影响这个持久化的过程。
所以,当我们重新启动集群的时候,会发生什么呢?首先,第一次启动的时候,它会去持久化设备读取集群的状态信息(创建的索引,配置等)然后执行应用它们(创建索引,创建mapping映射等),每一次shard节点第一次实例化加入复制组,它都会从长持久化存储里面恢复它的状态信息。
ES 提供了一个叫做Gateway的模块,举例来说,要将状态信息保存到共享文件系统,每个节点启动前可以做如下的配置:

gateway :
    type : fs
    fs :
        location : /shared/fs/

或者可以通过命令行的方式传递参数 (only on unix):

$ bin/elasticsearch -f \
        -Des.gateway.type=fs -Des.gateway.fs.location=/shared/fs/

以上意思是说集群的状态会被持久化到一个共享文件系统中,每个创建的索引的状态信息也会自动的持久化到这个共享文件系统中,此外,每个索引拥有各种的index gateway,我们可以很灵活的进行每索引级别来进行配置是否需要通过gateway保存状态信息,下面的例子就是不保存状态信息的例子,如下,

$ curl -XPUT http://localhost:9200/my_special_volatile_index/ -d '
index :
    gateway:
        type : none
'

你看,是不是非常强大啊,此外,在云环境里这也是一个非常完美的解决方案,在云端,长持久化存储通常是用云提供商的,例如,Amazon的EBS或S3,ES目前的版本,你可以直接使用Amazon的EBS(一个挂载的共享文件系统)来进行长持久化,未来将会支持直接使用AmazonS3或其他来进行直接的状态的长持久化。
最后的话
这里只是一些关于ES怎样做复制、故障恢复、节点发现、gateway具体怎样工作的一些简单介绍,将来会支持更多的强大功能,如,我现在正在弄的关于索引状态的版本控制,对索引打tag(类似svn),恢复特定tag版本的索引到新的索引或当前索引,我希望至少这些至少可以处理节点失败(部分或全部),ElasticSearch现在更有意义。

你可能感兴趣的:(elasticsearch)