46、弹性搜索与MongoDB集成及X-Pack功能应用

弹性搜索与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 }
  1. 扩展索引模板,添加之前创建的策略:
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 }
  1. 创建数据流,添加之前创建的策略:
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 }
  1. 向索引添加一条记录以强制创建索引:
POST timeseries/_doc
{ "message": "this is a message",
  "@timestamp": "2022-03-16T15:03:03" }

结果如下:

{ "_index" : ".ds-timeseries-2022.03.15-000001",
  "_id" : "osN7cHkBtG0xN2Ak2au2", … truncated … }
  1. 检查策略是否应用于 .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          
  1. 返回按价格降序排列的记录,每页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进行查询,降低了使用门槛,方便了数据的检索和分析。
  • 安全功能 :提供了用户认证、授权和加密等机制,保障了数据的安全性和访问的可控性。
  • 警报功能 :可以实时监控数据事件,当满足特定条件时及时触发警报,帮助用户及时发现和处理异常情况。

通过合理运用这些功能,能够更好地管理和利用数据,满足不同场景下的业务需求,提升数据处理和分析的效率与质量。

【源码免费下载链接】:https://renmaiwang.cn/s/0e6hs 数字信号处理实习实验二离散信号的频谱分析MATLAB本实验旨在掌握离散时间信号的DTFT和DFT的MATLAB实现,熟悉DTFT和DFT之间的关系,了解信号不同变形的DFT原信号DFT之间的关系,掌握系统函数和频率响应之间的关系。一、DTFT和DFT的概念DTFT(Discrete-Time Fourier Transform)是对离散时间信号进行频谱分析的重要工具,它可以将时域信号转换为频域信号,从而分析信号的频率特性。DFT(Discrete Fourier Transform)是DTFT的一种近似实现形式,它可以将有限长信号转换为频域信号。二、实验目的1. 掌握离散时间信号的DTFT和DFT的MATLAB实现2. 熟悉DTFT和DFT之间的关系3. 了解信号不同变形的DFT原信号DFT之间的关系4. 掌握系统函数和频率响应之间的关系三、实验内容1. 自定义一个长度为8点的信号,信号幅度值也由自己任意指定,对该信号作DTFT,分别画出幅度谱和相位谱2. 对信号分别做8点、16点、32点DFT,分别DTFT合并作图并比较DFTDTFT之间的关系3. 在信号每两个相邻样本之间插入一个零值,扩充为16点序列,作DFT,画出幅度谱和相位谱,并原序列的DFT进行比较4. 将信号以8为周期扩展,得到长为16的两个周期,作DFT,画出幅度谱和相位谱,并原序列的DFT进行比较5. 已知离散时间系统差分方程为y(n)-0.5y(n-1)+0.06y(n-2)=x(n)+x(n-1),求出并画出其频率响应6. 求该系统系统函数,并画极零点图,并通过freqz函数求频率响应四、设计流程1. 自定义序列为x=[1,2,3,4,5,8,9,7]2. 使用MATLAB实现DTFT和DFT3. 画出幅度谱和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值