Elasticsearch
Elasticsearch 是一个分布式、RESTful 的搜索和分析引擎,能够解决日益增长的用例。作为 Elastic Stack 的核心,它集中存储您的数据,以便您可以发现预期并揭示意外。
JanusGraph 支持 Elasticsearch 作为索引后端。以下是 JanusGraph 支持的一些 Elasticsearch 功能
- 全文:支持所有
Text谓词,用于搜索匹配给定单词、前缀或正则表达式的文本属性。 - 地理:支持所有
Geo谓词,用于搜索与给定查询几何体相交、在其中、不相交或包含的地理属性。支持点、圆、框、线和多边形进行索引。支持圆、框和多边形查询点属性,以及所有形状查询非点属性。 - 数字范围:支持
Compare中的所有数字比较。 - 灵活配置:支持远程操作和开放式设置自定义。
- 集合:支持索引 SET 和 LIST 基数属性。
- 时间:纳秒粒度的时间索引。
- 自定义分析器:选择使用自定义分析器
请参阅 版本兼容性,了解哪些版本的 Elasticsearch 可与 JanusGraph 配合使用。
重要
JanusGraph 使用沙盒化的 https://elastic.ac.cn/guide/en/elasticsearch/reference/master/modules-scripting-painless.html[Painless 脚本] 进行内联更新,这些脚本在 Elasticsearch 中默认启用。
运行 Elasticsearch
JanusGraph 支持连接到正在运行的 Elasticsearch 集群。JanusGraph 提供了两种运行本地 Elasticsearch 实例的选项,以便快速入门。JanusGraph 服务器(参见 入门)会自动启动一个本地 Elasticsearch 实例。另外,JanusGraph 版本包含一个完整的 Elasticsearch 分发版,允许用户手动启动一个本地 Elasticsearch 实例(参见 此页面 了解更多信息)。
$ elasticsearch/bin/elasticsearch
注意
出于安全原因,Elasticsearch 必须在非 root 账户下运行。
Elasticsearch 配置概述
JanusGraph 支持 HTTP(S) 客户端连接到正在运行的 Elasticsearch 集群。请参阅 版本兼容性,了解哪些版本的 Elasticsearch 可与 JanusGraph 中的不同客户端类型配合使用。
注意
JanusGraph 的索引选项以字符串 "index.[X]." 开头,其中 "[X]" 是后端的用户定义名称。当构建混合索引时,必须将此用户定义名称传递给 JanusGraph 的 ManagementSystem 接口,如 混合索引 中所述,以便 JanusGraph 知道使用多个可能已配置的索引后端中的哪一个。本章中的配置代码片段使用名称 search,而选项的散文讨论通常在相同位置写入 [X]。只要在 JanusGraph 的配置中和管理索引时一致使用,确切的索引名称并不重要。
提示
建议索引名称只包含字母数字小写字符和连字符,并以小写字母开头。
连接到 Elasticsearch
Elasticsearch 客户端指定如下
index.search.backend=elasticsearch
连接到 Elasticsearch 时,必须提供 Elasticsearch 实例的单个或列表主机名。这些通过 JanusGraph 的 index.[X].hostname 键提供。
index.search.backend=elasticsearch
index.search.hostname=10.0.0.10:9200
此处指定的每个主机或 host:port 对都将添加到 HTTP 客户端的请求目标循环列表。这是一个最小配置,它将在默认的 Elasticsearch HTTP 端口 (9200) 上循环 10.0.0.10 和在端口 7777 上循环 10.0.0.20
index.search.backend=elasticsearch
index.search.hostname=10.0.0.10, 10.0.0.20:7777
JanusGraph index.[X] 和 index.[X].elasticsearch 选项
JanusGraph 仅对 index-name 和 health-request-timeout 使用默认值。请参阅 配置参考,了解这些选项的描述及其接受的值。
index.[X].index-nameindex.[X].elasticsearch.health-request-timeout
REST 客户端选项
REST 客户端接受 index.[X].bulk-refresh 选项。此选项控制何时使更改对搜索可见。有关更多信息,请参阅 ?refresh 文档。
REST 客户端 HTTPS 配置
通过将 index.[X].elasticsearch.ssl.enabled 配置选项设置为 true,可以启用 HTTP 的 SSL 支持。请注意,根据您的配置,如果您的 HTTPS 端口号与 REST API 的默认端口号 (9200) 不同,您可能需要更改 index.[X].port 的值。
启用 SSL 后,您还可以配置信任库的位置和密码。这可以按如下方式完成
index.search.elasticsearch.ssl.truststore.location=/path/to/your/truststore.jks
index.search.elasticsearch.ssl.truststore.password=truststorepwd
请注意,这些设置仅适用于 Elasticsearch REST 客户端,不影响 JanusGraph 中的任何其他 SSL 连接。
也支持客户端密钥库的配置
index.search.elasticsearch.ssl.keystore.location=/path/to/your/keystore.jks
index.search.elasticsearch.ssl.keystore.storepassword=keystorepwd
index.search.elasticsearch.ssl.keystore.keypassword=keypwd
任何密码都可以为空。
如果需要,可以通过将 index.[X].elasticsearch.ssl.disable-hostname-verification 属性值设置为 true 来禁用 SSL 主机名验证,并且可以通过将 index.[X].elasticsearch.ssl.allow-self-signed-certificates 属性值设置为 true 来启用对自签名 SSL 证书的支持。
提示
不建议在生产系统中使用自签名 SSL 证书或禁用主机名验证,因为它会显著限制客户端提供与 Elasticsearch 服务器安全通信通道的能力。这可能会导致泄露可能是 JanusGraph 索引一部分的机密数据。
REST 客户端 HTTP 认证
REST 客户端支持以下认证选项:基本 HTTP 认证(用户名/密码)和基于用户提供的实现的自定义认证。
这些认证方法独立于上述 SSL 客户端认证。
REST 客户端基本 HTTP 认证
无论 SSL 支持的状态如何,基本 HTTP 认证都可用。可以选择通过 index.[X].elasticsearch.http.auth.basic.realm 属性指定认证领域。
index.search.elasticsearch.http.auth.type=basic
index.search.elasticsearch.http.auth.basic.username=httpuser
index.search.elasticsearch.http.auth.basic.password=httppassword
提示
强烈建议在使用此选项时使用 SSL(例如,将 index.[X].elasticsearch.ssl.enabled 设置为 true),因为凭据在通过未加密连接发送时可能会被拦截!
REST 客户端自定义 HTTP 认证
可以通过提供您自己的实现来实施额外的认证方法。自定义认证器配置如下
index.search.elasticsearch.http.auth.type=custom
index.search.elasticsearch.http.auth.custom.authenticator-class=fully.qualified.class.Name
index.search.elasticsearch.http.auth.custom.authenticator-args=arg1,arg2,...
参数列表是可选的,可以为空。
此处指定的类必须实现 org.janusgraph.diskstorage.es.rest.util.RestClientAuthenticator 接口或扩展 org.janusgraph.diskstorage.es.rest.util.RestClientAuthenticatorBase 便利类。该实现可以访问 HTTP 客户端配置,并可以根据需要自定义客户端。请参阅 <
例如,以下代码片段实现了一个认证器,允许 Elasticsearch REST 客户端针对 AWS IAM 进行认证和授权。
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.janusgraph.diskstorage.es.rest.util.RestClientAuthenticatorBase;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.regions.DefaultAwsRegionProviderChain;
import com.google.common.base.Supplier;
import vc.inreach.aws.request.AWSSigner;
import vc.inreach.aws.request.AWSSigningRequestInterceptor;
/**
* <p>
* Elasticsearch REST HTTP(S) client callback implementing AWS request signing.
* </p>
* <p>
* The signer is based on AWS SDK default provider chain, allowing multiple options for providing
* the caller credentials. See {@link DefaultAWSCredentialsProviderChain} documentation for the details.
* </p>
*/
public class AWSV4AuthHttpClientConfigCallback extends RestClientAuthenticatorBase {
private static final String AWS_SERVICE_NAME = "es";
private HttpRequestInterceptor awsSigningInterceptor;
public AWSV4AuthHttpClientConfigCallback(final String[] args) {
// does not require any configuration
}
@Override
public void init() throws IOException {
DefaultAWSCredentialsProviderChain awsCredentialsProvider = new DefaultAWSCredentialsProviderChain();
final Supplier<LocalDateTime> clock = () -> LocalDateTime.now(ZoneOffset.UTC);
// using default region provider chain
// (https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/java-dg-region-selection.html)
DefaultAwsRegionProviderChain regionProviderChain = new DefaultAwsRegionProviderChain();
final String awsRegion = regionProviderChain.getRegion();
final AWSSigner awsSigner = new AWSSigner(awsCredentialsProvider, awsRegion, AWS_SERVICE_NAME, clock);
this.awsSigningInterceptor = new AWSSigningRequestInterceptor(awsSigner);
}
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.addInterceptorLast(awsSigningInterceptor);/
}
}
此自定义认证器不使用任何构造函数参数。
摄取管道
可以为每个混合索引设置不同的摄取管道。摄取管道可用于在索引之前预处理文档。管道由一系列处理器组成。每个处理器以某种方式转换文档。例如,日期处理器 可以将文本中的日期提取到日期字段。这样您就可以使用 JanusGraph 查询此日期,而无需将其物理存储在主存储中。
index.[X].elasticsearch.ingest-pipeline.[mixedIndexName] = pipeline_id
请参阅 摄取文档 了解有关摄取管道的更多信息,并参阅 处理器文档 了解有关摄取处理器的更多信息。
保护 Elasticsearch
Elasticsearch 不执行身份验证或授权。可以连接到 Elasticsearch 的客户端被 Elasticsearch 信任。当 Elasticsearch 在不安全或公共网络上运行,特别是在互联网上运行时,它应该部署某种外部安全措施。这通常通过防火墙、Elasticsearch 端口隧道或使用 Elasticsearch 扩展(例如 X-Pack)的组合来完成。Elasticsearch 有两个面向客户端的端口需要考虑
- HTTP REST API,通常在端口 9200 上
- 原生“传输”协议,通常在端口 9300 上
客户端使用一个协议/端口或另一个,但不同时使用两者。保护 HTTP 协议端口通常通过防火墙和带有 SSL 加密和 HTTP 身份验证的反向代理的组合来完成。有几种方法可以在原生“传输”协议端口上实现安全性
此外,一些托管的 Elasticsearch 服务提供其他身份验证和授权方法。例如,AWS Elasticsearch Service 要求使用 HTTPS,并提供使用基于 IAM 的访问控制的选项。为此,发送到此服务的请求必须经过签名。这可以通过使用自定义身份验证器(参见上文)来实现。
隧道 Elasticsearch 的原生“传输”协议:此方法可以通过 SSL/TLS 隧道(例如通过 stunnel)、VPN 或 SSH 端口转发来实现。SSL/TLS 隧道需要非平凡的设置和监控:隧道的一端或两端需要证书,并且需要配置并持续运行 stunnel 进程。大多数安全 VPN 的设置同样非平凡。一些 Elasticsearch 服务提供商处理服务器端隧道管理,并提供自定义的 Elasticsearch transport.type 以简化客户端设置。
添加防火墙规则,只允许受信任的客户端连接到 Elasticsearch 的原生协议端口
这通常在主机防火墙级别完成。易于配置,但其自身的安全性非常弱。
索引创建选项
JanusGraph 支持自定义其在创建 Elasticsearch 索引时使用的索引设置。它允许在 JanusGraph 发出的 Elasticsearch create index 请求 的 settings 对象上设置任意键值对。以下是可以使用此机制自定义的一些非详尽的 Elasticsearch 索引设置示例
index.number_of_replicasindex.number_of_shardsindex.refresh_interval
通过此机制自定义的设置仅在 JanusGraph 尝试在 Elasticsearch 中创建其索引时应用。如果 JanusGraph 发现其索引已经存在,则它不会尝试重新创建它,并且这些设置不起作用。
使用 create.ext 嵌入 Elasticsearch 索引创建设置
JanusGraph 迭代所有以 index.[X].elasticsearch.create.ext. 为前缀的属性,其中 [X] 是索引名称,例如 search。它从每个属性键中删除前缀。剥离键的剩余部分将被解释为 Elasticsearch 索引创建设置。与键关联的值未修改。剥离的键和未修改的值作为 settings 对象的一部分传递到 JanusGraph 在 Elasticsearch 上引导时发出的 Elasticsearch 创建索引请求中。这允许在 JanusGraph 的属性中嵌入任意索引创建设置。以下是一个配置片段示例,它使用 create.ext 配置机制自定义三个 Elasticsearch 索引设置
index.search.backend=elasticsearch
index.search.elasticsearch.create.ext.number_of_shards=15
index.search.elasticsearch.create.ext.number_of_replicas=3
index.search.elasticsearch.create.ext.shard.check_on_startup=true
上面列出的配置片段利用了 Elasticsearch 的假设,即非限定的 create index 设置键具有 index. 前缀,该假设在服务器端实现。也可以明确拼写出索引前缀。以下是一个功能上与上面列出的 JanusGraph 配置文件等效的 JanusGraph 配置文件,只是索引创建设置前的 index. 前缀是显式的
index.search.backend=elasticsearch
index.search.elasticsearch.create.ext.index.number_of_shards=15
index.search.elasticsearch.create.ext.index.number_of_replicas=3
index.search.elasticsearch.create.ext.index.shard.check_on_startup=false
提示
用于指定索引创建设置的 create.ext 机制与 JanusGraph 的 Elasticsearch 配置兼容。
故障排除
连接到远程 Elasticsearch 集群的问题
检查 Elasticsearch 集群节点是否可通过 HTTP 协议端口从 JanusGraph 节点访问。通过检查 Elasticsearch 节点配置日志或使用 netstat 等通用诊断实用程序检查节点监听端口。检查 JanusGraph 配置。
优化 Elasticsearch
写入优化
对于 批量加载 或其他写入密集型应用程序,请考虑增加 Elasticsearch 的刷新间隔。请参阅 此讨论,了解如何增加刷新间隔及其对写入性能的影响。请注意,更高的刷新间隔意味着图突变在索引中可用需要更长的时间。
延伸阅读
- 请参阅 Elasticsearch 主页 和可用文档,了解有关 Elasticsearch 以及如何设置 Elasticsearch 集群的更多信息。