我们如何以编程方式(轻松)设置ZooKeeper服务器集群?
此问题的理由是,我们不能依靠我们的客户来运行单独的ZooKeeper集群,也不能像某个特定的客户那样仅仅出于此目的而运行单独的流程的想法。因此,我们希望朝着运行嵌入在我们自己的应用程序中的ZooKeeper服务器的方向发展,该服务器已经在集群中运行。 (最终目标是运行SolrCloud,它本身依赖ZooKeeper的存在。这就是我们的来源。)
因此,这是起点:运行我们的应用程序的任意数量的Java进程。为什么不运行嵌入在每个进程中的ZooKeeper服务器实例,从而形成一个ZooKeeper集群?
大多数教程介绍了如何将ZooKeeper作为独立进程运行,并在属性文件中提供了有关群集节点的信息。我对运行嵌入式ZooKeeper并没有太多了解。 (例如Zookeeper cluster set up,Best way to start zookeeper server from java program和Is it possible to start a zookeeper server instance in process, say for unit tests?)。
我很想知道是否有一种方法可以建立一个ZooKeeper集群,而无需事先知道将要参与的节点。有没有办法提供例如数据库连接,而ZooKeeper服务器节点将通过此数据库相互发现。或者,ZooKeeper服务器节点可以使用多播消息进行发现吗? 如果这不可能,我想我们将必须维护一个运行应用程序的节点列表(这将转换为ZooKeeper服务器节点列表)。
基于可用于在命令行中启动ZooKeeper服务器的Java代码,我想到了用于启动/停止服务器节点的以下代码:
File dir = new File(dataDirectory, "zookeeper-"+port).getAbsoluteFile();
server = new ZooKeeperServer(dir, dir, tickTime);
adminServer = AdminServerFactory.createAdminServer();
adminServer.setZooKeeperServer(server);
adminServer.start();
cnxnFactory = ServerCnxnFactory.createFactory(port, numConnections);
cnxnFactory.startup(server);
containerManager = new ContainerManager(server.getZKDatabase(), server.firstProcessor, (int) TimeUnit.MINUTES.toMillis(1), 10000);
containerManager.start();
// shutdown...
if (containerManager != null) {
containerManager.stop();
}
if (cnxnFactory != null) {
cnxnFactory.shutdown();
}
try {
if (adminServer != null) {
adminServer.shutdown();
}
} catch (AdminServerException e) {
e.printStackTrace();
}
cnxnFactory.join();
server.shutdown(true);
使用此代码实现的所有操作都是启动ZooKeeper服务器节点,但据我所知,到目前为止,节点之间没有链接。
我应该使用QuorumPeerConfig
在节点之间建立链接吗?这是我目前停留的地方。
在任何地方都存在有关如何设置ZooKeeper服务器集群的好例子吗?