弹性搜索与MongoDB集成及X-Pack功能应用
在大数据处理领域,数据的存储、管理和查询是关键环节。弹性搜索(Elasticsearch)和MongoDB是常用的数据存储和检索工具,而X-Pack则为弹性搜索提供了一系列强大的扩展功能。下面将详细介绍如何使用弹性搜索与MongoDB集成,以及X-Pack的常见功能。
弹性搜索与MongoDB集成
在管道中使用MongoDB的源和汇非常简单。通过弹性搜索源(ElasticsearchSource),结合ElasticsearchParams指定索引、查询领域特定语言(DSL)和源配置(ElasticsearchSourceSettings),可以生成类型化的项目流。
ElasticsearchSource
.typed[Iris](
ElasticsearchParams.V7("iris-alpakka"),
query = """{"match_all": {}}""",
settings = ElasticsearchSourceSettings(connectionSettings).withBufferSize(1000)
)
- ElasticsearchParams :有两个辅助方法。
-
V5:用于Elasticsearch 5.x/6.x版本,需要定义索引和类型。 -
V7:用于Elasticsearch 7.x及以上版本,只需定义索引名称。 - ElasticsearchSourceSettings :需要初始化ElasticsearchConnectionSettings,最常用的方法是
withBufferSize,可将默认的获取大小(10条记录)更改为更大的值,以加快记录获取速度。
返回的类型是 Source[ReadResult[T], NotUsed] ,其中 T 是我们定义的类型(如示例中的 Iris )。 ReadResult[T] 是一个包装对象,包含以下内容:
- id: String :Elasticsearch的ID。
- source: T :文档的源部分,转换为 T 对象。
- version: Option[Long] :可选的版本号。
要将数据写入MongoDB,需要创建连接、选择数据库并获取集合:
private val mongo = MongoClients.create("mongodb://localhost:27017")
private val db = mongo.getDatabase("es-to-mongo")
val irisCollection = db
.getCollection("iris", classOf[Iris])
.withCodecRegistry(codecRegistry)
这里定义了 irisCollection 为 Iris 类型,并提供了编解码器进行数据编组(转换)。编解码器注册表(codecRegistry)使用Scala宏构建:
import org.bson.codecs.configuration.CodecRegistries.{
fromProviders,
fromRegistries
}
import org.mongodb.scala.MongoClient.DEFAULT_CODEC_REGISTRY
import org.mongodb.scala.bson.codecs.Macros._
val codecRegistry =
fromRegistries(fromProviders(classOf[Iris]), DEFAULT_CODEC_REGISTRY)
为了加快写入速度,选择以100个元素为一组进行批量写入:
.grouped(100) // bulk insert of 100
结果使用 MongoSink 写入集合:
.runWith(MongoSink.insertMany[Iris](irisCollection))
在流式处理中,建议在弹性搜索和MongoDB中都进行批量写入。
X-Pack简介
X-Pack是一组扩展弹性搜索标准功能的模块/插件,包括安全、警报、报告、索引管理、监控、机器学习、SQL支持以及映射、分析器、搜索和摄取处理器的通用扩展等。它是由Elastic公司管理的商业组件,默认安装在弹性搜索中。所有功能都可以试用30天,其中许多功能在免费层是终身免费的。不同X-Pack层级提供的完整功能映射可在 这里 查看。
索引生命周期管理(ILM)
索引生命周期管理(ILM)允许设置策略来管理索引生命周期的不同方面,如:
- 管理每日、每周和每月的索引,进行备份、优化并在不同服务层(热层和冷层)之间移动。
- 当某些索引达到一定大小或文档数量时,创建并切换到新索引。
- 在索引生命周期结束时删除过时的索引。
- 删除陈旧的索引以执行保留标准(如通用数据保护条例(GDPR)和3个月保留期)。
ILM策略可以通过API或Kibana(进入Stack Management | Index Lifecycle Policies)定义。
创建90天保留策略
以下是创建一个能够删除所有数据超过90天的索引的策略的步骤:
1. 创建策略:
PUT _ilm/policy/90d_policy
{"policy": {
"phases": {
"delete": { "min_age": "90d",
"actions": { "delete": {} } } } } }
如果一切正常,将得到以下结果:
{ "acknowledged" : true }
- 扩展索引模板,添加之前创建的策略:
PUT _index_template/order
{ "index_patterns": ["order-*"],
"template": {
"settings": {
"number_of_shards": 1,
"index.lifecycle.name": "90d_policy",
"index.lifecycle.rollover_alias": "order" },
"mappings": {
"properties": { "id": { "type": "keyword"}}}},
"priority": 200,
"composed_of": ["timestamp-management", "order-data",
"items-data"], "version": 1,
"_meta": {"description": "My order index template"}}
如果一切正常,将得到以下结果:
{ "acknowledged" : true }
ILM通过定义应用于索引的策略来工作,最佳做法是将这些策略放在索引模板中,以便自动应用于新创建的索引。创建策略的URL为: PUT _ilm/policy/<policy_name> 。
策略是一个嵌套的JSON,由一个或多个可选阶段组成:
| 阶段 | 描述 |
| ---- | ---- |
| Hot | 索引正在被积极更新和查询,是最常见的实时索引。 |
| Warm | 索引不再更新,但仍被查询,通常是前一周/月的索引,不再接收新数据。 |
| Cold | 索引不再更新,很少被查询,可搜索但查询速度较慢,索引数据通常保存在旋转磁盘上。 |
| Frozen | 索引不再更新,极少被查询,查询速度极慢,通常是存储在S3或其他远程数据存储中的离线索引。 |
| Delete | 索引数据不再需要,或已达到最大保留时间,可以删除。 |
阶段之间的迁移由每个阶段的最小年龄定义,默认为0。为防止阶段迁移和ILM出现问题,集群状态必须为绿色。在黄色状态下,阶段更改可能不可预测。在阶段执行期间,索引的状态保存在索引元数据中。ILM由弹性搜索集群定期执行,轮询时间由 indices.lifecycle.poll_interval 设置(默认10分钟)。
支持的操作按执行步骤顺序如下:
- Set Priority:设置执行步骤的优先级。
- Unfollow:将跨集群索引设置为标准索引。
- Rollover:设置滚动索引。
- Read-Only:将索引设置为只读模式,通常在滚动命令之后。
- Shrink:减少当前索引的分片数量。
- Force Merge:优化索引中的段数量。
- Allocate:更改可以托管索引的节点。
- Migrate:更改索引的层级(并可根据请求减少分片数量)。
- Freeze:冻结索引(从内存中移除)。
- Searchable Snapshot:将快照挂载为可搜索的索引。
- Wait for Snapshot:等待索引的完整快照,以确保在删除之前有索引的备份副本。
- Delete:删除索引。
并非所有操作都适用于不同阶段,以下是各阶段操作的总结:
| 阶段 | 支持的操作 |
| ---- | ---- |
| Hot | Set Priority, Rollover |
| Warm | Set Priority, Read-Only, Shrink, Force Merge, Allocate, Migrate |
| Cold | Set Priority, Freeze, Allocate, Migrate |
| Frozen | Set Priority, Searchable Snapshot |
| Delete | Wait for Snapshot, Delete |
ILM可以通过简单更新现有索引的设置轻松集成到现有索引中。要为现有索引添加策略,只需提供策略名称:
PUT myindex/_settings
{ "index": {
"lifecycle": { "name": "50gb_30d_delete_90d_policy" }}}
可以在索引名称中使用通配符将更改应用于多个索引。
自动滚动索引
ILM通常与滚动索引结合使用,这些索引通常包含仅追加的数据,如日志。滚动索引的标准管理如下:
- 索引创建,通常由索引模板管理。
- 当索引达到特定大小(默认50 GB)或预定义的文档数量时进行滚动。
- 如果需要,将索引移动到不同的层级。
- 删除索引以符合保留策略。
滚动功能通常与称为数据流的托管索引一起使用,数据流是仅追加的数据索引,当满足某些大小和文档数量标准时会自动滚动到新索引。这些索引主要用于日志、事件、指标和连续生成的数据。
创建自动滚动和删除策略
以下是创建一个能够在索引达到50 GB或30天数据时自动滚动,并删除所有数据超过90天的索引的策略的步骤:
1. 创建策略:
PUT _ilm/policy/50gb_30d_delete_90d_policy
{ "policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50GB", "max_age": "30d" }}},
"delete": {
"min_age": "90d",
"actions": { "delete": {} } } } } }
如果一切正常,将得到以下结果:
{ "acknowledged" : true }
- 创建数据流,添加之前创建的策略:
PUT _index_template/timeseries_template
{ "index_patterns": ["timeseries"],
"data_stream": { },
"template": {
"settings": {
"number_of_shards": 1, "number_of_replicas": 1,
"index.lifecycle.name": "50gb_30d_delete_90d_policy" } } }
如果一切正常,将得到以下结果:
{ "acknowledged" : true }
- 向索引添加一条记录以强制创建索引:
POST timeseries/_doc
{ "message": "this is a message",
"@timestamp": "2022-03-16T15:03:03" }
结果如下:
{ "_index" : ".ds-timeseries-2022.03.15-000001",
"_id" : "osN7cHkBtG0xN2Ak2au2", … truncated … }
- 检查策略是否应用于
.ds-timeseries-2022.03.15-000001索引:
GET .ds-timeseries-*/_ilm/explain
结果类似如下:
{ "indices" : {
".ds-timeseries-2022.03.15-000001" : {
"index" : ".ds-timeseries-2022.03.15-000001",
"managed" : true,
"policy" : "50gb_30d_delete_90d_policy",
"lifecycle_date_millis" : 1621089728349,
"age" : "3.3m", "phase" : "hot",
"phase_time_millis" : 1621089728462,
"action" : "rollover",
"action_time_millis" : 1621089728533,
"step" : "check-rollover-ready",
"step_time_millis" : 1621089728533,
"phase_execution" : {
"policy" : "50gb_30d_delete_90d_policy",
"phase_definition" : {
"min_age" : "0ms",
"actions" : {
"rollover" : {
"max_size":"50gb","max_age" : "30d"}}},
"version" : 2,
"modified_date_in_millis" : 1621089704907 }}}}
滚动操作使用两个可选参数(至少提供一个):
- max_size :定义索引的最大大小。
- max_age :定义索引的最大年龄。
当满足其中一个约束条件时,将自动创建新索引。
ILM可以通过简单更新现有索引的设置轻松集成到现有索引中。要为现有索引添加策略,只需提供策略名称:
PUT myindex/_settings
{ "index": {
"lifecycle": { "name": "50gb_30d_delete_90d_policy" }}}
可以在索引名称中使用通配符将更改应用于多个索引。通过在索引模板中定义ILM策略,可以自动将其应用于每个新创建的索引。可以通过REST API检查每个索引应用的ILM规则: GET <index_name>/_ilm/explain 。结果包含很多信息,最重要的字段如下:
| 字段 | 描述 |
| ---- | ---- |
| managed (Boolean) | 索引是否由ILM管理。 |
| policy | 应用的策略名称,主要用于调试目的。 |
| age | 索引的时间。 |
| phase | 索引的实际阶段。 |
| action | 最后应用的操作。 |
| step | 操作的步骤,某些操作可能有一个或多个步骤。 |
| phase_execution | 实际阶段执行的描述。 |
使用X-Pack提供的弹性搜索功能非常简单,它还简化了流式数据的所有索引管理。
使用SQL Rest API
X-Pack允许将标准的SQL查询语言的强大功能引入弹性搜索,以简化数据用户的使用和外部应用程序的集成。
准备工作
需要运行一个正常的弹性搜索实例,并可以使用任何HTTP客户端(如 curl 、 Postman 等)执行命令。建议使用Kibana控制台,因为它为弹性搜索提供代码补全和更好的字符转义功能。将使用在第4章和第7章中填充的数据集。
执行SQL查询
以下是执行SQL查询的步骤:
1. 返回按数量排序的前五本书:
GET _sql?format=txt
{ "query": "SELECT * FROM mybooks ORDER BY quantity DESC LIMIT 5" }
如果一切正常,将得到以下结果:
date | description | position | price | quantity | title | uuid
------------------------+------------------------------------+---------------+---------------+---------------+---------------+---------------
2015-10-22T00:00:00.000Z|Joe Testere nice guy |1 |4.3 |50 |Joe Tester |11111
2016-06-12T00:00:00.000Z|Bill Testere nice guy |2 |5.0 |34 |Bill Baloney |22222
2017-09-21T00:00:00.000Z|Bill is not nice guy |3 |6.0 |33 |Bill Klingon |33333
- 返回按价格降序排列的记录,每页5条,以JSON格式返回:
GET _sql?format=json
{ "query": """SELECT in_stock, date, name, age, price
FROM "index-agg" ORDER BY price DESC""",
"fetch_size": 5 }
如果一切正常,将得到以下结果:
{ "columns" : [
{"name" : "in_stock", "type" : "boolean"},
{"name" : "date", "type" : "datetime"},
{"name" : "name", "type" : "text"},
{"name" : "age", "type" : "long"},
{"name" : "price", "type" : "float"}
],
"rows" : [
[false, "2013-01-26T16:46:02.828Z", "Bova", 48, 99.983025],
[true, "2013-09-11T16:46:01.837Z", "Achilles", 87, 99.91804],
[false, "2015-08-05T16:46:02.666Z", "Silver Samurai", 44, 99.86804],
[false, "2012-10-10T16:46:02.964Z", "Dweller-in-Darkness", 94, 99.78011],
[true, "2018-12-08T16:46:02.849Z", "Sunfire", 6, 99.62338 ]
],
"cursor" :
"x8qyAwFaAXN4RkdsdVkyeDFaR1ZmWTI5dWRHVjRkRjkxZFdsa0RYRjFaWEo1UVc1a1JtVjBZMmdCRmw4MlRuTTRRMloyVVZSaGMzWXlNR1ZRZVVSdFNIY0FBQUFBQUFBRmhSWTBVMnh3Tmpkb1ZGUmZiVXBpUkcxZmIwcG5iRTlS/////w8FAWYIaW5fc3RvY2sBB2Jvb2xlYW4AAAFmBGRhdGUBCGRhdGV0aW1lAAABZgRuYW1lAQR0ZXh0AAABZgNhZ2UBBGxvbmcAAAFmBXByaWNlAQVmbG9hdAAAAR8=" }
X-Pack提供对使用 _sql 端点的支持,允许将标准SQL查询转换为弹性搜索查询,并在所需的索引上运行。REST API的格式为: POST _sql 。可以通过查询参数传递 format 参数来自定义返回的响应,它接受以下可能的值: csv 、 json 、 tsv 、 txt 、 yaml 、 cbor 和 smile 。 POST 主体内的JSON对象可以包含以下参数:
| 参数 | 描述 |
| ---- | ---- |
| query | 包含要执行的SQL的必填字段。 |
| params | 可选的数组值,用于替换查询中的“值占位符”( ? )。 |
| fetch_size | 单个响应中返回的最大行数(默认1000)。 |
| filter | 可选的查询DSL,用于过滤值。 |
| runtime_mappings | 用于在运行时计算额外字段的键和脚本的字典。 |
fetch_size 允许使用分页,返回一个游标,直到所有记录都被获取。
通过以上介绍,我们了解了如何将弹性搜索与MongoDB集成,以及X-Pack的索引生命周期管理、自动滚动索引和SQL Rest API等功能的使用方法。这些功能可以帮助我们更高效地管理和查询数据,满足不同场景下的需求。
弹性搜索与MongoDB集成及X-Pack功能应用
使用SQL via JDBC
除了使用SQL Rest API,还可以通过JDBC使用X - Pack的SQL功能。通过JDBC连接,能让Java应用程序更方便地与Elasticsearch进行交互。
准备工作
- 确保有一个运行正常的Elasticsearch实例,且X - Pack已启用SQL支持。
- 下载并配置Elasticsearch的JDBC驱动。可以从Maven仓库获取合适版本的驱动依赖。
示例代码
以下是一个简单的Java代码示例,展示如何通过JDBC连接到Elasticsearch并执行SQL查询:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class ElasticsearchJdbcExample {
public static void main(String[] args) {
try {
// 加载JDBC驱动
Class.forName("com.elastic.clients.jdbc.ElasticDriver");
// 建立连接
String url = "jdbc:elastic://http://localhost:9200";
Connection connection = DriverManager.getConnection(url);
// 创建Statement对象
Statement statement = connection.createStatement();
// 执行SQL查询
String sql = "SELECT * FROM mybooks ORDER BY quantity DESC LIMIT 5";
ResultSet resultSet = statement.executeQuery(sql);
// 处理查询结果
while (resultSet.next()) {
System.out.println("Title: " + resultSet.getString("title") +
", Quantity: " + resultSet.getInt("quantity"));
}
// 关闭资源
resultSet.close();
statement.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过上述代码,我们可以看到通过JDBC连接到Elasticsearch并执行SQL查询的基本流程。首先加载驱动,然后建立连接,接着创建 Statement 对象执行查询,最后处理结果并关闭资源。
使用X - Pack安全
X - Pack的安全功能为Elasticsearch提供了强大的安全防护,包括用户认证、授权、加密等。
用户认证
可以通过创建用户并分配角色来实现用户认证。以下是创建用户和角色的步骤:
1. 创建角色
PUT _security/role/my_role
{
"cluster": ["monitor"],
"indices": [
{
"names": ["my_index*"],
"privileges": ["read"]
}
]
}
这个角色具有监控集群的权限,并且对以 my_index 开头的索引有读取权限。
2. 创建用户
PUT _security/user/my_user
{
"password": "my_password",
"roles": ["my_role"],
"full_name": "My User",
"email": "myuser@example.com"
}
创建了一个名为 my_user 的用户,分配了 my_role 角色,并设置了密码、全名和邮箱。
授权
授权通过角色来实现,角色定义了用户对集群和索引的操作权限。可以根据不同的业务需求创建不同的角色,然后将角色分配给用户。
加密
可以通过配置SSL/TLS来实现数据传输的加密。在Elasticsearch的配置文件中添加以下配置:
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
xpack.security.transport.ssl.keystore.path: /path/to/keystore.p12
xpack.security.transport.ssl.truststore.path: /path/to/truststore.p12
通过上述配置,启用了传输层的SSL/TLS加密,确保数据在传输过程中的安全性。
使用警报来监控数据事件
X - Pack的警报功能可以帮助我们监控数据事件,当满足特定条件时触发警报。
创建监视器
可以通过Kibana的警报管理界面或者API来创建监视器。以下是一个通过API创建监视器的示例:
PUT _watcher/watch/my_watcher
{
"trigger": {
"schedule": {
"interval": "1m"
}
},
"input": {
"search": {
"request": {
"indices": ["my_index"],
"body": {
"query": {
"range": {
"value": {
"gt": 100
}
}
}
}
}
}
},
"condition": {
"compare": {
"ctx.payload.hits.total.value": {
"gt": 0
}
}
},
"actions": {
"send_email": {
"email": {
"to": "admin@example.com",
"subject": "Alert: High values detected",
"body": "There are documents with value greater than 100 in my_index."
}
}
}
}
上述监视器每分钟执行一次搜索查询,当 my_index 中存在 value 字段大于100的文档时,触发警报并发送邮件给 admin@example.com 。
监控流程
graph LR
A[创建监视器] --> B[定时触发]
B --> C[执行搜索查询]
C --> D{是否满足条件}
D -- 是 --> E[触发警报动作]
D -- 否 --> B
通过以上步骤,我们可以利用X - Pack的警报功能对数据进行实时监控,及时发现异常情况。
总结
本文详细介绍了如何将Elasticsearch与MongoDB集成,以及X - Pack的多个重要功能。在集成方面,展示了如何从Elasticsearch获取数据并批量写入MongoDB,提高了数据处理的效率。在X - Pack功能上,涵盖了索引生命周期管理(ILM)、自动滚动索引、SQL Rest API、SQL via JDBC、X - Pack安全和警报监控等内容。
- ILM :通过设置策略和模板,实现了对索引生命周期的自动化管理,包括索引的创建、滚动、删除等操作,有助于优化存储和提高查询性能。
- SQL功能 :无论是通过Rest API还是JDBC,都能让用户使用熟悉的SQL语言对Elasticsearch进行查询,降低了使用门槛,方便了数据的检索和分析。
- 安全功能 :提供了用户认证、授权和加密等机制,保障了数据的安全性和访问的可控性。
- 警报功能 :可以实时监控数据事件,当满足特定条件时及时触发警报,帮助用户及时发现和处理异常情况。
通过合理运用这些功能,能够更好地管理和利用数据,满足不同场景下的业务需求,提升数据处理和分析的效率与质量。
1195

被折叠的 条评论
为什么被折叠?



