在Solr客户端上指定ZooKeeper主机的最佳方法?

Bru*_*e P 11 solr amazon-web-services solrcloud apache-zookeeper

我们在AWS EC2中运行了一些SolrCloud和ZooKeeper设置,并且在大多数情况下它们运行顺利,但是在最近我们的一个ZooKeeper节点发生故障后,我开始想知道是否有任何一种让客户端解决ZooKeeper的方法是比别人好.我们的客户端是基于Java的,使用Solr 4.1 java客户端.

最初我们使用hostfile条目来识别ZooKeepers,但/etc/hosts考虑到AWS的性质,确保条目是最新的,这样做变得非常繁琐.所以我们现在通过Route53使用自定义DNS来识别ZooKeepers.但是我们仍然单独识别ZooKeeper节点,因此我们当前在启动客户端时指定了这一点:

-Dsolr.zookeeperHosts='zk-1.mydomain.com:2181,zk-2.mydomain.com:2181,zk-3.mydomain.com:2181'
Run Code Online (Sandbox Code Playgroud)

主机zk-1.mydomain.com等只是每个ZooKeeper EC2实例的DNS的CNAME.所以现在如果亚马逊强迫我们重新启动ZooKeeper,导致它获得一个新的IP地址,那么当DNS记录更新时,客户端最终将获得新的IP.

我的问题与想知道是否有更好的方法来处理这个问题有关.假设我们想要在混合中添加额外的ZooKeepers,所以我们有5个节点的法定数量而不是3个.(我实际上想要这样做.)拥有包含所有的单个DNS循环记录会更有意义吗ZooKeepers在其中并将该单个DNS名称传递给客户端?

例如,成立了DNS记录zookeepers.mydomain.com的CNAME指向zk-1.mydomain.com,zk-2.mydomain.com并且zk-mydomain.com,然后简单地PAS这给我的客户:

-Dsolr.zookeeperHosts='zookeepers.mydomain.com:2181'
Run Code Online (Sandbox Code Playgroud)

这样,当我将新的ZooKeepers添加到集群时,我可以简单地添加另一个CNAME记录,zookeepers.mydomain.com而不必担心更新所有客户端上的配置.

Solr客户端是否足够智能,可以使用包含多条记录的DNS记录?具体来说,如果一个ZooKeeper碰巧关闭,并且客户端试图连接到它,客户端是否会知道再次查询DNS以获取下一个ZooKeeper的IP并尝试与之通信?

Mon*_*lon 1

使用 CNAME 是一个好主意,但我建议使用弹性 IP 对其进行扩展,以使其更加强大,DNS 更改需要时间来传播,弹性 IPS 的响应速度更快。

不过,我确实有一些警告,在我们的调查中,我们试图探索如果我们不使用主机名/ip,而使用负载均衡器并将其交给 Solr,Zookeeper/Solr 将如何反应,不要这样做!似乎在内部将每个solr.zookeeperHosts条目标识为 Zookeeper 服务器,当其中一个由于某种原因发生故障时,它会使其失效,因为从 Solr 的角度来看,没有任何其他 Zookeeper 服务器,因此 Solr 不会停机。我的猜测是,如果您拥有多个 IP 的记录,也会遇到同样的问题。

对此的最佳解决方案是尽可能自动化。在之前的项目中,我使用 Chef 收集所有 Zookeeper 节点,并在每个 solr 节点上动态设置 ips/主机名。如果 Chef 对您来说需要做很大的改变,那么也可以使用 EC2 标签和一些巧妙的 bash 脚本来完成。您可以使用标签标记您的 Zookeeper 实例,并使用像这样的 aws cli 来获取 ip 列表。

 ec2-describe-instances --filter "tag-key=Zookeeper"
Run Code Online (Sandbox Code Playgroud)