
GitHub 将Elasticsearch作为其搜索服务的主要后端支持技术。为了管理好集群,他们通过Hubot使用 ChatOps。截止 2017 年,这些命令是 Bash 和基于 Ruby 的脚本的集合。
尽管这在一段时间内满足了我们的需求,但这些脚本缺乏可组合性和可重用性的缺点变得越来越明显。由于它们特定于 GitHub 基础设施,因此想通过开源这些脚本来回馈社区也很困难。
为什么要构建新的东西呢?
我们有很多优秀的 Elasticsearch 库,其中有官方的也有社区驱动的。对于 Ruby,GitHub 已经发布了Elastomer库。而对于 Go,我们使用用户olivere提供的Elastic库。然而,这些库主要关注的是索引和查询数据。对于一个需要使用 Elasticsearch 的应用程序来说,这正合所需。但是,它不符合 Elasticsearch 集群的操作人员对工具集的需求。我们希望用一个高级 API 实现我们在集群上的常见操作,如:禁用分配或从节点中清除分片。我们的目标是创建一个专注于这些管理操作并易于使用我们现有工具的库。
用 Go 全速前进……
我们开始研究 Go,这是受到了 GitHub 上freno 和 orchestrator的成功的启发。
Go 的结构鼓励构造可组合(自包含、无状态的、可选择和组装的组件)软件,我们认为它很适合该应用程序。
遇上麻烦了
我们最初把该项目作为一个打包的聊天应用程序,并计划开源那些我们只在内部使用的东西。然而,在实施过程中,我们遇到了一些问题:
GitHub 使用一个简单协议,该协议基于 JSON-RPC,通过 HTTPS 调用ChatOps RPC。然而,ChatOps RPC 除了 GitHub 外没有被广泛采用。对大多数参与方来说,这将难以把我们的应用程序集成到 ChatOps 基础设施。
我们的 ChatOps 命令所依赖的内部 REST 库没有开源。该 REST 的一些依赖项也将需要开源。我们已经开始开源该库及其依赖项的过程,但是这需要一些时间。
我们依靠Consul进行服务发现,但并不是每个人都用 Consul。
基于这些因素,我们决定把我们库的核心拆分成可以开源的独立包。这将使该包与我们的内部库、Consul 和 ChatOps RPC 解耦。
该包只有这么几个目标:
访问单个主机上的 REST 端点。
执行一项操作。
提供该操作的结果。
然后,可以开源这个模块,而不把它绑定在我们的内部基础设施上。这样,任何人都可以将它与 ChatOps 基础设施、服务发现或他们选择的工具一起使用。
为此,我们编写了 Vulcanizer。
Vulcanizer
Vulcanizer 是用于与 Elasticsearch 集群交互的 Go 库。这并不是说它是一个成熟的 Elasticsearch 客户端。它的目标是提供一个高级 API,以帮助与操作 Elasticsearch 集群相关的常见任务,如:查询集群的健康状态、迁移节点的数据、更新集群的设置等等。
Go API 的示例
几乎在所有需要用到 HTTP 接口来完成的事情上,Elasticsearch 都表现得很好。但是,我们不想手工编写 JSON,尤其是在出问题的时候。以下是一些我们如何把 Vulcanizer 用于常见任务及等效 curl 命令的例子。这些 Go 示例已被简化,没有展示错误处理代码。
获取集群的节点
我们总是希望列出集群中的所有节点,以选择特定的节点或查看集群中每种节点的个数
Vulcanizer 为这类对象公开类型化结构
更新最大恢复集群设置
如果我们希望在集群中平衡恢复时间和 I/O 压力,索引恢复速度是个常见更新设置。curl 版本要编写很多 JSON 代码。
该 Vulcanizer API 相当简单。它还会检索及返回该键的所有现有设置,以便记录先前的值。
把碎片移入和移出节点
为了安全地更新一个节点,我们可以设置分配规则,以便从特定节点迁移数据。在 Elasticsearch 设置中,这是一个由逗号分隔的节点名称列表,因此,我们需要注意不要在更新时覆盖现有值。
该 Vulcanizer API 将安全地从排除设置中添加和删除节点。因此,碎片不会被意外地分配到节点上。
命令行应用程序
包含一个利用该库的小型 CLI 应用程序:
ChatOps
ChatOps 对 GitHub 和我们这些异地工作人员很重要。Vulcanizer 使我们能够轻松快速地围绕 Elasticsearch 构建 ChatOps 工具,以执行常见任务:



结语
当我们第一次开始尝试这种方法时,有点跌跌撞撞。但是,最终的结果对大家来说都是最好的:
由于我们不得不重新组合我们打算开源的确切功能,因此,我们确保能为自己及社区提供价值,而不只是传送东西。
内部工具不总是遵循工程最佳实践(如正确的版本管理),因此,在开放的环境中开发 Vulcanizer 给了我们外部压力,以确保我们遵循所有的最佳实践。
将所有 Elasticsearch 功能放在其自己的库中,使我们的内部应用程序变得非常轻巧和独立。显然,不同的内部应用程序依赖于 Vulcanizer,而非互相依赖,更不是试图让 ChatOps 和另一个 ChatOps 通信。
请访问Vulcanizer存储库以进行克隆或为该项目做点贡献。我们对 Vulcanizer路径图上未来的发展是有想法的。
阅读英文原文:Vulcanizer: a library for operating Elasticsearch;https://githubengineering.com/vulcanizer-a-library-for-elasticsearch/
评论