如何在 Easysearch 中使用 Rollup 优化时序数据的存储和查询
背景
在现代数据驱动的世界中,时序数据的处理变得越来越重要。无论是监控系统、日志分析,还是物联网设备的数据收集,时序数据都占据了大量的存储空间。随着时间的推移,这些数据的存储成本和管理复杂度也在不断增加。
为了解决这一问题,Rollup 技术应运而生。本文将带你深入了解 Rollup 的概念、优势以及如何在 Easysearch 中使用 Rollup 来优化时序数据的存储和查询。
什么是 Rollup?
Rollup 是一种数据聚合技术,主要用于处理时序数据。它通过将细粒度的原始数据汇总为粗粒度的数据,从而减少存储空间并提高查询效率。简单来说,Rollup 可以将大量的详细数据压缩为更小的、更具代表性的数据集,同时保留关键的业务指标。
Rollup 的优势
- 降低存储成本:通过汇总数据,Rollup 可以显著减少历史数据的存储空间,从而降低存储成本。
- 提高查询性能:汇总后的数据量更小,查询速度更快,尤其是在处理大规模历史数据时,性能提升尤为明显。
- 无缝集成:Easysearch 的 Rollup 功能支持直接查询原始索引,业务代码无需修改,用户无感知。
- 自动化管理:Rollup 任务可以自动滚动生成新的索引,无需手动干预,简化了数据管理流程。
Rollup 的使用场景
Rollup 特别适用于以下场景:
- 监控系统:监控系统产生的指标数据通常非常详细,但随着时间推移,这些数据的价值逐渐降低。通过 Rollup,可以将这些数据汇总为更粗粒度的指标,保留关键信息的同时减少存储压力。
- 日志分析:日志数据通常包含大量的细节信息,但随着时间的推移,这些细节信息的重要性逐渐降低。Rollup 可以帮助你将日志数据汇总为更高层次的统计信息,便于长期存储和分析。
- 物联网数据:物联网设备产生的数据量巨大,且大部分数据在短期内具有较高的分析价值。通过 Rollup,可以将这些数据汇总为更粗粒度的形式,便于长期存储和查询。
使用 Rollup 的先决条件
在使用 Rollup 之前,需要满足以下条件:
安装索引生命周期管理插件:Rollup 功能是索引生命周期管理插件的一部分,因此必须安装该插件。
源索引必须包含 date 类型字段:Rollup 依赖于时间字段来进行数据聚合,因此源索引必须包含一个 date 类型的字段。
Easysearch 中的 Rollup 功能
Easysearch 提供了强大的 Rollup 功能,支持多种聚合类型,并且可以自动滚动生成新的索引。下面我们将详细介绍如何在 Easysearch 中使用 Rollup。
支持的聚合类型
Easysearch 的 Rollup 功能支持以下聚合类型:
- 数值类型字段:
avg
、sum
、max
、min
、value_count
、percentiles
- keyword 类型字段:
terms
聚合 - date 类型字段:
date_histogram
和date_range
聚合
Rollup 的核心参数详解
在配置 Rollup 任务时,以下几个参数至关重要:
1. metrics
参数:定义需要聚合的数值字段
metrics
参数用于指定哪些数值字段需要进行聚合计算。Rollup 任务会对这些字段进行指定的聚合操作(如 avg
、sum
、max
、min
、value_count
、percentiles
),并将结果存储到目标索引中。
示例:
"metrics": [
"payload.elasticsearch.index_stats.*"
]
在这个例子中,metrics
指定了对 payload.elasticsearch.index_stats
下的所有字段进行聚合。
2. attributes
参数:保留原始数据的非聚合字段
attributes
参数用于指定哪些字段需要原封不动地保留在 Rollup 结果中。这些字段不会被聚合,而是直接复制到目标索引中。
示例:
"attributes": [
"agent.*",
"metadata.*"
]
在这个例子中,attributes
指定了所有以 agent.
和 metadata.
开头的字段都会被保留到 Rollup 结果中。
3. exclude
参数:排除不需要处理的字段
exclude
参数用于排除某些字段,使其不参与 Rollup 任务。这些字段既不会被聚合,也不会被保留到目标索引中。
示例:
"exclude": ["payload.elasticsearch.index_stats.routing.*"]
在这个例子中,exclude
指定了 payload.elasticsearch.index_stats.routing
下的所有字段都不会被处理。
4. filter
参数:过滤源数据
filter
参数用于过滤源数据,只有符合过滤条件的文档才会被 Rollup 任务处理。这个参数可以帮助你减少需要处理的数据量,从而提高 Rollup 任务的效率。
示例:
"filter": {
"metadata.name": "index_stats"
}
在这个例子中,filter
指定了只有 metadata.name
字段值为 index_stats
的文档才会被 Rollup 任务处理。
5. identity
参数:定义分组字段
identity
参数用于指定哪些字段作为分组条件。Rollup 任务会根据这些字段的值对数据进行分组,然后在每个分组内进行聚合计算。
功能:
- 定义数据分组的字段。
- 支持多个字段的组合,用于创建唯一的分组键。
- 常用于标识数据的来源或类别。
示例:
"identity": [
"metadata.labels.cluster_id",
"metadata.labels.index_id",
"metadata.labels.index_name",
"metadata.category",
"payload.elasticsearch.index_stats.index_info.health"
]
在这个例子中,identity
指定了多个字段作为分组条件。Rollup 任务会根据这些字段的值对数据进行分组,然后在每个分组内进行聚合计算。
6. interval
参数:定义时间聚合间隔
interval
参数用于指定时间聚合的间隔。Rollup 任务会根据这个间隔将数据按时间分桶,然后在每个时间桶内进行聚合计算。
功能:
- 定义时间聚合的粒度。
- 支持多种时间单位,如
1m
(1 分钟)、1h
(1 小时)、1d
(1 天)等。 - 常用于按时间维度汇总数据。
示例:
"interval": "1m"
在这个例子中,interval
指定了时间聚合的间隔为 1 分钟。Rollup 任务会每分钟对数据进行一次聚合。
1.10 版本的新特性
从 Easysearch 1.10.0 版本开始,Rollup 功能引入了一些新特性,进一步增强了其灵活性和易用性。
1. 支持 date_range
聚合
在 1.10.0 版本中,Rollup 增加了对 原始索引使用 date_range
聚合的支持。这意味着你可以在原始索引根据日期范围对数据进行聚合,而不仅仅是固定的时间间隔。
示例:
"date_range": {
"field": "@timestamp",
"ranges": [
{ "from": "now-1d/d", "to": "now" },
{ "from": "now-7d/d", "to": "now-1d/d" }
]
}
2. 通配符方式批量启动/停止 Rollup Job
在 1.10.0 版本中,你可以使用通配符批量启动或停止 Rollup 任务。这大大简化了任务管理的操作。
示例:
POST _rollup/jobs/rollup*/_start
POST _rollup/jobs/rollup*/_stop
3. 设置 Rollup 索引自动滚动的条数
你可以通过设置 rollup.max_docs
参数,控制 Rollup 索引自动滚动的条数。当索引中的文档数量达到设定值时,系统会自动创建一个新的 Rollup 索引。
示例:
PUT /_cluster/settings
{
"transient": {
"rollup.max_docs": 10000000
}
}
4. 新增 ROLLUP_SEARCH_MAX_COUNT
配置
在 1.10.0 版本中,新增了 ROLLUP_SEARCH_MAX_COUNT
配置项,用于控制 Rollup 在运行 Job 时收集历史数据的最大并发分片请求数。这个配置项可以帮助你优化 Rollup 任务的性能,并避免集群资源过载。
功能:
- 控制并发请求数:限制 Rollup 任务在执行搜索请求时的最大并发分片请求数。
- 动态调整:支持在集群运行时动态调整,无需重启集群。
- 默认值:
2
,即默认情况下,Rollup 任务最多会同时发送 2 个并发分片请求。
示例:
PUT /_cluster/settings
{
"transient": {
"rollup.search.max_count": 2
}
}
在这个例子中,ROLLUP_SEARCH_MAX_COUNT
被设置为 2
,表示 Rollup 任务在执行搜索请求时,最多会同时发送 2 个并发分片请求。
配置建议:
- 小规模集群:建议设置为较小的值(如
2
),以避免资源竞争。 - 大规模集群:可以适当增加该值(如
4
),以提高并发性能。 - 动态调整:根据集群负载情况动态调整该值,以优化性能和资源利用率。
创建 Rollup 任务的完整示例
以下是一个完整的 Rollup 任务配置示例,展示了 metrics
、attributes
、exclude
和 filter
参数的综合使用:
PUT _rollup/jobs/rollup1
{
"rollup": {
"source_index": ".infini_metrics",
"target_index": "rollup1_{{ctx.source_index}}",
"timestamp": "timestamp",
"continuous": true,
"page_size": 1000,
"cron": "*/10 1-23 * * *",
"timezone": "UTC+8",
"stats": [
{
"max": {}
},
{
"value_count": {}
}
],
"interval": "1m",
"identity": [
"metadata.labels.cluster_id",
"metadata.labels.index_id",
"metadata.labels.index_name",
"metadata.category",
"payload.elasticsearch.index_stats.index_info.health"
],
"attributes": [
"agent.*",
"metadata.*"
],
"metrics": [
"payload.elasticsearch.index_stats.*"
],
"exclude": ["payload.elasticsearch.index_stats.routing.*"],
"filter": {
"metadata.name": "index_stats"
}
}
}
如何使用 Rollup 索引
从 1.10.0 版本开始,索引生命周期插件不再默认启用 rollup 搜索功能,如果想使用搜索 rollup 搜索功能,需要设置
PUT /_cluster/settings
{
"transient": {
"rollup.search.enabled": true
}
}
无需特意搜索 rollup 索引,只需使用标准的 _search API 对原始目标索引进行搜索。需要注意的是,查询时必须符合目标索引的约束条件。
以下是一个使用 Rollup 索引的示例:
GET target-test/_search
{
"size": 0,
"aggs": {
"a": {
"date_histogram": {
"field": "@timestamp",
"fixed_interval": "1h"
}
},
"total_passenger_count": {
"sum": {
"field": "passenger_count"
}
}
}
}
总结
Rollup 是处理时序数据的强大工具,能够有效降低存储成本并提高查询性能。Easysearch 的 Rollup 功能不仅支持多种聚合类型,还提供了自动滚动索引、无缝查询等特性,极大地简化了时序数据的管理和分析流程。通过合理配置 metrics
、attributes
、exclude
和 filter
参数,你可以灵活地控制 Rollup 任务的行为,从而高效地处理时序数据。
如果你正在处理大量的时序数据,不妨尝试使用 Rollup 来优化你的数据存储和查询。通过本文的介绍,相信你已经对 Rollup 有了深入的了解。赶快动手试试吧,体验 Rollup 带来的高效与便捷!
更详细的使用文档可在 官网 查看
关于 Easysearch
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://infinilabs.cn/docs/latest/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
背景
在现代数据驱动的世界中,时序数据的处理变得越来越重要。无论是监控系统、日志分析,还是物联网设备的数据收集,时序数据都占据了大量的存储空间。随着时间的推移,这些数据的存储成本和管理复杂度也在不断增加。
为了解决这一问题,Rollup 技术应运而生。本文将带你深入了解 Rollup 的概念、优势以及如何在 Easysearch 中使用 Rollup 来优化时序数据的存储和查询。
什么是 Rollup?
Rollup 是一种数据聚合技术,主要用于处理时序数据。它通过将细粒度的原始数据汇总为粗粒度的数据,从而减少存储空间并提高查询效率。简单来说,Rollup 可以将大量的详细数据压缩为更小的、更具代表性的数据集,同时保留关键的业务指标。
Rollup 的优势
- 降低存储成本:通过汇总数据,Rollup 可以显著减少历史数据的存储空间,从而降低存储成本。
- 提高查询性能:汇总后的数据量更小,查询速度更快,尤其是在处理大规模历史数据时,性能提升尤为明显。
- 无缝集成:Easysearch 的 Rollup 功能支持直接查询原始索引,业务代码无需修改,用户无感知。
- 自动化管理:Rollup 任务可以自动滚动生成新的索引,无需手动干预,简化了数据管理流程。
Rollup 的使用场景
Rollup 特别适用于以下场景:
- 监控系统:监控系统产生的指标数据通常非常详细,但随着时间推移,这些数据的价值逐渐降低。通过 Rollup,可以将这些数据汇总为更粗粒度的指标,保留关键信息的同时减少存储压力。
- 日志分析:日志数据通常包含大量的细节信息,但随着时间的推移,这些细节信息的重要性逐渐降低。Rollup 可以帮助你将日志数据汇总为更高层次的统计信息,便于长期存储和分析。
- 物联网数据:物联网设备产生的数据量巨大,且大部分数据在短期内具有较高的分析价值。通过 Rollup,可以将这些数据汇总为更粗粒度的形式,便于长期存储和查询。
使用 Rollup 的先决条件
在使用 Rollup 之前,需要满足以下条件:
安装索引生命周期管理插件:Rollup 功能是索引生命周期管理插件的一部分,因此必须安装该插件。
源索引必须包含 date 类型字段:Rollup 依赖于时间字段来进行数据聚合,因此源索引必须包含一个 date 类型的字段。
Easysearch 中的 Rollup 功能
Easysearch 提供了强大的 Rollup 功能,支持多种聚合类型,并且可以自动滚动生成新的索引。下面我们将详细介绍如何在 Easysearch 中使用 Rollup。
支持的聚合类型
Easysearch 的 Rollup 功能支持以下聚合类型:
- 数值类型字段:
avg
、sum
、max
、min
、value_count
、percentiles
- keyword 类型字段:
terms
聚合 - date 类型字段:
date_histogram
和date_range
聚合
Rollup 的核心参数详解
在配置 Rollup 任务时,以下几个参数至关重要:
1. metrics
参数:定义需要聚合的数值字段
metrics
参数用于指定哪些数值字段需要进行聚合计算。Rollup 任务会对这些字段进行指定的聚合操作(如 avg
、sum
、max
、min
、value_count
、percentiles
),并将结果存储到目标索引中。
示例:
"metrics": [
"payload.elasticsearch.index_stats.*"
]
在这个例子中,metrics
指定了对 payload.elasticsearch.index_stats
下的所有字段进行聚合。
2. attributes
参数:保留原始数据的非聚合字段
attributes
参数用于指定哪些字段需要原封不动地保留在 Rollup 结果中。这些字段不会被聚合,而是直接复制到目标索引中。
示例:
"attributes": [
"agent.*",
"metadata.*"
]
在这个例子中,attributes
指定了所有以 agent.
和 metadata.
开头的字段都会被保留到 Rollup 结果中。
3. exclude
参数:排除不需要处理的字段
exclude
参数用于排除某些字段,使其不参与 Rollup 任务。这些字段既不会被聚合,也不会被保留到目标索引中。
示例:
"exclude": ["payload.elasticsearch.index_stats.routing.*"]
在这个例子中,exclude
指定了 payload.elasticsearch.index_stats.routing
下的所有字段都不会被处理。
4. filter
参数:过滤源数据
filter
参数用于过滤源数据,只有符合过滤条件的文档才会被 Rollup 任务处理。这个参数可以帮助你减少需要处理的数据量,从而提高 Rollup 任务的效率。
示例:
"filter": {
"metadata.name": "index_stats"
}
在这个例子中,filter
指定了只有 metadata.name
字段值为 index_stats
的文档才会被 Rollup 任务处理。
5. identity
参数:定义分组字段
identity
参数用于指定哪些字段作为分组条件。Rollup 任务会根据这些字段的值对数据进行分组,然后在每个分组内进行聚合计算。
功能:
- 定义数据分组的字段。
- 支持多个字段的组合,用于创建唯一的分组键。
- 常用于标识数据的来源或类别。
示例:
"identity": [
"metadata.labels.cluster_id",
"metadata.labels.index_id",
"metadata.labels.index_name",
"metadata.category",
"payload.elasticsearch.index_stats.index_info.health"
]
在这个例子中,identity
指定了多个字段作为分组条件。Rollup 任务会根据这些字段的值对数据进行分组,然后在每个分组内进行聚合计算。
6. interval
参数:定义时间聚合间隔
interval
参数用于指定时间聚合的间隔。Rollup 任务会根据这个间隔将数据按时间分桶,然后在每个时间桶内进行聚合计算。
功能:
- 定义时间聚合的粒度。
- 支持多种时间单位,如
1m
(1 分钟)、1h
(1 小时)、1d
(1 天)等。 - 常用于按时间维度汇总数据。
示例:
"interval": "1m"
在这个例子中,interval
指定了时间聚合的间隔为 1 分钟。Rollup 任务会每分钟对数据进行一次聚合。
1.10 版本的新特性
从 Easysearch 1.10.0 版本开始,Rollup 功能引入了一些新特性,进一步增强了其灵活性和易用性。
1. 支持 date_range
聚合
在 1.10.0 版本中,Rollup 增加了对 原始索引使用 date_range
聚合的支持。这意味着你可以在原始索引根据日期范围对数据进行聚合,而不仅仅是固定的时间间隔。
示例:
"date_range": {
"field": "@timestamp",
"ranges": [
{ "from": "now-1d/d", "to": "now" },
{ "from": "now-7d/d", "to": "now-1d/d" }
]
}
2. 通配符方式批量启动/停止 Rollup Job
在 1.10.0 版本中,你可以使用通配符批量启动或停止 Rollup 任务。这大大简化了任务管理的操作。
示例:
POST _rollup/jobs/rollup*/_start
POST _rollup/jobs/rollup*/_stop
3. 设置 Rollup 索引自动滚动的条数
你可以通过设置 rollup.max_docs
参数,控制 Rollup 索引自动滚动的条数。当索引中的文档数量达到设定值时,系统会自动创建一个新的 Rollup 索引。
示例:
PUT /_cluster/settings
{
"transient": {
"rollup.max_docs": 10000000
}
}
4. 新增 ROLLUP_SEARCH_MAX_COUNT
配置
在 1.10.0 版本中,新增了 ROLLUP_SEARCH_MAX_COUNT
配置项,用于控制 Rollup 在运行 Job 时收集历史数据的最大并发分片请求数。这个配置项可以帮助你优化 Rollup 任务的性能,并避免集群资源过载。
功能:
- 控制并发请求数:限制 Rollup 任务在执行搜索请求时的最大并发分片请求数。
- 动态调整:支持在集群运行时动态调整,无需重启集群。
- 默认值:
2
,即默认情况下,Rollup 任务最多会同时发送 2 个并发分片请求。
示例:
PUT /_cluster/settings
{
"transient": {
"rollup.search.max_count": 2
}
}
在这个例子中,ROLLUP_SEARCH_MAX_COUNT
被设置为 2
,表示 Rollup 任务在执行搜索请求时,最多会同时发送 2 个并发分片请求。
配置建议:
- 小规模集群:建议设置为较小的值(如
2
),以避免资源竞争。 - 大规模集群:可以适当增加该值(如
4
),以提高并发性能。 - 动态调整:根据集群负载情况动态调整该值,以优化性能和资源利用率。
创建 Rollup 任务的完整示例
以下是一个完整的 Rollup 任务配置示例,展示了 metrics
、attributes
、exclude
和 filter
参数的综合使用:
PUT _rollup/jobs/rollup1
{
"rollup": {
"source_index": ".infini_metrics",
"target_index": "rollup1_{{ctx.source_index}}",
"timestamp": "timestamp",
"continuous": true,
"page_size": 1000,
"cron": "*/10 1-23 * * *",
"timezone": "UTC+8",
"stats": [
{
"max": {}
},
{
"value_count": {}
}
],
"interval": "1m",
"identity": [
"metadata.labels.cluster_id",
"metadata.labels.index_id",
"metadata.labels.index_name",
"metadata.category",
"payload.elasticsearch.index_stats.index_info.health"
],
"attributes": [
"agent.*",
"metadata.*"
],
"metrics": [
"payload.elasticsearch.index_stats.*"
],
"exclude": ["payload.elasticsearch.index_stats.routing.*"],
"filter": {
"metadata.name": "index_stats"
}
}
}
如何使用 Rollup 索引
从 1.10.0 版本开始,索引生命周期插件不再默认启用 rollup 搜索功能,如果想使用搜索 rollup 搜索功能,需要设置
PUT /_cluster/settings
{
"transient": {
"rollup.search.enabled": true
}
}
无需特意搜索 rollup 索引,只需使用标准的 _search API 对原始目标索引进行搜索。需要注意的是,查询时必须符合目标索引的约束条件。
以下是一个使用 Rollup 索引的示例:
GET target-test/_search
{
"size": 0,
"aggs": {
"a": {
"date_histogram": {
"field": "@timestamp",
"fixed_interval": "1h"
}
},
"total_passenger_count": {
"sum": {
"field": "passenger_count"
}
}
}
}
总结
Rollup 是处理时序数据的强大工具,能够有效降低存储成本并提高查询性能。Easysearch 的 Rollup 功能不仅支持多种聚合类型,还提供了自动滚动索引、无缝查询等特性,极大地简化了时序数据的管理和分析流程。通过合理配置 metrics
、attributes
、exclude
和 filter
参数,你可以灵活地控制 Rollup 任务的行为,从而高效地处理时序数据。
如果你正在处理大量的时序数据,不妨尝试使用 Rollup 来优化你的数据存储和查询。通过本文的介绍,相信你已经对 Rollup 有了深入的了解。赶快动手试试吧,体验 Rollup 带来的高效与便捷!
更详细的使用文档可在 官网 查看
关于 Easysearch
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://infinilabs.cn/docs/latest/easysearch
收起阅读 »作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
从 Elastic 迁移到 Easysearch 指引
从 Elasticsearch 迁移到 Easysearch 需要考虑多个方面,这取决于当前使用的 Elasticsearch 版本、能容忍的停机时间、应用需求等。在此背景下,我们梳理了一下通用的升级指引,方便大家进行迁移工作。
迁移路径
Elasticsearch 版本 | 快照兼容 | 推荐升级方法 |
---|---|---|
5.x | ❌ | 使用 INFINI Console 迁移 |
6.x | ✅ | 快照恢复迁移 |
7.0.0 - 7.10.2 | ✅ | 快照恢复迁移 |
>7.11.0 | ❌ | 使用 INFINI Console 迁移 |
之前有同事做过相关测试,详情请移步这里。
快照恢复迁移
- 部署新的 Easysearch 集群,如果有使用插件(如 IK),也一并安装。
- 将备份仓库注册到 Easysearch 集群。
- 在 Easysearch 中设置需要使用的用户名和密码信息。
- 原 Elasticsearch 集群进行快照备份。
- 在 Easysearch 集群中进行备份还原。
- 另部署一套应用连接 Easysearch 集群,进行数据、功能验证。
- 停止应用写入新的数据到 Elasticsearch。
- 原 Elasticsearch 集群进行快照备份。
- 在 Easysearch 集群中进行备份还原。
- 再次使用应用验证数据、功能正常。
- 切换,老应用下线使用新应用或者老应用修改地址连接 Easysearch 集群。
INFINI Console 迁移
- 部署新的 Easysearch 集群及其插件(如 IK)。
- 部署 INFINI Console、Gateway 程序。
- 将 Elasticsearch 和 Easysearch 注册到 INFINI Console 中。
- 在 Easysearch 中设置需要使用的用户名和密码信息。
- 建立数据迁移任务,对业务索引进行迁移,建议启用压缩功能。
- 另部署一套应用连接 Easysearch 集群,进行数据、功能验证。
- 停止应用写入新的数据到 Elasticsearch。
- 再次建立数据迁移任务,设置条件,只迁移增量数据。
- 再次使用应用验证数据、功能正常。
- 切换,老应用下线使用新应用或者老应用修改地址连接 Easysearch 集群。
客户端调整
如果要继续使用 Java High Level REST Client,建议将版本调整到 7.10.2 。当然更建议的是使用 Easysearch 的客户端,更轻更快,构建查询,跟搭积木一样简单。
开源事业
极限科技(INFINI Labs) 一直致力于为开发者和企业提供优质的开源工具,提升整个技术生态的活力。除了维护国内最流行的分词器 analysis-ik 和 analysis-pinyin ,也在不断推动更多高质量开源产品的诞生。
在极限科技成立三周年之际,公司宣布以下产品和工具已全面开源:
以上开源软件都可以在 Github 上面找到:https://github.com/infinilabs
欢迎大家一起参与到开源工具的维护、贡献当中来,别忘了 Star🌟 支持一下!!!
如果您对迁移过程有任何疑问,欢迎与我讨论。
从 Elasticsearch 迁移到 Easysearch 需要考虑多个方面,这取决于当前使用的 Elasticsearch 版本、能容忍的停机时间、应用需求等。在此背景下,我们梳理了一下通用的升级指引,方便大家进行迁移工作。
迁移路径
Elasticsearch 版本 | 快照兼容 | 推荐升级方法 |
---|---|---|
5.x | ❌ | 使用 INFINI Console 迁移 |
6.x | ✅ | 快照恢复迁移 |
7.0.0 - 7.10.2 | ✅ | 快照恢复迁移 |
>7.11.0 | ❌ | 使用 INFINI Console 迁移 |
之前有同事做过相关测试,详情请移步这里。
快照恢复迁移
- 部署新的 Easysearch 集群,如果有使用插件(如 IK),也一并安装。
- 将备份仓库注册到 Easysearch 集群。
- 在 Easysearch 中设置需要使用的用户名和密码信息。
- 原 Elasticsearch 集群进行快照备份。
- 在 Easysearch 集群中进行备份还原。
- 另部署一套应用连接 Easysearch 集群,进行数据、功能验证。
- 停止应用写入新的数据到 Elasticsearch。
- 原 Elasticsearch 集群进行快照备份。
- 在 Easysearch 集群中进行备份还原。
- 再次使用应用验证数据、功能正常。
- 切换,老应用下线使用新应用或者老应用修改地址连接 Easysearch 集群。
INFINI Console 迁移
- 部署新的 Easysearch 集群及其插件(如 IK)。
- 部署 INFINI Console、Gateway 程序。
- 将 Elasticsearch 和 Easysearch 注册到 INFINI Console 中。
- 在 Easysearch 中设置需要使用的用户名和密码信息。
- 建立数据迁移任务,对业务索引进行迁移,建议启用压缩功能。
- 另部署一套应用连接 Easysearch 集群,进行数据、功能验证。
- 停止应用写入新的数据到 Elasticsearch。
- 再次建立数据迁移任务,设置条件,只迁移增量数据。
- 再次使用应用验证数据、功能正常。
- 切换,老应用下线使用新应用或者老应用修改地址连接 Easysearch 集群。
客户端调整
如果要继续使用 Java High Level REST Client,建议将版本调整到 7.10.2 。当然更建议的是使用 Easysearch 的客户端,更轻更快,构建查询,跟搭积木一样简单。
开源事业
极限科技(INFINI Labs) 一直致力于为开发者和企业提供优质的开源工具,提升整个技术生态的活力。除了维护国内最流行的分词器 analysis-ik 和 analysis-pinyin ,也在不断推动更多高质量开源产品的诞生。
在极限科技成立三周年之际,公司宣布以下产品和工具已全面开源:
以上开源软件都可以在 Github 上面找到:https://github.com/infinilabs
欢迎大家一起参与到开源工具的维护、贡献当中来,别忘了 Star🌟 支持一下!!!
如果您对迁移过程有任何疑问,欢迎与我讨论。
收起阅读 »Easysearch 可搜索快照功能,看这篇就够了
可搜索快照功能改变了我们对备份数据的查询方式。以往要查询备份数据时,要先找到备份数据所在的快照,然后在一个合适的环境中恢复快照,最后再发起请求查询数据。这个处理路径很长,而且很消耗时间。可搜索快照功能将大大简化该处理路径,节约时间。
角色设置
相信你对节点角色的概念已经有所熟悉。要启用可搜索快照功能,Easysearch 集群中必须至少有一个节点拥有 search 角色。参考设置如下。
node.roles: ["search"]
node.search.cache.size: 500mb
- node.roles: 指定节点角色,只有 search 角色的节点才能去搜索快照中的数据。
- node.search.cache.size: 执行快照搜索时,数据缓存大小。
混合角色设置,参考如下。
node.roles: ["master","data","search","ingest"]
node.search.cache.size: 500mb
创建快照
可搜索快照功能使用普通快照作为基础,创建快照命令不变。比如我创建且备份个 infini 索引。
# 创建 infini 索引
POST infini/_doc
{
"test":"Searchable snapshots"
}
# 创建快照备份 infini 索引
PUT _snapshot/my-fs-repository/1
{
"indices": "infini",
"include_global_state": false
}
创建快照索引
可搜索快照功能的核心是搜索快照中的索引,这一步是通过快照索引实现的。为了和集群中的普通索引区别开来,我们将实际存储在快照中的索引称为快照索引。通过使用 Easysearch 的 _restore API 并指定 remote_snapshot 存储类型来创建快照索引。
创建快照索引时,注意名称不能与当前索引名称重复。通常我们备份完索引后,可删除索引释放节点磁盘空间,创建快照索引时默认使用原来的名称。
# 删除 infini 索引释放磁盘空间
DELETE infini
# 创建快照索引,使用原索引名称
POST /_snapshot/my-fs-repository/1/_restore
{
"indices": "infini",
"include_global_state": false,
"include_aliases": false,
"storage_type": "remote_snapshot"
}
创建快照索引的命令和还原快照的命令非常相似,关键在于 storage_type 参数指定 remote_snapshot 存储类型。
如果要将快照中的全部索引都创建快照索引,可省略 indices 参数。
如果想在创建快照索引时指定不同的名字,参考下面的命令。
POST /_snapshot/my-fs-repository/1/_restore
{
"indices": "infini",
"include_global_state": false,
"include_aliases": false,
"storage_type": "remote_snapshot",
"rename_pattern": "(infini)",
"rename_replacement": "snapshot-$1"
}
- rename_pattern: 使用此选项指定索引匹配的正则表达式。使用捕获组重用索引名称的部分。
- rename_replacement: 使用 $0 包括整个匹配索引名称,使用 $1 包括第一个捕获组的内容,等等。
上述命令创建出来的快照索引名称是 snapshot-infini 。
经过上面一系列的操作,我已经拥有了两个快照索引。
搜索快照索引
我们通过搜索快照索引达到搜索快照数据的目的,令人开心的是搜索快照索引和搜索普通索引的语法完全一样。😀
常见问题
如何区分普通索引和快照索引呢?
我们可以通过索引的 settings 信息区分,快照索引的 settings 信息中有 store.type: remote_snapshot 信息,普通索引没有此信息。
快照索引能写入数据吗?
快照索引无法写入,数据仍然保持在快照格式中存储在存储库中,因此可搜索快照索引本质上是只读的。 任何尝试写入可搜索快照索引的操作都会导致错误。
快照索引不想要了怎么办?
直接删除,需要时再执行创建快照索引流程。此外快照在创建快照索引后,无法直接删除快照,要先删除快照索引。
如果您对上述内容有任何疑问,欢迎与我讨论。
可搜索快照功能改变了我们对备份数据的查询方式。以往要查询备份数据时,要先找到备份数据所在的快照,然后在一个合适的环境中恢复快照,最后再发起请求查询数据。这个处理路径很长,而且很消耗时间。可搜索快照功能将大大简化该处理路径,节约时间。
角色设置
相信你对节点角色的概念已经有所熟悉。要启用可搜索快照功能,Easysearch 集群中必须至少有一个节点拥有 search 角色。参考设置如下。
node.roles: ["search"]
node.search.cache.size: 500mb
- node.roles: 指定节点角色,只有 search 角色的节点才能去搜索快照中的数据。
- node.search.cache.size: 执行快照搜索时,数据缓存大小。
混合角色设置,参考如下。
node.roles: ["master","data","search","ingest"]
node.search.cache.size: 500mb
创建快照
可搜索快照功能使用普通快照作为基础,创建快照命令不变。比如我创建且备份个 infini 索引。
# 创建 infini 索引
POST infini/_doc
{
"test":"Searchable snapshots"
}
# 创建快照备份 infini 索引
PUT _snapshot/my-fs-repository/1
{
"indices": "infini",
"include_global_state": false
}
创建快照索引
可搜索快照功能的核心是搜索快照中的索引,这一步是通过快照索引实现的。为了和集群中的普通索引区别开来,我们将实际存储在快照中的索引称为快照索引。通过使用 Easysearch 的 _restore API 并指定 remote_snapshot 存储类型来创建快照索引。
创建快照索引时,注意名称不能与当前索引名称重复。通常我们备份完索引后,可删除索引释放节点磁盘空间,创建快照索引时默认使用原来的名称。
# 删除 infini 索引释放磁盘空间
DELETE infini
# 创建快照索引,使用原索引名称
POST /_snapshot/my-fs-repository/1/_restore
{
"indices": "infini",
"include_global_state": false,
"include_aliases": false,
"storage_type": "remote_snapshot"
}
创建快照索引的命令和还原快照的命令非常相似,关键在于 storage_type 参数指定 remote_snapshot 存储类型。
如果要将快照中的全部索引都创建快照索引,可省略 indices 参数。
如果想在创建快照索引时指定不同的名字,参考下面的命令。
POST /_snapshot/my-fs-repository/1/_restore
{
"indices": "infini",
"include_global_state": false,
"include_aliases": false,
"storage_type": "remote_snapshot",
"rename_pattern": "(infini)",
"rename_replacement": "snapshot-$1"
}
- rename_pattern: 使用此选项指定索引匹配的正则表达式。使用捕获组重用索引名称的部分。
- rename_replacement: 使用 $0 包括整个匹配索引名称,使用 $1 包括第一个捕获组的内容,等等。
上述命令创建出来的快照索引名称是 snapshot-infini 。
经过上面一系列的操作,我已经拥有了两个快照索引。
搜索快照索引
我们通过搜索快照索引达到搜索快照数据的目的,令人开心的是搜索快照索引和搜索普通索引的语法完全一样。😀
常见问题
如何区分普通索引和快照索引呢?
我们可以通过索引的 settings 信息区分,快照索引的 settings 信息中有 store.type: remote_snapshot 信息,普通索引没有此信息。
快照索引能写入数据吗?
快照索引无法写入,数据仍然保持在快照格式中存储在存储库中,因此可搜索快照索引本质上是只读的。 任何尝试写入可搜索快照索引的操作都会导致错误。
快照索引不想要了怎么办?
直接删除,需要时再执行创建快照索引流程。此外快照在创建快照索引后,无法直接删除快照,要先删除快照索引。
如果您对上述内容有任何疑问,欢迎与我讨论。
收起阅读 »Spring Boot 集成 Easysearch 完整指南
Easysearch 的很多用户都有这样的需要,之前是用的 ES,现在要迁移到 Easysearch,但是业务方使用的是 Spring Boot 集成的客户端,问是否能平滑迁移。
Easysearch 是完全兼容 Spring Boot 的,完全不用修改,本指南将探讨如何将 Spring Boot 和 ES 的 high-level 客户端 与 Easysearch 进行集成,涵盖从基础设置到实现 CRUD 操作和测试的所有内容。
服务器设置
首先,需要修改 Easysearch 节点的 easysearch.yml 文件,打开并配置这 2 个配置项:
elasticsearch.api_compatibility: true
#根据客户端版本配置版本号,我这里配置成 7.17.18
elasticsearch.api_compatibility_version: "7.17.18"
项目设置
然后,让我们设置 Maven 依赖。以下是 pom.xml
中的基本配置:
<properties>
<java.version>11</java.version>
<spring-data-elasticsearch.version>4.4.18</spring-data-elasticsearch.version>
<elasticsearch.version>7.17.18</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>${spring-data-elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
客户端连接配置
完全和连接 Elasticsearch 的方式一样,不用修改:
配置 src/main/resources/application.yml 文件
spring:
elasticsearch:
rest:
uris: https://localhost:9202
username: admin
password: xxxxxxxxxxx
ssl:
verification-mode: none
连接配置类
@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
@Value("${spring.elasticsearch.rest.uris}")
private String elasticsearchUrl;
@Value("${spring.elasticsearch.rest.username}")
private String username;
@Value("${spring.elasticsearch.rest.password}")
private String password;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, (x509Certificates, s) -> true)
.build();
RestClientBuilder builder = RestClient.builder(HttpHost.create(elasticsearchUrl))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider)
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE));
return new RestHighLevelClient(builder);
}
}
领域模型
使用 Spring 的 Elasticsearch 注解定义领域模型:
@Data
@Document(indexName = "products")
public class Product {
@Id
private String id;
@Field(type = FieldType.Text, name = "name")
private String name;
@Field(type = FieldType.Double, name = "price")
private Double price;
}
仓库层
创建继承 ElasticsearchRepository 的仓库接口:
@Repository
@EnableElasticsearchRepositories
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
}
服务层
实现服务层来处理业务逻辑:
@Service
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public Product saveProduct(Product product) {
return productRepository.save(product);
}
public Product findProductById(String id) {
return productRepository.findById(id).orElse(null);
}
}
测试
编写集成测试类:
@SpringBootTest
public class ProductServiceIntegrationTest {
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Autowired
private ProductService productService;
private static final String INDEX_NAME = "products";
@BeforeEach
public void setUp() {
IndexOperations indexOperations = elasticsearchOperations.indexOps(IndexCoordinates.of(INDEX_NAME));
if (indexOperations.exists()) {
indexOperations.delete();
}
// 定义 mapping
Document mapping = Document.create()
.append("properties", Document.create()
.append("name", Document.create()
.append("type", "text")
.append("analyzer", "standard"))
.append("price", Document.create()
.append("type", "double")));
// 创建索引并应用 mapping
indexOperations.create(Collections.EMPTY_MAP, mapping);
}
@Test
public void testSaveAndFindProduct() {
List<Product> products = Arrays.asList(
new Product("Test Product 1", 99.99),
new Product("Test Product 2", 199.99),
new Product("Test Product 3", 299.99)
);
List<IndexQuery> queries = products.stream()
.map(product -> new IndexQueryBuilder()
.withObject(product)
.withIndex(INDEX_NAME)
.build())
.collect(Collectors.toList());
List<IndexedObjectInformation> indexedInfos = elasticsearchOperations.bulkIndex(
queries,
IndexCoordinates.of(INDEX_NAME)
);
// 验证结果
List<String> ids = indexedInfos.stream()
.map(IndexedObjectInformation::getId)
.collect(Collectors.toList());
assertFalse(ids.isEmpty());
assertEquals(products.size(), ids.size());
}
}
结论
本指南展示了 Easysearch 与 Elasticsearch 的高度兼容性:
- 配置方式相同,仅需启用 Easysearch 的 API 兼容模式。
- 可直接使用现有 Elasticsearch 客户端。
- Maven 依赖无需更改。
- API、注解和仓库接口完全兼容。
- 现有测试代码可直接应用。
这种兼容性使得从 Elasticsearch 迁移到 Easysearch 成为一个简单、低风险的过程。Spring Boot 项目可以几乎无缝地切换到 Easysearch,同时获得其性能和资源利用方面的优势。
关于 Easysearch
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://infinilabs.cn/docs/latest/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
原文:https://infinilabs.cn/blog/2024/use-spring-boot-for-easysearch-connection/
Easysearch 的很多用户都有这样的需要,之前是用的 ES,现在要迁移到 Easysearch,但是业务方使用的是 Spring Boot 集成的客户端,问是否能平滑迁移。
Easysearch 是完全兼容 Spring Boot 的,完全不用修改,本指南将探讨如何将 Spring Boot 和 ES 的 high-level 客户端 与 Easysearch 进行集成,涵盖从基础设置到实现 CRUD 操作和测试的所有内容。
服务器设置
首先,需要修改 Easysearch 节点的 easysearch.yml 文件,打开并配置这 2 个配置项:
elasticsearch.api_compatibility: true
#根据客户端版本配置版本号,我这里配置成 7.17.18
elasticsearch.api_compatibility_version: "7.17.18"
项目设置
然后,让我们设置 Maven 依赖。以下是 pom.xml
中的基本配置:
<properties>
<java.version>11</java.version>
<spring-data-elasticsearch.version>4.4.18</spring-data-elasticsearch.version>
<elasticsearch.version>7.17.18</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>${spring-data-elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
客户端连接配置
完全和连接 Elasticsearch 的方式一样,不用修改:
配置 src/main/resources/application.yml 文件
spring:
elasticsearch:
rest:
uris: https://localhost:9202
username: admin
password: xxxxxxxxxxx
ssl:
verification-mode: none
连接配置类
@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
@Value("${spring.elasticsearch.rest.uris}")
private String elasticsearchUrl;
@Value("${spring.elasticsearch.rest.username}")
private String username;
@Value("${spring.elasticsearch.rest.password}")
private String password;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
SSLContext sslContext = SSLContexts.custom()
.loadTrustMaterial(null, (x509Certificates, s) -> true)
.build();
RestClientBuilder builder = RestClient.builder(HttpHost.create(elasticsearchUrl))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider)
.setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE));
return new RestHighLevelClient(builder);
}
}
领域模型
使用 Spring 的 Elasticsearch 注解定义领域模型:
@Data
@Document(indexName = "products")
public class Product {
@Id
private String id;
@Field(type = FieldType.Text, name = "name")
private String name;
@Field(type = FieldType.Double, name = "price")
private Double price;
}
仓库层
创建继承 ElasticsearchRepository 的仓库接口:
@Repository
@EnableElasticsearchRepositories
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
}
服务层
实现服务层来处理业务逻辑:
@Service
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public Product saveProduct(Product product) {
return productRepository.save(product);
}
public Product findProductById(String id) {
return productRepository.findById(id).orElse(null);
}
}
测试
编写集成测试类:
@SpringBootTest
public class ProductServiceIntegrationTest {
@Autowired
private ElasticsearchOperations elasticsearchOperations;
@Autowired
private ProductService productService;
private static final String INDEX_NAME = "products";
@BeforeEach
public void setUp() {
IndexOperations indexOperations = elasticsearchOperations.indexOps(IndexCoordinates.of(INDEX_NAME));
if (indexOperations.exists()) {
indexOperations.delete();
}
// 定义 mapping
Document mapping = Document.create()
.append("properties", Document.create()
.append("name", Document.create()
.append("type", "text")
.append("analyzer", "standard"))
.append("price", Document.create()
.append("type", "double")));
// 创建索引并应用 mapping
indexOperations.create(Collections.EMPTY_MAP, mapping);
}
@Test
public void testSaveAndFindProduct() {
List<Product> products = Arrays.asList(
new Product("Test Product 1", 99.99),
new Product("Test Product 2", 199.99),
new Product("Test Product 3", 299.99)
);
List<IndexQuery> queries = products.stream()
.map(product -> new IndexQueryBuilder()
.withObject(product)
.withIndex(INDEX_NAME)
.build())
.collect(Collectors.toList());
List<IndexedObjectInformation> indexedInfos = elasticsearchOperations.bulkIndex(
queries,
IndexCoordinates.of(INDEX_NAME)
);
// 验证结果
List<String> ids = indexedInfos.stream()
.map(IndexedObjectInformation::getId)
.collect(Collectors.toList());
assertFalse(ids.isEmpty());
assertEquals(products.size(), ids.size());
}
}
结论
本指南展示了 Easysearch 与 Elasticsearch 的高度兼容性:
- 配置方式相同,仅需启用 Easysearch 的 API 兼容模式。
- 可直接使用现有 Elasticsearch 客户端。
- Maven 依赖无需更改。
- API、注解和仓库接口完全兼容。
- 现有测试代码可直接应用。
这种兼容性使得从 Elasticsearch 迁移到 Easysearch 成为一个简单、低风险的过程。Spring Boot 项目可以几乎无缝地切换到 Easysearch,同时获得其性能和资源利用方面的优势。
关于 Easysearch
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://infinilabs.cn/docs/latest/easysearch
收起阅读 »作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
原文:https://infinilabs.cn/blog/2024/use-spring-boot-for-easysearch-connection/
Easysearch Java SDK 2.0.x 使用指南(一)
各位 Easysearch 的小伙伴们,我们前一阵刚把 easysearch-client 更新到了 2.0.2 版本!借此详细介绍下新版客户端的使用。
新版客户端和 1.0 版本相比,完全重构,抛弃了旧版客户端的一些历史包袱,从里到外都焕然一新!不管是刚入门的小白还是经验丰富的老司机,2.0.x 客户端都能让你开发效率蹭蹭往上涨!
到底有啥新东西?
- 更轻更快: 以前的版本依赖了一堆乱七八糟的东西,现在好了,我们把那些没用的都砍掉了,客户端变得更苗条,性能也杠杠的!
- 类型安全,告别迷糊: 常用的 Easysearch API 现在都配上了强类型的请求和响应对象,再也不用担心写错参数类型了,代码也更好看了,维护起来也更省心!
- 同步异步,想咋用咋用: 所有 API 都支持同步和异步两种调用方式,不管是啥场景,都能轻松应对!
- 构建查询,跟搭积木一样简单: 我们用了流式构建器和函数式编程,构建复杂查询的时候,代码写起来那叫一个流畅,看着也舒服!
- 和 Jackson 无缝对接: 可以轻松地把你的 Java 类和客户端 API 关联起来,数据转换嗖嗖的快!
快速上手
废话不多说,咱们直接上干货!这部分教你怎么快速安装和使用 easysearch-client 2.0.2 客户端,还会演示一些基本操作。
安装
easysearch-client 2.0.2 已经上传到 Maven 中央仓库了,加到你的项目里超级方便。
最低要求: JDK 8 或者更高版本
依赖管理: 客户端内部用 Jackson 来处理对象映射。
Maven 项目
在你的 pom.xml
文件的 <dependencies>
里面加上这段:
<dependencies>
<dependency>
<groupId>com.infinilabs</groupId>
<artifactId>easysearch-client</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
Gradle 项目
在你的 build.gradle
文件的 dependencies
里面加上这段:
dependencies {
implementation 'com.infinilabs:easysearch-client:2.0.2'
}
初始化客户端
下面这段代码演示了怎么初始化一个启用了安全通信加密和 security 的 Easysearch 客户端,看起来有点长,别慌,我们一步一步解释!
public static EasysearchClient create() throws NoSuchAlgorithmException, KeyStoreException,
KeyManagementException {
final HttpHost[] hosts = new HttpHost[]{new HttpHost("localhost", 9200, "https")};
final SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, (chains, authType) -> true).build();
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("username", "passwowd"));
RestClient restClient = RestClient.builder(hosts)
.setHttpClientConfigCallback(httpClientBuilder ->
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
.setSSLStrategy(sessionStrategy)
.disableAuthCaching()
).setRequestConfigCallback(requestConfigCallback ->
requestConfigCallback.setConnectTimeout(30000).setSocketTimeout(300000))
.build();
EasysearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
return new EasysearchClient(transport);
}
这段代码,简单来说,就是:
- 连上 Easysearch: 我们要用 HTTPS 连接到本地的 9200 端口。
- 搞定证书: 这里为了方便,我们信任了所有证书(注意!生产环境一定要配置好你们自己的证书)。
- 填上用户名密码: 这里需要填上你的用户名和密码。
- 设置连接参数: 设置了连接超时时间(30 秒)和读取超时时间(300 秒)。
- 创建客户端: 最后,我们就创建好了一个
EasysearchClient
实例,可以开始干活了!
举个栗子:批量操作
下面的例子演示了怎么用 bulk
API 来批量索引数据:
public static void bulk() throws Exception {
String json2 = "{"
+ " \"@timestamp\": \"2023-01-08T22:50:13.059Z\","
+ " \"agent\": {"
+ " \"version\": \"7.3.2\","
+ " \"type\": \"filebeat\","
+ " \"ephemeral_id\": \"3ff1f2c8-1f7f-48c2-b560-4272591b8578\","
+ " \"hostname\": \"ba-0226-msa-fbl-747db69c8d-ngff6\""
+ " }"
+ "}";
EasysearchClient client = create();
BulkRequest.Builder br = new BulkRequest.Builder();
br.index("test1");
for (int i = 0; i < 10; i++) {
BulkOperation.Builder builder = new BulkOperation.Builder();
IndexOperation.Builder indexBuilder = new IndexOperation.Builder();
builder.index(indexBuilder.document(JsonData.fromJson(json2)).build());
br.operations(builder.build());
}
for (int i = 0; i < 10; i++) {
BulkOperation.Builder builder = new BulkOperation.Builder();
IndexOperation.Builder indexBuilder = new IndexOperation.Builder();
indexBuilder.document(JsonData.fromJson(json2)).index("test2");
builder.index(indexBuilder.build());
br.operations(builder.build());
}
for (int i = 0; i < 10; i++) {
Map<String, Object> map = new HashMap<>();
map.put("@timestamp", "2023-01-08T22:50:13.059Z");
map.put("field1", "value1");
IndexOperation.Builder indexBuilder = new IndexOperation.Builder();
indexBuilder.document(map).index("test3");
br.operations(new BulkOperation(indexBuilder.build()));
}
BulkResponse bulkResponse = client.bulk(br.build());
if (bulkResponse.errors()) {
for (BulkResponseItem item : bulkResponse.items()) {
System.out.println(item.toString());
}
}
client._transport().close();
}
这个例子里,我们一口气把数据批量索引到了 test1
、test2
和 test3
这三个索引里,
并且展示了三种在 bulk API 中构建 IndexOperation 的方式,虽然它们最终都能实现将文档索引到 Easysearch,但在使用场景和灵活性上还是有一些区别的:
这段代码的核心是利用 BulkRequest.Builder 来构建一个批量请求,并通过 br.operations(...) 方法添加多个操作。而每个操作,在这个例子里,都是一个 IndexOperation,也就是索引一个文档。IndexOperation 可以通过 IndexOperation.Builder 来创建。
三种方式的区别主要体现在如何构建 IndexOperation 里的 document 部分,也就是要索引的文档内容。
第一种方式:使用 JsonData.fromJson(json2) 且不指定索引。
特点:
使用 JsonData.fromJson(json2) 将一个 JSON 字符串直接转换成 JsonData 对象作为文档内容。
这里没有在 IndexOperation.Builder 上调用 index() 方法来指定索引名称。由于没有在每个 IndexOperation 中指定索引,这个索引名称将回退到 BulkRequest.Builder 上设置的索引,即 br.index("test1"),所以这 10 个文档都会被索引到 test1。
当你需要将一批相同结构的 JSON 文档索引到同一个索引时,这种方式比较简洁。
第二种方式:使用 JsonData.fromJson(json2) 并指定索引
特点:
同样使用 JsonData.fromJson(json2) 将 JSON 字符串转换成 JsonData 对象。
关键区别在于,这里在 IndexOperation.Builder 上调用了 index("test2"),为每个操作单独指定了索引名称。
这 10 个文档会被索引到 test2,即使 BulkRequest.Builder 上设置了 index("test1") 也没用,因为 IndexOperation 里的设置优先级更高。
当你需要将一批相同结构的 JSON 文档索引到不同的索引时,就需要使用这种方式来分别指定索引。
第三种方式:使用 Map<String, Object> 并指定索引
特点:
使用 Map<String, Object> 来构建文档内容,这种方式更加灵活,可以构建任意结构的文档。
同样在 IndexOperation.Builder 上调用了 index("test3") 指定了索引名称。
使用 new BulkOperation(indexBuilder.build()) 代替之前的 builder.index(indexBuilder.build()), 这是等价的。
这 10 个文档会被索引到 test3。
当你需要索引的文档结构不固定,或者你需要动态构建文档内容时,使用 Map 是最佳选择。例如,你可以根据不同的业务逻辑,往 Map 里添加不同的字段。
总结
这次 easysearch-client 2.0.x Java 客户端的更新真的很给力,强烈建议大家升级体验!相信我,用了新版客户端,你的开发效率绝对会提升一大截!
想要了解更多?
-
客户端 Maven 地址: https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2
- 更详细的文档和示例代码在 官网 持续更新中,请随时关注!
大家有啥问题或者建议,也欢迎随时反馈!
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
各位 Easysearch 的小伙伴们,我们前一阵刚把 easysearch-client 更新到了 2.0.2 版本!借此详细介绍下新版客户端的使用。
新版客户端和 1.0 版本相比,完全重构,抛弃了旧版客户端的一些历史包袱,从里到外都焕然一新!不管是刚入门的小白还是经验丰富的老司机,2.0.x 客户端都能让你开发效率蹭蹭往上涨!
到底有啥新东西?
- 更轻更快: 以前的版本依赖了一堆乱七八糟的东西,现在好了,我们把那些没用的都砍掉了,客户端变得更苗条,性能也杠杠的!
- 类型安全,告别迷糊: 常用的 Easysearch API 现在都配上了强类型的请求和响应对象,再也不用担心写错参数类型了,代码也更好看了,维护起来也更省心!
- 同步异步,想咋用咋用: 所有 API 都支持同步和异步两种调用方式,不管是啥场景,都能轻松应对!
- 构建查询,跟搭积木一样简单: 我们用了流式构建器和函数式编程,构建复杂查询的时候,代码写起来那叫一个流畅,看着也舒服!
- 和 Jackson 无缝对接: 可以轻松地把你的 Java 类和客户端 API 关联起来,数据转换嗖嗖的快!
快速上手
废话不多说,咱们直接上干货!这部分教你怎么快速安装和使用 easysearch-client 2.0.2 客户端,还会演示一些基本操作。
安装
easysearch-client 2.0.2 已经上传到 Maven 中央仓库了,加到你的项目里超级方便。
最低要求: JDK 8 或者更高版本
依赖管理: 客户端内部用 Jackson 来处理对象映射。
Maven 项目
在你的 pom.xml
文件的 <dependencies>
里面加上这段:
<dependencies>
<dependency>
<groupId>com.infinilabs</groupId>
<artifactId>easysearch-client</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
Gradle 项目
在你的 build.gradle
文件的 dependencies
里面加上这段:
dependencies {
implementation 'com.infinilabs:easysearch-client:2.0.2'
}
初始化客户端
下面这段代码演示了怎么初始化一个启用了安全通信加密和 security 的 Easysearch 客户端,看起来有点长,别慌,我们一步一步解释!
public static EasysearchClient create() throws NoSuchAlgorithmException, KeyStoreException,
KeyManagementException {
final HttpHost[] hosts = new HttpHost[]{new HttpHost("localhost", 9200, "https")};
final SSLContext sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, (chains, authType) -> true).build();
SSLIOSessionStrategy sessionStrategy = new SSLIOSessionStrategy(sslContext, NoopHostnameVerifier.INSTANCE);
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("username", "passwowd"));
RestClient restClient = RestClient.builder(hosts)
.setHttpClientConfigCallback(httpClientBuilder ->
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
.setSSLStrategy(sessionStrategy)
.disableAuthCaching()
).setRequestConfigCallback(requestConfigCallback ->
requestConfigCallback.setConnectTimeout(30000).setSocketTimeout(300000))
.build();
EasysearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
return new EasysearchClient(transport);
}
这段代码,简单来说,就是:
- 连上 Easysearch: 我们要用 HTTPS 连接到本地的 9200 端口。
- 搞定证书: 这里为了方便,我们信任了所有证书(注意!生产环境一定要配置好你们自己的证书)。
- 填上用户名密码: 这里需要填上你的用户名和密码。
- 设置连接参数: 设置了连接超时时间(30 秒)和读取超时时间(300 秒)。
- 创建客户端: 最后,我们就创建好了一个
EasysearchClient
实例,可以开始干活了!
举个栗子:批量操作
下面的例子演示了怎么用 bulk
API 来批量索引数据:
public static void bulk() throws Exception {
String json2 = "{"
+ " \"@timestamp\": \"2023-01-08T22:50:13.059Z\","
+ " \"agent\": {"
+ " \"version\": \"7.3.2\","
+ " \"type\": \"filebeat\","
+ " \"ephemeral_id\": \"3ff1f2c8-1f7f-48c2-b560-4272591b8578\","
+ " \"hostname\": \"ba-0226-msa-fbl-747db69c8d-ngff6\""
+ " }"
+ "}";
EasysearchClient client = create();
BulkRequest.Builder br = new BulkRequest.Builder();
br.index("test1");
for (int i = 0; i < 10; i++) {
BulkOperation.Builder builder = new BulkOperation.Builder();
IndexOperation.Builder indexBuilder = new IndexOperation.Builder();
builder.index(indexBuilder.document(JsonData.fromJson(json2)).build());
br.operations(builder.build());
}
for (int i = 0; i < 10; i++) {
BulkOperation.Builder builder = new BulkOperation.Builder();
IndexOperation.Builder indexBuilder = new IndexOperation.Builder();
indexBuilder.document(JsonData.fromJson(json2)).index("test2");
builder.index(indexBuilder.build());
br.operations(builder.build());
}
for (int i = 0; i < 10; i++) {
Map<String, Object> map = new HashMap<>();
map.put("@timestamp", "2023-01-08T22:50:13.059Z");
map.put("field1", "value1");
IndexOperation.Builder indexBuilder = new IndexOperation.Builder();
indexBuilder.document(map).index("test3");
br.operations(new BulkOperation(indexBuilder.build()));
}
BulkResponse bulkResponse = client.bulk(br.build());
if (bulkResponse.errors()) {
for (BulkResponseItem item : bulkResponse.items()) {
System.out.println(item.toString());
}
}
client._transport().close();
}
这个例子里,我们一口气把数据批量索引到了 test1
、test2
和 test3
这三个索引里,
并且展示了三种在 bulk API 中构建 IndexOperation 的方式,虽然它们最终都能实现将文档索引到 Easysearch,但在使用场景和灵活性上还是有一些区别的:
这段代码的核心是利用 BulkRequest.Builder 来构建一个批量请求,并通过 br.operations(...) 方法添加多个操作。而每个操作,在这个例子里,都是一个 IndexOperation,也就是索引一个文档。IndexOperation 可以通过 IndexOperation.Builder 来创建。
三种方式的区别主要体现在如何构建 IndexOperation 里的 document 部分,也就是要索引的文档内容。
第一种方式:使用 JsonData.fromJson(json2) 且不指定索引。
特点:
使用 JsonData.fromJson(json2) 将一个 JSON 字符串直接转换成 JsonData 对象作为文档内容。
这里没有在 IndexOperation.Builder 上调用 index() 方法来指定索引名称。由于没有在每个 IndexOperation 中指定索引,这个索引名称将回退到 BulkRequest.Builder 上设置的索引,即 br.index("test1"),所以这 10 个文档都会被索引到 test1。
当你需要将一批相同结构的 JSON 文档索引到同一个索引时,这种方式比较简洁。
第二种方式:使用 JsonData.fromJson(json2) 并指定索引
特点:
同样使用 JsonData.fromJson(json2) 将 JSON 字符串转换成 JsonData 对象。
关键区别在于,这里在 IndexOperation.Builder 上调用了 index("test2"),为每个操作单独指定了索引名称。
这 10 个文档会被索引到 test2,即使 BulkRequest.Builder 上设置了 index("test1") 也没用,因为 IndexOperation 里的设置优先级更高。
当你需要将一批相同结构的 JSON 文档索引到不同的索引时,就需要使用这种方式来分别指定索引。
第三种方式:使用 Map<String, Object> 并指定索引
特点:
使用 Map<String, Object> 来构建文档内容,这种方式更加灵活,可以构建任意结构的文档。
同样在 IndexOperation.Builder 上调用了 index("test3") 指定了索引名称。
使用 new BulkOperation(indexBuilder.build()) 代替之前的 builder.index(indexBuilder.build()), 这是等价的。
这 10 个文档会被索引到 test3。
当你需要索引的文档结构不固定,或者你需要动态构建文档内容时,使用 Map 是最佳选择。例如,你可以根据不同的业务逻辑,往 Map 里添加不同的字段。
总结
这次 easysearch-client 2.0.x Java 客户端的更新真的很给力,强烈建议大家升级体验!相信我,用了新版客户端,你的开发效率绝对会提升一大截!
想要了解更多?
-
客户端 Maven 地址: https://mvnrepository.com/artifact/com.infinilabs/easysearch-client/2.0.2
- 更详细的文档和示例代码在 官网 持续更新中,请随时关注!
大家有啥问题或者建议,也欢迎随时反馈!
收起阅读 »作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
【第3期】INFINI Easysearch 免费认证培训开放报名
探索 Easysearch 的无限可能,与 INFINI Labs 共赴搜索技术前沿!
随着数字化转型的加速,搜索技术已成为企业数据洞察的核心。INFINI Labs 作为搜索创新技术的引领者,诚邀所有对 Easysearch 搜索引擎感兴趣的开发者、技术爱好者及合作伙伴,参加我们即将于 2024 年 10 月 19 日至 20 日举办的第 3 期 Easysearch 线上免费培训活动。这不仅是一场知识的盛宴,更是技能提升的加速器,将助您在职业道路上迈出坚实的一步!
活动亮点
- 系统课程,全面深入:从 Easysearch 的基本概念到环境搭建,再到高级功能的实战应用,INFINI Labs 的技术专家将为您带来全面而深入的讲解,确保每位参与者都能收获满满。
- 实战导向,解决痛点:课程设计紧贴实际需求,旨在帮助学员掌握 Easysearch 的核心技术,有效解决工作中的搜索需求和技术难题,让理论知识迅速转化为实践能力。
- 认证证书,助力进阶:后期 INFINI Labs 将推出 Easysearch 认证考试。通过考试的学员将获得官方认证的 Easysearch 证书,为您的职业发展增添强力背书,开启职业生涯的新篇章。
培训时间
2024 年 10 月 19 日至 20 日(周六、周日)共两天,每天具体培训时间:
- 上午 09:30 ~ 11:30
- 下午 14:00 ~ 16:00
培训内容概览
第一阶段:初识 Easysearch
- Easysearch 环境搭建与对比,了解其与 Elasticsearch 的差异;
- 功能初探:身份验证、数据脱敏、权限控制等,全面掌握 Easysearch 的基础功能;
- 容灾技术:兼容性验证、跨集群复制等,确保您的搜索服务稳定可靠;
第二阶段:Easysearch 高阶使用
- 深度探析:性能压测、数据迁移、请求管理等,提升 Easysearch 的使用效率;
- 高级功能:快照管理、可视化看板、告警功能等,让您的搜索服务更加智能;
- 生态集成:Filebeat、Logstash、LangChain 等,轻松实现 Easysearch 与其他工具的集成;
参与方式
本次活动完全免费,名额有限,请尽快报名,同时微信扫码添加小助手进群(培训会议地址将在微信群公布),锁定您的学习席位!
扫码或点击 我要报名
👉 立即行动:不要错过这次提升自我、与行业精英共成长的宝贵机会。让我们相聚云端,共同探索 Easysearch 的无限可能,开启技术进阶的新篇章!
参会提示
- 培训内容涉及动手实践,请务必自备电脑(Windows 系统环境请提前安装好 Linux 虚拟机);
- 请提前在 INFINI Labs 官网下载对应平台最新安装包(INFINI Easysearch、INFINI Gateway、INFINI Console);
- 下载地址:https://infinilabs.cn/download
联系我们
如有任何疑问,欢迎通过微信添加 [小助手:INFINI-Labs] 与我们联系。
INFINI Labs 期待与您相约,共赴这场技术盛宴!
关于 Easysearch
Easysearch 是一个分布式的近实时搜索与分析引擎,基于开源的 Apache Lucene 构建。它旨在提供一个自主可控、轻量级的 Elasticsearch 可替代版本,并不断完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更注重搜索业务场景的优化,同时保持其产品的简洁与易用性。
详情参见:Easysearch 介绍
关于极限科技(INFINI Labs)
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
探索 Easysearch 的无限可能,与 INFINI Labs 共赴搜索技术前沿!
随着数字化转型的加速,搜索技术已成为企业数据洞察的核心。INFINI Labs 作为搜索创新技术的引领者,诚邀所有对 Easysearch 搜索引擎感兴趣的开发者、技术爱好者及合作伙伴,参加我们即将于 2024 年 10 月 19 日至 20 日举办的第 3 期 Easysearch 线上免费培训活动。这不仅是一场知识的盛宴,更是技能提升的加速器,将助您在职业道路上迈出坚实的一步!
活动亮点
- 系统课程,全面深入:从 Easysearch 的基本概念到环境搭建,再到高级功能的实战应用,INFINI Labs 的技术专家将为您带来全面而深入的讲解,确保每位参与者都能收获满满。
- 实战导向,解决痛点:课程设计紧贴实际需求,旨在帮助学员掌握 Easysearch 的核心技术,有效解决工作中的搜索需求和技术难题,让理论知识迅速转化为实践能力。
- 认证证书,助力进阶:后期 INFINI Labs 将推出 Easysearch 认证考试。通过考试的学员将获得官方认证的 Easysearch 证书,为您的职业发展增添强力背书,开启职业生涯的新篇章。
培训时间
2024 年 10 月 19 日至 20 日(周六、周日)共两天,每天具体培训时间:
- 上午 09:30 ~ 11:30
- 下午 14:00 ~ 16:00
培训内容概览
第一阶段:初识 Easysearch
- Easysearch 环境搭建与对比,了解其与 Elasticsearch 的差异;
- 功能初探:身份验证、数据脱敏、权限控制等,全面掌握 Easysearch 的基础功能;
- 容灾技术:兼容性验证、跨集群复制等,确保您的搜索服务稳定可靠;
第二阶段:Easysearch 高阶使用
- 深度探析:性能压测、数据迁移、请求管理等,提升 Easysearch 的使用效率;
- 高级功能:快照管理、可视化看板、告警功能等,让您的搜索服务更加智能;
- 生态集成:Filebeat、Logstash、LangChain 等,轻松实现 Easysearch 与其他工具的集成;
参与方式
本次活动完全免费,名额有限,请尽快报名,同时微信扫码添加小助手进群(培训会议地址将在微信群公布),锁定您的学习席位!
扫码或点击 我要报名
👉 立即行动:不要错过这次提升自我、与行业精英共成长的宝贵机会。让我们相聚云端,共同探索 Easysearch 的无限可能,开启技术进阶的新篇章!
参会提示
- 培训内容涉及动手实践,请务必自备电脑(Windows 系统环境请提前安装好 Linux 虚拟机);
- 请提前在 INFINI Labs 官网下载对应平台最新安装包(INFINI Easysearch、INFINI Gateway、INFINI Console);
- 下载地址:https://infinilabs.cn/download
联系我们
如有任何疑问,欢迎通过微信添加 [小助手:INFINI-Labs] 与我们联系。
INFINI Labs 期待与您相约,共赴这场技术盛宴!
关于 Easysearch
Easysearch 是一个分布式的近实时搜索与分析引擎,基于开源的 Apache Lucene 构建。它旨在提供一个自主可控、轻量级的 Elasticsearch 可替代版本,并不断完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更注重搜索业务场景的优化,同时保持其产品的简洁与易用性。
详情参见:Easysearch 介绍
关于极限科技(INFINI Labs)
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
收起阅读 »如何用 Scrapy 爬取网站数据并在 Easysearch 中进行存储检索分析
做过数据分析和爬虫程序的小伙伴想必对 Scrapy 这个爬虫框架已经很熟悉了。今天给大家介绍下,如何基于 Scrapy 快速编写一个爬虫程序并利用 Easysearch 储存、检索、分析爬取的数据。我们以极限科技的官网 Blog 为数据源(https://infinilabs.cn/blog) ,做下实操演示。
1、安装 scrapy
使用 Scrapy 可以快速构建一个爬虫项目,从目标网站中获取所需的数据,并进行后续的处理和分析。
pip install scrapy
# 新建项目 infini_spiders
scrapy startproject infini_spiders
# 初始化爬虫
cd infini_spiders/spiders
scrapy genspider blog infinilabs.cn
2、爬虫编写
编写一个爬虫文件 blog.py ,它会首先访问 start_urls 指定的地址,将结果发给 parse 函数解析。通过这一步解析,我们得到了每一篇博客的地址。然后我们对每个博客的地址发送请求,将结果发给 parse_blog 函数进行解析,在这里才会真正提取每篇博客的 title、tag、url、date、content 内容。
from typing import Any, Iterable
import scrapy
from bs4 import BeautifulSoup
from scrapy.http import Response
class BlogSpider(scrapy.Spider):
name = "blog"
allowed_domains = ["infinilabs.cn"]
start_urls = ["https://infinilabs.cn/blog/"]
def parse(self, response):
links = response.css("div.blogs a")
yield from response.follow_all(links, self.parse_blog)
def parse_blog(self, response):
title = response.xpath('//div[@class="title"]/text()').extract_first()
tags = response.xpath('//div[@class="tags"]/div[@class="tag"]/text()').extract()
url = response.url
author = response.xpath('//div[@class="logo"]/div[@class="name"]//text()').extract_first()
date = response.xpath('//div[@class="date"]/text()').extract_first()
all_text = response.xpath('//p//text() | //h3/text() | //h2/text() | //h4/text() | //ol/li//text()').extract()
content = '\n'.join(all_text)
yield {
'title': title,
'tags': tags,
'url': url,
'author': author,
'date': date,
'content': content
}
提取完我们想要的内容后,接下来就要考虑存储了。考虑到要对内容进行检索、分析,接下来我们将内容直接存放到 Easysearch 当中。
3、安装插件
通过安装 ScrapyElasticsearch pipeline 可将 scrapy 爬取的内容存入到 Easysearch 中。
pip install ScrapyElasticSearch
修改 scrapy 自带的配置文件 settings.py ,添加以下内容。
ITEM_PIPELINES = {
'scrapyelasticsearch.scrapyelasticsearch.ElasticSearchPipeline': 10
}
ELASTICSEARCH_SERVERS = ['http://192.168.56.3:9210']
ELASTICSEARCH_INDEX = 'scrapy'
ELASTICSEARCH_INDEX_DATE_FORMAT = '%Y-%m-%d'
ELASTICSEARCH_TYPE = '_doc'
ELASTICSEARCH_USERNAME = 'admin'
ELASTICSEARCH_PASSWORD = '9423d1d5345ed6d0db19'
ScrapyElasticSearch 会以 bulk 方式写入 Easysearch,每次批量的大小由 scrapyelasticsearch.scrapyelasticsearch.ElasticSearchPipeline 参数控制,大家可自行修改。
在上述配置中,我们会将爬到的数据存放到 scrapy-yyyy-mm-dd 索引中。
4、启动爬虫
在 infini_spiders/spiders 目录下,使用命令启动爬虫。
scrapy crawl blog
blog 就是爬虫的名字,对应到 blog.py 里面的 name 变量。运行完成后,就可以去 Easysearch 里查看数据了,当然我们还是使用 Console 进行查看。
5、查看数据
先查看下索引情况,scrapy 索引已经生成,里面有 129 篇博客。
查看详细内容,确保博客正文已经保存。
到了这一步,我们就能使用 Console 对博客进行搜索、分析了。
6、结语
这次的分享就到这里了。欢迎与我一起交流 ES 的各种问题和解决方案。
关于 Easysearch
INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。 与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。
官网文档:https://infinilabs.cn/docs/latest/easysearch
做过数据分析和爬虫程序的小伙伴想必对 Scrapy 这个爬虫框架已经很熟悉了。今天给大家介绍下,如何基于 Scrapy 快速编写一个爬虫程序并利用 Easysearch 储存、检索、分析爬取的数据。我们以极限科技的官网 Blog 为数据源(https://infinilabs.cn/blog) ,做下实操演示。
1、安装 scrapy
使用 Scrapy 可以快速构建一个爬虫项目,从目标网站中获取所需的数据,并进行后续的处理和分析。
pip install scrapy
# 新建项目 infini_spiders
scrapy startproject infini_spiders
# 初始化爬虫
cd infini_spiders/spiders
scrapy genspider blog infinilabs.cn
2、爬虫编写
编写一个爬虫文件 blog.py ,它会首先访问 start_urls 指定的地址,将结果发给 parse 函数解析。通过这一步解析,我们得到了每一篇博客的地址。然后我们对每个博客的地址发送请求,将结果发给 parse_blog 函数进行解析,在这里才会真正提取每篇博客的 title、tag、url、date、content 内容。
from typing import Any, Iterable
import scrapy
from bs4 import BeautifulSoup
from scrapy.http import Response
class BlogSpider(scrapy.Spider):
name = "blog"
allowed_domains = ["infinilabs.cn"]
start_urls = ["https://infinilabs.cn/blog/"]
def parse(self, response):
links = response.css("div.blogs a")
yield from response.follow_all(links, self.parse_blog)
def parse_blog(self, response):
title = response.xpath('//div[@class="title"]/text()').extract_first()
tags = response.xpath('//div[@class="tags"]/div[@class="tag"]/text()').extract()
url = response.url
author = response.xpath('//div[@class="logo"]/div[@class="name"]//text()').extract_first()
date = response.xpath('//div[@class="date"]/text()').extract_first()
all_text = response.xpath('//p//text() | //h3/text() | //h2/text() | //h4/text() | //ol/li//text()').extract()
content = '\n'.join(all_text)
yield {
'title': title,
'tags': tags,
'url': url,
'author': author,
'date': date,
'content': content
}
提取完我们想要的内容后,接下来就要考虑存储了。考虑到要对内容进行检索、分析,接下来我们将内容直接存放到 Easysearch 当中。
3、安装插件
通过安装 ScrapyElasticsearch pipeline 可将 scrapy 爬取的内容存入到 Easysearch 中。
pip install ScrapyElasticSearch
修改 scrapy 自带的配置文件 settings.py ,添加以下内容。
ITEM_PIPELINES = {
'scrapyelasticsearch.scrapyelasticsearch.ElasticSearchPipeline': 10
}
ELASTICSEARCH_SERVERS = ['http://192.168.56.3:9210']
ELASTICSEARCH_INDEX = 'scrapy'
ELASTICSEARCH_INDEX_DATE_FORMAT = '%Y-%m-%d'
ELASTICSEARCH_TYPE = '_doc'
ELASTICSEARCH_USERNAME = 'admin'
ELASTICSEARCH_PASSWORD = '9423d1d5345ed6d0db19'
ScrapyElasticSearch 会以 bulk 方式写入 Easysearch,每次批量的大小由 scrapyelasticsearch.scrapyelasticsearch.ElasticSearchPipeline 参数控制,大家可自行修改。
在上述配置中,我们会将爬到的数据存放到 scrapy-yyyy-mm-dd 索引中。
4、启动爬虫
在 infini_spiders/spiders 目录下,使用命令启动爬虫。
scrapy crawl blog
blog 就是爬虫的名字,对应到 blog.py 里面的 name 变量。运行完成后,就可以去 Easysearch 里查看数据了,当然我们还是使用 Console 进行查看。
5、查看数据
先查看下索引情况,scrapy 索引已经生成,里面有 129 篇博客。
查看详细内容,确保博客正文已经保存。
到了这一步,我们就能使用 Console 对博客进行搜索、分析了。
6、结语
这次的分享就到这里了。欢迎与我一起交流 ES 的各种问题和解决方案。
关于 Easysearch
INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。 与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。
官网文档:https://infinilabs.cn/docs/latest/easysearch
收起阅读 »
Easysearch 性能测试方法概要
INFINI Easysearch
INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 衍生自基于开源协议 Apache 2.0 的 Elasticsearch 7.10 版本,完善和支持更多的企业级功能,优化搜索业务场景,以保证更佳的数据探索与分析体验。
Easysearch 的主要特点:
- 兼容 Elasticsearch,业务代码无需改动;可平滑迁移
- 企业级安全;更稳定可靠
- 企业级管理后台(多集群统一管理,实现运营标准化、自动化)
- 信创适配(全面适配国产 CPU/OS/服务器,支持国密算法)
Easysearch 快速体验,请参阅:
Loadgen
Loadgen 是 Elasticsearch 专属压测工具,用来对 Easysearch 或者网关进行压力测试。
Loadgen 的特点:
- 性能强劲
- 轻量级无依赖
- 支持模板化参数随机
- 支持高并发
- 支持压测端均衡流量控制
- 支持服务端返回值校验
当前最新版本为 1.26.1-598,下载链接如下:
https://release.infinilabs.com/loadgen/stable/
下载并解压安装包后,得到二进制文件。
查看版本信息。
$ ./loadgen-linux-amd64 -v
__ ___ _ ___ ___ __ __
/ / /___\/_\ / \/ _ \ /__\/\ \ \
/ / // ///_\\ / /\ / /_\//_\ / \/ /
/ /__/ \_// _ \/ /_// /_\\//__/ /\ /
\____|___/\_/ \_/___,'\____/\__/\_\ \/
[LOADGEN] A http load generator and testing suite.
[LOADGEN] 1.26.1#598, 2024-08-14 04:50:03, 2024-12-31 10:10:10, 00f15fd86834d7ea539f6d66ee608e3915eef0e3
loadgen 1.26.1 598 2024-08-14 04:50:03 +0000 UTC 2024-12-31 10:10:10 +0000 UTC 00f15fd86834d7ea539f6d66ee608e3915eef0e3
Loadgen 测试
Loadgen 使用非常简单,下面演示如何进行查询压测。
- 建立索引,根据节点数调节分片数。
curl -X PUT -H "Content-Type: application/json" \
-ku admin:xxx "https://localhost:9200/loadtest" -d'
{
"settings":{
"number_of_shards":"3",
"number_of_replicas":1,
"translog":{
"durability":"async"
}
}
}'
{"acknowledged":true,"shards_acknowledged":true,"index":"loadtest"}
- 创建
loadgen.dsl.shawnyan
配置文件,定义查询
GET loadtest/_search
{"query": {"term": {"id.keyword": {"value": $[[id]]}}}}
- 执行压测,
-d
表示秒数,-c
表示并发数。
$ ES_ENDPOINT=https://localhost:9200 ES_USERNAME=admin ES_PASSWORD=xxx ./loadgen-linux-amd64 -run loadgen.dsl.shawnyan -d 10 -c 2
__ ___ _ ___ ___ __ __
/ / /___\/_\ / \/ _ \ /__\/\ \ \
/ / // ///_\\ / /\ / /_\//_\ / \/ /
/ /__/ \_// _ \/ /_// /_\\//__/ /\ /
\____|___/\_/ \_/___,'\____/\__/\_\ \/
[LOADGEN] A http load generator and testing suite.
[LOADGEN] 1.26.1#598, 2024-08-14 04:50:03, 2024-12-31 10:10:10, 00f15fd86834d7ea539f6d66ee608e3915eef0e3
[08-19 16:43:27] [INF] [env.go:179] configuration auto reload enabled
[08-19 16:43:27] [INF] [app.go:285] initializing loadgen, pid: 30792
[08-19 16:43:27] [INF] [app.go:286] using config: /data/es/loadgen.yml
[08-19 16:43:27] [INF] [module.go:155] started plugin: statsd
[08-19 16:43:27] [INF] [module.go:161] all modules are started
[08-19 16:43:27] [INF] [instance.go:78] workspace: /data/es/data/loadgen/nodes/cr1gabqr90cng685o2s0
[08-19 16:43:27] [INF] [app.go:511] loadgen is up and running now.
[08-19 16:43:27] [INF] [main.go:403] loading config: /data/es/loadgen.dsl.shawnyan
21108 requests finished in 9.79061677s, 1.08MB sent, 3.22MB received
[Loadgen Client Metrics]
Requests/sec: 2110.63
Request Traffic/sec: 110.22KB
Total Transfer/sec: 440.00KB
Fastest Request: 680.198µs
Slowest Request: 12.409574ms
Status 200: 21108
[Latency Metrics]
10000 samples of 21108 events
Cumulative: 8.732205871s
HMean: 851.869µs
Avg.: 873.22µs
p50: 839.498µs
p75: 914.298µs
p95: 1.059197ms
p99: 1.327098ms
p999: 4.83579ms
Long 5%: 1.394411ms
Short 5%: 724.226µs
Max: 11.618475ms
Min: 680.198µs
Range: 10.938277ms
StdDev: 289.216µs
Rate/sec.: 2110.63
[Latency Distribution]
680µs - 1.774ms ------------------------------
1.774ms - 2.867ms -
2.867ms - 3.961ms -
3.961ms - 5.055ms -
5.055ms - 6.149ms -
6.149ms - 7.243ms -
7.243ms - 8.336ms -
8.336ms - 9.43ms -
9.43ms - 10.524ms -
10.524ms - 11.618ms -
[Estimated Server Metrics]
Requests/sec: 2155.94
Avg Req Time: 927.668µs
Transfer/sec: 449.45KB
更多内容请参阅文档:
https://infinilabs.cn/docs/latest/gateway/getting-started/benchmark/
Rally
如果对 Elasticsearch 熟悉的同学,也可尝试使用 Rally 对 Easysearch 进行测试。
Rally 是 Elasticsearch 的基准测试框架。它可以帮助您完成以下任务:
- 安装 Elasticsearch 集群以进行基准测试
- 跨 Elasticsearch 版本管理基准数据和规范
- 运行基准测试并记录结果
- 通过连接遥测设备来查找性能问题
- 比较性能结果
安装 Rally。
[root@easysearch /]# pip3 install esrally
Requirement already satisfied: esrally in /usr/local/lib/python3.9/site-packages (2.11.0)
Requirement already satisfied: py-cpuinfo==7.0.0 in /usr/local/lib/python3.9/site-packages (from esrally) (7.0.0)
Requirement already satisfied: elastic-transport==8.4.1 in /usr/local/lib/python3.9/site-packages (from esrally) (8.4.1)
Requirement already satisfied: google-resumable-media[requests]==1.1.0 in /usr/local/lib/python3.9/site-packages (from esrally) (1.1.0)
Requirement already satisfied: urllib3==1.26.18 in /usr/local/lib/python3.9/site-packages (from esrally) (1.26.18)
Requirement already satisfied: google-auth==1.22.1 in /usr/local/lib/python3.9/site-packages (from esrally) (1.22.1)
Requirement already satisfied: thespian==3.10.1 in /usr/local/lib/python3.9/site-packages (from esrally) (3.10.1)
Requirement already satisfied: jsonschema==3.1.1 in /usr/local/lib/python3.9/site-packages (from esrally) (3.1.1)
Requirement already satisfied: markupsafe==2.0.1 in /usr/local/lib64/python3.9/site-packages (from esrally) (2.0.1)
Requirement already satisfied: yappi==1.5.1 in /usr/local/lib64/python3.9/site-packages (from esrally) (1.5.1)
Requirement already satisfied: psutil==5.9.4 in /usr/local/lib64/python3.9/site-packages (from esrally) (5.9.4)
Requirement already satisfied: certifi in /usr/local/lib/python3.9/site-packages (from esrally) (2024.7.4)
Requirement already satisfied: elasticsearch[async]==8.6.1 in /usr/local/lib/python3.9/site-packages (from esrally) (8.6.1)
Requirement already satisfied: ijson==2.6.1 in /usr/local/lib/python3.9/site-packages (from esrally) (2.6.1)
Requirement already satisfied: jinja2==3.1.4 in /usr/local/lib/python3.9/site-packages (from esrally) (3.1.4)
Requirement already satisfied: requests<2.32.0 in /usr/local/lib/python3.9/site-packages (from esrally) (2.31.0)
Requirement already satisfied: tabulate==0.8.9 in /usr/local/lib/python3.9/site-packages (from esrally) (0.8.9)
Requirement already satisfied: zstandard==0.21.0 in /usr/local/lib64/python3.9/site-packages (from esrally) (0.21.0)
Requirement already satisfied: docker==6.0.0 in /usr/local/lib/python3.9/site-packages (from esrally) (6.0.0)
Requirement already satisfied: websocket-client>=0.32.0 in /usr/local/lib/python3.9/site-packages (from docker==6.0.0->esrally) (1.8.0)
Requirement already satisfied: packaging>=14.0 in /usr/lib/python3.9/site-packages (from docker==6.0.0->esrally) (20.9)
Requirement already satisfied: aiohttp<4,>=3 in /usr/local/lib64/python3.9/site-packages (from elasticsearch[async]==8.6.1->esrally) (3.10.4)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (0.4.0)
Requirement already satisfied: six>=1.9.0 in /usr/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (1.15.0)
Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (4.9)
Requirement already satisfied: setuptools>=40.3.0 in /usr/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (53.0.0)
Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (4.2.4)
Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in /usr/local/lib64/python3.9/site-packages (from google-resumable-media[requests]==1.1.0->esrally) (1.5.0)
Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.9/site-packages (from jsonschema==3.1.1->esrally) (24.2.0)
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.9/site-packages (from jsonschema==3.1.1->esrally) (8.2.0)
Requirement already satisfied: pyrsistent>=0.14.0 in /usr/local/lib64/python3.9/site-packages (from jsonschema==3.1.1->esrally) (0.20.0)
Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib64/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (1.9.4)
Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib64/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (1.4.1)
Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (1.3.1)
Requirement already satisfied: async-timeout<5.0,>=4.0 in /usr/local/lib/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (4.0.3)
Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /usr/local/lib/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (2.3.7)
Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib64/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (6.0.5)
Requirement already satisfied: pyparsing>=2.0.2 in /usr/lib/python3.9/site-packages (from packaging>=14.0->docker==6.0.0->esrally) (2.4.7)
Requirement already satisfied: pyasn1<0.7.0,>=0.4.6 in /usr/local/lib/python3.9/site-packages (from pyasn1-modules>=0.2.1->google-auth==1.22.1->esrally) (0.6.0)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/site-packages (from requests<2.32.0->esrally) (3.7)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib64/python3.9/site-packages (from requests<2.32.0->esrally) (3.3.2)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.9/site-packages (from importlib-metadata->jsonschema==3.1.1->esrally) (3.20.0)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
[root@easysearch /]# esrally --version
esrally 2.11.0
[root@easysearch /]#
关于 Rally 的更多内容,请参阅官方文档:
https://esrally.readthedocs.io/en/stable/
作者:少安事务所
原文:https://mp.weixin.qq.com/s/9eEH38kgsw4i150CJqyxvQ
INFINI Easysearch
INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 衍生自基于开源协议 Apache 2.0 的 Elasticsearch 7.10 版本,完善和支持更多的企业级功能,优化搜索业务场景,以保证更佳的数据探索与分析体验。
Easysearch 的主要特点:
- 兼容 Elasticsearch,业务代码无需改动;可平滑迁移
- 企业级安全;更稳定可靠
- 企业级管理后台(多集群统一管理,实现运营标准化、自动化)
- 信创适配(全面适配国产 CPU/OS/服务器,支持国密算法)
Easysearch 快速体验,请参阅:
Loadgen
Loadgen 是 Elasticsearch 专属压测工具,用来对 Easysearch 或者网关进行压力测试。
Loadgen 的特点:
- 性能强劲
- 轻量级无依赖
- 支持模板化参数随机
- 支持高并发
- 支持压测端均衡流量控制
- 支持服务端返回值校验
当前最新版本为 1.26.1-598,下载链接如下:
https://release.infinilabs.com/loadgen/stable/
下载并解压安装包后,得到二进制文件。
查看版本信息。
$ ./loadgen-linux-amd64 -v
__ ___ _ ___ ___ __ __
/ / /___\/_\ / \/ _ \ /__\/\ \ \
/ / // ///_\\ / /\ / /_\//_\ / \/ /
/ /__/ \_// _ \/ /_// /_\\//__/ /\ /
\____|___/\_/ \_/___,'\____/\__/\_\ \/
[LOADGEN] A http load generator and testing suite.
[LOADGEN] 1.26.1#598, 2024-08-14 04:50:03, 2024-12-31 10:10:10, 00f15fd86834d7ea539f6d66ee608e3915eef0e3
loadgen 1.26.1 598 2024-08-14 04:50:03 +0000 UTC 2024-12-31 10:10:10 +0000 UTC 00f15fd86834d7ea539f6d66ee608e3915eef0e3
Loadgen 测试
Loadgen 使用非常简单,下面演示如何进行查询压测。
- 建立索引,根据节点数调节分片数。
curl -X PUT -H "Content-Type: application/json" \
-ku admin:xxx "https://localhost:9200/loadtest" -d'
{
"settings":{
"number_of_shards":"3",
"number_of_replicas":1,
"translog":{
"durability":"async"
}
}
}'
{"acknowledged":true,"shards_acknowledged":true,"index":"loadtest"}
- 创建
loadgen.dsl.shawnyan
配置文件,定义查询
GET loadtest/_search
{"query": {"term": {"id.keyword": {"value": $[[id]]}}}}
- 执行压测,
-d
表示秒数,-c
表示并发数。
$ ES_ENDPOINT=https://localhost:9200 ES_USERNAME=admin ES_PASSWORD=xxx ./loadgen-linux-amd64 -run loadgen.dsl.shawnyan -d 10 -c 2
__ ___ _ ___ ___ __ __
/ / /___\/_\ / \/ _ \ /__\/\ \ \
/ / // ///_\\ / /\ / /_\//_\ / \/ /
/ /__/ \_// _ \/ /_// /_\\//__/ /\ /
\____|___/\_/ \_/___,'\____/\__/\_\ \/
[LOADGEN] A http load generator and testing suite.
[LOADGEN] 1.26.1#598, 2024-08-14 04:50:03, 2024-12-31 10:10:10, 00f15fd86834d7ea539f6d66ee608e3915eef0e3
[08-19 16:43:27] [INF] [env.go:179] configuration auto reload enabled
[08-19 16:43:27] [INF] [app.go:285] initializing loadgen, pid: 30792
[08-19 16:43:27] [INF] [app.go:286] using config: /data/es/loadgen.yml
[08-19 16:43:27] [INF] [module.go:155] started plugin: statsd
[08-19 16:43:27] [INF] [module.go:161] all modules are started
[08-19 16:43:27] [INF] [instance.go:78] workspace: /data/es/data/loadgen/nodes/cr1gabqr90cng685o2s0
[08-19 16:43:27] [INF] [app.go:511] loadgen is up and running now.
[08-19 16:43:27] [INF] [main.go:403] loading config: /data/es/loadgen.dsl.shawnyan
21108 requests finished in 9.79061677s, 1.08MB sent, 3.22MB received
[Loadgen Client Metrics]
Requests/sec: 2110.63
Request Traffic/sec: 110.22KB
Total Transfer/sec: 440.00KB
Fastest Request: 680.198µs
Slowest Request: 12.409574ms
Status 200: 21108
[Latency Metrics]
10000 samples of 21108 events
Cumulative: 8.732205871s
HMean: 851.869µs
Avg.: 873.22µs
p50: 839.498µs
p75: 914.298µs
p95: 1.059197ms
p99: 1.327098ms
p999: 4.83579ms
Long 5%: 1.394411ms
Short 5%: 724.226µs
Max: 11.618475ms
Min: 680.198µs
Range: 10.938277ms
StdDev: 289.216µs
Rate/sec.: 2110.63
[Latency Distribution]
680µs - 1.774ms ------------------------------
1.774ms - 2.867ms -
2.867ms - 3.961ms -
3.961ms - 5.055ms -
5.055ms - 6.149ms -
6.149ms - 7.243ms -
7.243ms - 8.336ms -
8.336ms - 9.43ms -
9.43ms - 10.524ms -
10.524ms - 11.618ms -
[Estimated Server Metrics]
Requests/sec: 2155.94
Avg Req Time: 927.668µs
Transfer/sec: 449.45KB
更多内容请参阅文档:
https://infinilabs.cn/docs/latest/gateway/getting-started/benchmark/
Rally
如果对 Elasticsearch 熟悉的同学,也可尝试使用 Rally 对 Easysearch 进行测试。
Rally 是 Elasticsearch 的基准测试框架。它可以帮助您完成以下任务:
- 安装 Elasticsearch 集群以进行基准测试
- 跨 Elasticsearch 版本管理基准数据和规范
- 运行基准测试并记录结果
- 通过连接遥测设备来查找性能问题
- 比较性能结果
安装 Rally。
[root@easysearch /]# pip3 install esrally
Requirement already satisfied: esrally in /usr/local/lib/python3.9/site-packages (2.11.0)
Requirement already satisfied: py-cpuinfo==7.0.0 in /usr/local/lib/python3.9/site-packages (from esrally) (7.0.0)
Requirement already satisfied: elastic-transport==8.4.1 in /usr/local/lib/python3.9/site-packages (from esrally) (8.4.1)
Requirement already satisfied: google-resumable-media[requests]==1.1.0 in /usr/local/lib/python3.9/site-packages (from esrally) (1.1.0)
Requirement already satisfied: urllib3==1.26.18 in /usr/local/lib/python3.9/site-packages (from esrally) (1.26.18)
Requirement already satisfied: google-auth==1.22.1 in /usr/local/lib/python3.9/site-packages (from esrally) (1.22.1)
Requirement already satisfied: thespian==3.10.1 in /usr/local/lib/python3.9/site-packages (from esrally) (3.10.1)
Requirement already satisfied: jsonschema==3.1.1 in /usr/local/lib/python3.9/site-packages (from esrally) (3.1.1)
Requirement already satisfied: markupsafe==2.0.1 in /usr/local/lib64/python3.9/site-packages (from esrally) (2.0.1)
Requirement already satisfied: yappi==1.5.1 in /usr/local/lib64/python3.9/site-packages (from esrally) (1.5.1)
Requirement already satisfied: psutil==5.9.4 in /usr/local/lib64/python3.9/site-packages (from esrally) (5.9.4)
Requirement already satisfied: certifi in /usr/local/lib/python3.9/site-packages (from esrally) (2024.7.4)
Requirement already satisfied: elasticsearch[async]==8.6.1 in /usr/local/lib/python3.9/site-packages (from esrally) (8.6.1)
Requirement already satisfied: ijson==2.6.1 in /usr/local/lib/python3.9/site-packages (from esrally) (2.6.1)
Requirement already satisfied: jinja2==3.1.4 in /usr/local/lib/python3.9/site-packages (from esrally) (3.1.4)
Requirement already satisfied: requests<2.32.0 in /usr/local/lib/python3.9/site-packages (from esrally) (2.31.0)
Requirement already satisfied: tabulate==0.8.9 in /usr/local/lib/python3.9/site-packages (from esrally) (0.8.9)
Requirement already satisfied: zstandard==0.21.0 in /usr/local/lib64/python3.9/site-packages (from esrally) (0.21.0)
Requirement already satisfied: docker==6.0.0 in /usr/local/lib/python3.9/site-packages (from esrally) (6.0.0)
Requirement already satisfied: websocket-client>=0.32.0 in /usr/local/lib/python3.9/site-packages (from docker==6.0.0->esrally) (1.8.0)
Requirement already satisfied: packaging>=14.0 in /usr/lib/python3.9/site-packages (from docker==6.0.0->esrally) (20.9)
Requirement already satisfied: aiohttp<4,>=3 in /usr/local/lib64/python3.9/site-packages (from elasticsearch[async]==8.6.1->esrally) (3.10.4)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (0.4.0)
Requirement already satisfied: six>=1.9.0 in /usr/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (1.15.0)
Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (4.9)
Requirement already satisfied: setuptools>=40.3.0 in /usr/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (53.0.0)
Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.9/site-packages (from google-auth==1.22.1->esrally) (4.2.4)
Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in /usr/local/lib64/python3.9/site-packages (from google-resumable-media[requests]==1.1.0->esrally) (1.5.0)
Requirement already satisfied: attrs>=17.4.0 in /usr/local/lib/python3.9/site-packages (from jsonschema==3.1.1->esrally) (24.2.0)
Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.9/site-packages (from jsonschema==3.1.1->esrally) (8.2.0)
Requirement already satisfied: pyrsistent>=0.14.0 in /usr/local/lib64/python3.9/site-packages (from jsonschema==3.1.1->esrally) (0.20.0)
Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib64/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (1.9.4)
Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib64/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (1.4.1)
Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (1.3.1)
Requirement already satisfied: async-timeout<5.0,>=4.0 in /usr/local/lib/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (4.0.3)
Requirement already satisfied: aiohappyeyeballs>=2.3.0 in /usr/local/lib/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (2.3.7)
Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib64/python3.9/site-packages (from aiohttp<4,>=3->elasticsearch[async]==8.6.1->esrally) (6.0.5)
Requirement already satisfied: pyparsing>=2.0.2 in /usr/lib/python3.9/site-packages (from packaging>=14.0->docker==6.0.0->esrally) (2.4.7)
Requirement already satisfied: pyasn1<0.7.0,>=0.4.6 in /usr/local/lib/python3.9/site-packages (from pyasn1-modules>=0.2.1->google-auth==1.22.1->esrally) (0.6.0)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/site-packages (from requests<2.32.0->esrally) (3.7)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib64/python3.9/site-packages (from requests<2.32.0->esrally) (3.3.2)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.9/site-packages (from importlib-metadata->jsonschema==3.1.1->esrally) (3.20.0)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
[root@easysearch /]# esrally --version
esrally 2.11.0
[root@easysearch /]#
关于 Rally 的更多内容,请参阅官方文档:
https://esrally.readthedocs.io/en/stable/
收起阅读 »作者:少安事务所
原文:https://mp.weixin.qq.com/s/9eEH38kgsw4i150CJqyxvQ
Easysearch x 《黑神话悟空》有奖征文获奖结果公示
随着《黑神话:悟空》游戏的正式发售,我们 INFINI Labs 组织的 Easysearch 有奖征文大赛也圆满落幕。本次征文活动自启动以来,收到了众多创作者的热情投稿。在此,我们衷心感谢每一位参与活动的作者,是你们的才华和热情让这次征文活动异彩纷呈。
经过专业评审团的认真评选,最终确定了以下获奖作品及作者,现予以公布:
奖项 | 作者 | 作品 | 奖品 |
---|---|---|---|
一等奖 | AWS 加油站 | 玩转 Easysearch 语法 | 《黑神话:悟空》数字豪华版一套 |
二等奖 | 杨帆 | 使用 Easysearch 打造企业内部知识问答系统 | 《黑神话:悟空》数字标准版一套 |
二等奖 | 李家兴 | 从 Elasticsearch 到 Easysearch:国产搜索型数据库的崛起与未来展望 | 《黑神话:悟空》数字标准版一套 |
三等奖 | 严少安 | Easysearch,地表最强,没有之一! | INFINI Labs 咖啡杯 / 指甲剪套装 |
三等奖 | 张磊 | Easysearch 新特性:写入限流功能介绍 | INFINI Labs 咖啡杯 / 指甲剪套装 |
三等奖 | keep | 如何在 MacOS 环境下快速安装部署 Easysearch | INFINI Labs 咖啡杯 / 指甲剪套装 |
恭喜以上获奖作者,你们的作品不仅展现了 Easysearch 的强大功能,也为社区成员提供了宝贵的学习资源。我们将会通过小助手微信联系各位获奖者,安排奖品的发放。
同时,我们也要感谢所有参与本次征文活动的作者,你们的每一篇 Easysearch 投稿都是对社区的一份贡献。我们期待在未来的活动中再次与大家相遇。
请继续关注 INFINI Labs,我们将持续为大家带来更多优质的产品和精彩的活动。再次感谢大家的参与和支持!
如有疑问或想加入 Easysearch 用户交流群请联系我们小助手!
附征文活动原文:
天命人, 你在吗?快拿走你的《黑神话:悟空》游戏,去开启神话冒险!
关于极限科技(INFINI Labs)
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
随着《黑神话:悟空》游戏的正式发售,我们 INFINI Labs 组织的 Easysearch 有奖征文大赛也圆满落幕。本次征文活动自启动以来,收到了众多创作者的热情投稿。在此,我们衷心感谢每一位参与活动的作者,是你们的才华和热情让这次征文活动异彩纷呈。
经过专业评审团的认真评选,最终确定了以下获奖作品及作者,现予以公布:
奖项 | 作者 | 作品 | 奖品 |
---|---|---|---|
一等奖 | AWS 加油站 | 玩转 Easysearch 语法 | 《黑神话:悟空》数字豪华版一套 |
二等奖 | 杨帆 | 使用 Easysearch 打造企业内部知识问答系统 | 《黑神话:悟空》数字标准版一套 |
二等奖 | 李家兴 | 从 Elasticsearch 到 Easysearch:国产搜索型数据库的崛起与未来展望 | 《黑神话:悟空》数字标准版一套 |
三等奖 | 严少安 | Easysearch,地表最强,没有之一! | INFINI Labs 咖啡杯 / 指甲剪套装 |
三等奖 | 张磊 | Easysearch 新特性:写入限流功能介绍 | INFINI Labs 咖啡杯 / 指甲剪套装 |
三等奖 | keep | 如何在 MacOS 环境下快速安装部署 Easysearch | INFINI Labs 咖啡杯 / 指甲剪套装 |
恭喜以上获奖作者,你们的作品不仅展现了 Easysearch 的强大功能,也为社区成员提供了宝贵的学习资源。我们将会通过小助手微信联系各位获奖者,安排奖品的发放。
同时,我们也要感谢所有参与本次征文活动的作者,你们的每一篇 Easysearch 投稿都是对社区的一份贡献。我们期待在未来的活动中再次与大家相遇。
请继续关注 INFINI Labs,我们将持续为大家带来更多优质的产品和精彩的活动。再次感谢大家的参与和支持!
如有疑问或想加入 Easysearch 用户交流群请联系我们小助手!
附征文活动原文:
天命人, 你在吗?快拿走你的《黑神话:悟空》游戏,去开启神话冒险!
关于极限科技(INFINI Labs)
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
收起阅读 »如何在 MacOS 环境下快速安装部署 Easysearch
1、什么是 Easysearch
Easysearch 是极限科技研发的一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。 同时也是一款具备自主可控的分布式近实时搜索型数据库产品,具备高性能、高可用、弹性伸缩、高安全性等特性,具备支持丰富的个性化搜索及聚合分析能力,可部署在物理机、虚拟机、容器、私有云和公有云,能承载 PB 级别的海量业务数据,为金融核心系统、运营商、制造业和政企业务系统提供安全、稳定、可靠的快速检索和实时数据探索分析能力,可满足不同业务场景的各项复杂需求。
2、前期准备
在安装 Easysearch 之前,确保您的 MacOS 系统符合以下要求:
- MacOS 操作系统版本应为最新或推荐稳定版本。
- 确保系统上已安装 Java 运行环境,因为 Easysearch 是基于 Java 开发的。
3、下载 Easysearch
打开浏览器,访问 Easysearch 官方下载页面。
找到 MacOS 版本安装包,然后根据自己电脑 CPU 架构选择对应的 Easysearch 安装包。我自己的电脑是 Intel X86 架构,直接选择默认的 amd64,点击下载即可。如果你的电脑是 Apple 的自己的 M 系列芯片,请选择 arm64 版本安装包。
4、安装 Easysearch
打开终端(Terminal)并导航到下载目录,找到 Easysearch 的压缩包,然后双击解压到您选择的目录。或者使用以下命令解压文件:
unzip ./easysearch-1.8.3-265-mac-amd64.zip
5、启动 Easysearch
- 执行初始化脚本:
由于 Easysearch 默认自带了安全模块,所以在启动之前需要先执行初始化脚本,脚本里会自动帮我们处理好 Easysearch 安全证书、下载基本的 plugins 插件以及初始用户名和密码等,方便省心。
cd ./easysearch-1.8.3-265-mac-amd64 && bin/initialize.sh
执行过程中遇到 [y/N] 询问,输入 y 即可。最后执行完初始化脚本之后,我们可以在输出的 log 日志中看到 easysearch 的访问用户名和密码,需要注意的是,这个用户名和密码需要自己保存好。 如下图所示:
- 启动 Easysearch: 使用以下命令启动 Easysearch:
./bin/easysearch
启动后,Easysearch 将在终端中输出运行日志,您可以在此查看启动过程中的详细信息。
6、验证安装
- 检查运行状态:
打开浏览器,访问 https://localhost:9200
,输入上面提到的用户名密码,如果您看到类似以下的 JSON 响应,说明 Easysearch 已成功启动:
- 检查集群健康状况:
在浏览器中输入 https:/localhost:9200/_cluster/health?pretty
或者在终端中执行以下命令来检查集群的健康状况:
curl -ku admin:4395c2f67208ca5ad7de https://localhost:9200/_cluster/health?pretty"
这将返回集群的详细健康信息,status
为 green 表示集群状态正常。如下图所示:
7、总结
通过上述步骤,可以轻松地在 MacOS 环境下安装和部署 Easysearch,享受它带来的强大功能和便捷体验。Easysearch 作为 Elasticsearch 的替代产品,不仅在功能上保持了高效和稳定,还进一步优化了搜索业务场景,使其更适合企业级应用。现在,您可以进一步配置集群,开始索引数据,并探索 Easysearch 提供的强大搜索和分析功能。建议参考 官网文档,深入了解并实践更多高级功能。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:Keep simple
原文:https://blog.csdn.net/weixin_48688147/article/details/141238374
1、什么是 Easysearch
Easysearch 是极限科技研发的一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。 同时也是一款具备自主可控的分布式近实时搜索型数据库产品,具备高性能、高可用、弹性伸缩、高安全性等特性,具备支持丰富的个性化搜索及聚合分析能力,可部署在物理机、虚拟机、容器、私有云和公有云,能承载 PB 级别的海量业务数据,为金融核心系统、运营商、制造业和政企业务系统提供安全、稳定、可靠的快速检索和实时数据探索分析能力,可满足不同业务场景的各项复杂需求。
2、前期准备
在安装 Easysearch 之前,确保您的 MacOS 系统符合以下要求:
- MacOS 操作系统版本应为最新或推荐稳定版本。
- 确保系统上已安装 Java 运行环境,因为 Easysearch 是基于 Java 开发的。
3、下载 Easysearch
打开浏览器,访问 Easysearch 官方下载页面。
找到 MacOS 版本安装包,然后根据自己电脑 CPU 架构选择对应的 Easysearch 安装包。我自己的电脑是 Intel X86 架构,直接选择默认的 amd64,点击下载即可。如果你的电脑是 Apple 的自己的 M 系列芯片,请选择 arm64 版本安装包。
4、安装 Easysearch
打开终端(Terminal)并导航到下载目录,找到 Easysearch 的压缩包,然后双击解压到您选择的目录。或者使用以下命令解压文件:
unzip ./easysearch-1.8.3-265-mac-amd64.zip
5、启动 Easysearch
- 执行初始化脚本:
由于 Easysearch 默认自带了安全模块,所以在启动之前需要先执行初始化脚本,脚本里会自动帮我们处理好 Easysearch 安全证书、下载基本的 plugins 插件以及初始用户名和密码等,方便省心。
cd ./easysearch-1.8.3-265-mac-amd64 && bin/initialize.sh
执行过程中遇到 [y/N] 询问,输入 y 即可。最后执行完初始化脚本之后,我们可以在输出的 log 日志中看到 easysearch 的访问用户名和密码,需要注意的是,这个用户名和密码需要自己保存好。 如下图所示:
- 启动 Easysearch: 使用以下命令启动 Easysearch:
./bin/easysearch
启动后,Easysearch 将在终端中输出运行日志,您可以在此查看启动过程中的详细信息。
6、验证安装
- 检查运行状态:
打开浏览器,访问 https://localhost:9200
,输入上面提到的用户名密码,如果您看到类似以下的 JSON 响应,说明 Easysearch 已成功启动:
- 检查集群健康状况:
在浏览器中输入 https:/localhost:9200/_cluster/health?pretty
或者在终端中执行以下命令来检查集群的健康状况:
curl -ku admin:4395c2f67208ca5ad7de https://localhost:9200/_cluster/health?pretty"
这将返回集群的详细健康信息,status
为 green 表示集群状态正常。如下图所示:
7、总结
通过上述步骤,可以轻松地在 MacOS 环境下安装和部署 Easysearch,享受它带来的强大功能和便捷体验。Easysearch 作为 Elasticsearch 的替代产品,不仅在功能上保持了高效和稳定,还进一步优化了搜索业务场景,使其更适合企业级应用。现在,您可以进一步配置集群,开始索引数据,并探索 Easysearch 提供的强大搜索和分析功能。建议参考 官网文档,深入了解并实践更多高级功能。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »作者:Keep simple
原文:https://blog.csdn.net/weixin_48688147/article/details/141238374
使用 AWS EKS 部署 Easysearch
随着企业对数据搜索和分析需求的增加,高效的搜索引擎解决方案变得越来越重要。Easysearch 作为一款强大的企业级搜索引擎,可以帮助企业快速构建高性能、可扩展的数据检索系统。在云计算的背景下,使用容器化技术来部署和管理这些解决方案已经成为主流选择,而 Amazon Elastic Kubernetes Service (EKS) 则提供了一个强大且易于使用的平台来运行容器化的应用程序。
本文旨在探索如何在 AWS EKS 上部署 Easysearch,并通过实践操作展示从集群配置到服务部署的完整过程。通过本文,读者可以了解如何在云环境中快速搭建高效的搜索服务,最大化利用云资源的弹性和可扩展性。
准备工作
- 准备一个 AWS Global 账户,本文选择东京区域(ap-northeast-1)进行部署。
- 部署 EKS 集群版本为 1.30,同时需要在 Linux 环境中安装 AWS CLI、Helm、eksctl 和 kubectl 等命令行工具。本文使用 eksctl 管理 EKS 集群,eksctl 是 AWS 官方推出的高效管理 EKS 集群的命令行工具。
- 本文将使用 EBS-CSI-Driver 作为存储驱动来部署 Easysearch 服务,并通过 AWS LoadBalancer Controller 将 Easysearch Console 服务以 AWS 负载均衡器的方式对外提供服务,连接集群内部的 Easysearch。
命令行工具的安装
安装 AWS CLI:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install -i /usr/local/aws-cli -b /usr/local/bin
aws --version
安装 Helm:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
安装 eksctl:
# 对于 ARM 系统,设置 ARCH 为:`arm64`、`armv6` 或 `armv7`
ARCH=amd64
PLATFORM=$(uname -s)_$ARCH
curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
# (可选)验证校验和
curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check
tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
sudo mv /tmp/eksctl /usr/local/bin
安装 kubectl:
curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.30.2/2024-07-12/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
配置 EKS 集群环境
我们使用 eksctl 创建一个 1.30 版本的集群,这里通过 YAML 模板定义 EKS 集群的 VPC 网络配置,并根据 eksctl 官方文档调整相关字段。将以下模板保存为 my-cluster.yaml
文件:
# 创建一个包含 2 个 m5.2xlarge 实例的节点组
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: LAB-1-30
region: ap-northeast-1
vpc:
subnets:
private:
ap-northeast-1a: { id: subnet-11223344 }
ap-northeast-1c: { id: subnet-55667788 }
ap-northeast-1d: { id: subnet-99001122 }
nodeGroups:
- name: managed-workers-01
labels: { role: workers }
instanceType: m5.2xlarge
minSize: 2
maxSize: 4
desiredCapacity: 3
privateNetworking: true
volumeSize: 30
通过以下命令创建集群:
eksctl create cluster -f my-cluster.yaml
集群创建完成后,使用以下命令检查集群是否就绪:
# 更新 kubeconfig 的凭证文件
aws eks update-kubeconfig --name LAB-1-30 --region ap-northeast-1
kubectl get node
[ec2-user@ip-10-0-0-84 ~]$ kubectl get node
NAME STATUS ROLES AGE VERSION
ip-10-0-100-132.ap-northeast-1.compute.internal Ready <none> 16m v1.30.2-eks-1552ad0
ip-10-0-101-148.ap-northeast-1.compute.internal Ready <none> 16m v1.30.2-eks-1552ad0
安装 EBS-CSI-Driver 插件,后续部署时可以指定 StorageClass 来使用亚马逊云的 EBS 块存储服务:
eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=LAB-1-30 --approve
eksctl create iamserviceaccount \
--name ebs-csi-controller-sa \
--namespace kube-system \
--cluster LAB-1-30 \
--region ap-northeast-1 \
--role-name AmazonEKS_EBS_CSI_DriverRole \
--role-only \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
--approve
eksctl create addon --cluster LAB-1-30 --name aws-ebs-csi-driver --version latest --region ap-northeast-1 \
--service-account-role-arn arn:aws:iam::112233445566:role/AmazonEKS_EBS_CSI_DriverRole --force
[ec2-user@ip-10-0-0-84 ~]$ kubectl get pod -n kube-system | grep -i ebs
ebs-csi-controller-868598b64f-pwmxq 6/6 Running 0 11m
ebs-csi-controller-868598b64f-qn2lz 6/6 Running 0 11m
ebs-csi-node-fplxg 3/3 Running 0 11m
ebs-csi-node-v6qwj 3/3 Running 0 11m
安装 AWS LoadBalancer Controller 组件:
eksctl create iamserviceaccount \
--cluster=LAB-1-30 \
--region ap-northeast-1 \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole_130 \
--attach-policy-arn=arn:aws:iam::112233445566:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
helm repo add eks https://aws.github.io/eks-charts
helm repo update eks
wget https://raw.githubusercontent.com/aws/eks-charts/master/stable/aws-load-balancer-controller/crds/crds.yaml
kubectl apply -f crds.yaml
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=LAB-1-30 \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=ap-northeast-1
# 验证安装
kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 39s
至此,我们已经完成了 EKS 集群的配置。
安装 Easysearch 服务
本文中,将通过 AWS LoadBalancer 部署 Console 服务。首先,通过 Helm 将 Console 相关的模板文件拉取到本地,执行以下命令:
helm pull infinilabs/console
tar -zxvf console-0.2.0.tgz
cd console
目录结构如下:
[ec2-user@ip-10-0-0-84 console]$ tree
.
├── Chart.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── statefulset.yaml
└── values.yaml
我们需要修改 service.yaml
和 values.yaml
中的部分配置:
# serivce.yaml
# 参考 AWS Load Balancer Controller 的文档,配置负载均衡器面向公网
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-11223344, subnet-55667788, subnet-9911223344
# values.yaml
# 使用 GP2 StorageClass,并指定 Service Type 为 LoadBalancer
service:
type: LoadBalancer
storageClassName: gp2
使用 Helm 部署 console 服务:
kubectl create ns Easysearch
helm upgrade --install console . -f values.yaml -n Easysearch
# 检查是否创建了 Service 并获取负载均衡器的 DNS 地址
kubectl get svc -n Easysearch
NAME TYPE CL
USTER-IP EXTERNAL-IP PORT(S) AGE
console LoadBalancer 172.20.237.237 k8s-xxxx.elb.ap-northeast-1.amazonaws.com 9000:32190/TCP 6h49m
接下来是创建 Easysearch 单节点集群服务。创建一个新的 values.yaml
文件并定义使用 GP2 类型的 StorageClass,如下:
cd ~
echo 'storageClassName: gp2' > values.yaml
cat << EOF | kubectl apply -n Easysearch -f -
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: Easysearch-ca-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: Easysearch-ca-certificate
spec:
commonName: Easysearch-ca-certificate
duration: 87600h0m0s
isCA: true
issuerRef:
kind: Issuer
name: Easysearch-ca-issuer
privateKey:
algorithm: ECDSA
size: 256
renewBefore: 2160h0m0s
secretName: Easysearch-ca-secret
EOF
helm install Easysearch infinilabs/Easysearch -n Easysearch -f values.yaml
至此,我们已在 AWS EKS 平台上完成了 Easysearch 的部署。可以通过 Kubernetes 中的 Service DNS 地址在 Console 中验证连接到内部的 Easysearch 服务。本文中使用的地址为:Easysearch.Easysearch.svc.cluster.local:9200
。
也可以在 Easysearch 的 Pod 中使用命令进行连接验证:
kubectl exec -n Easysearch Easysearch-0 -it -- curl -ku 'admin:admin' https://Easysearch.Easysearch.svc.cluster.local:9200
{
"name" : "Easysearch-0",
"cluster_name" : "infinilabs",
"cluster_uuid" : "fq3r_ZaHSFuZDjDtKyJY_w",
"version" : {
"distribution" : "Easysearch",
"number" : "1.6.0",
"distributor" : "INFINI Labs",
"build_hash" : "e5d1ff9067b3dd696d52c61fbca1f8daed931fb7",
"build_date" : "2023-09-22T00:55:32.292580Z",
"build_snapshot" : false,
"lucene_version" : "8.11.2",
"minimum_wire_lucene_version" : "7.7.0",
"minimum_lucene_index_compatibility_version" : "7.7.0"
},
"tagline" : "You Know, For Easy Search!"
}
总结
通过本文的实践操作,我们成功地在 AWS EKS 平台上部署了 Easysearch 服务,验证了其在云环境中的高效运行能力。从 EKS 集群的配置、存储和网络资源的准备,到最终的 Easysearch 部署与测试,整个过程展示了如何利用 AWS 提供的工具和服务,快速构建企业级搜索引擎解决方案。
通过这次部署,我们不仅了解了 Easysearch 在 Kubernetes 环境中的部署方法,还深入体验了 AWS EKS 平台的强大功能。未来,随着企业数据量的不断增长,结合云计算的弹性和容器化技术的优势,将会为企业的数据管理和搜索提供更加高效的解决方案。
参考文档
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://infinilabs.cn/blog/2024/deploy-easysearch-using-aws-eks/
随着企业对数据搜索和分析需求的增加,高效的搜索引擎解决方案变得越来越重要。Easysearch 作为一款强大的企业级搜索引擎,可以帮助企业快速构建高性能、可扩展的数据检索系统。在云计算的背景下,使用容器化技术来部署和管理这些解决方案已经成为主流选择,而 Amazon Elastic Kubernetes Service (EKS) 则提供了一个强大且易于使用的平台来运行容器化的应用程序。
本文旨在探索如何在 AWS EKS 上部署 Easysearch,并通过实践操作展示从集群配置到服务部署的完整过程。通过本文,读者可以了解如何在云环境中快速搭建高效的搜索服务,最大化利用云资源的弹性和可扩展性。
准备工作
- 准备一个 AWS Global 账户,本文选择东京区域(ap-northeast-1)进行部署。
- 部署 EKS 集群版本为 1.30,同时需要在 Linux 环境中安装 AWS CLI、Helm、eksctl 和 kubectl 等命令行工具。本文使用 eksctl 管理 EKS 集群,eksctl 是 AWS 官方推出的高效管理 EKS 集群的命令行工具。
- 本文将使用 EBS-CSI-Driver 作为存储驱动来部署 Easysearch 服务,并通过 AWS LoadBalancer Controller 将 Easysearch Console 服务以 AWS 负载均衡器的方式对外提供服务,连接集群内部的 Easysearch。
命令行工具的安装
安装 AWS CLI:
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install -i /usr/local/aws-cli -b /usr/local/bin
aws --version
安装 Helm:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
安装 eksctl:
# 对于 ARM 系统,设置 ARCH 为:`arm64`、`armv6` 或 `armv7`
ARCH=amd64
PLATFORM=$(uname -s)_$ARCH
curl -sLO "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_$PLATFORM.tar.gz"
# (可选)验证校验和
curl -sL "https://github.com/eksctl-io/eksctl/releases/latest/download/eksctl_checksums.txt" | grep $PLATFORM | sha256sum --check
tar -xzf eksctl_$PLATFORM.tar.gz -C /tmp && rm eksctl_$PLATFORM.tar.gz
sudo mv /tmp/eksctl /usr/local/bin
安装 kubectl:
curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.30.2/2024-07-12/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$HOME/bin:$PATH
配置 EKS 集群环境
我们使用 eksctl 创建一个 1.30 版本的集群,这里通过 YAML 模板定义 EKS 集群的 VPC 网络配置,并根据 eksctl 官方文档调整相关字段。将以下模板保存为 my-cluster.yaml
文件:
# 创建一个包含 2 个 m5.2xlarge 实例的节点组
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: LAB-1-30
region: ap-northeast-1
vpc:
subnets:
private:
ap-northeast-1a: { id: subnet-11223344 }
ap-northeast-1c: { id: subnet-55667788 }
ap-northeast-1d: { id: subnet-99001122 }
nodeGroups:
- name: managed-workers-01
labels: { role: workers }
instanceType: m5.2xlarge
minSize: 2
maxSize: 4
desiredCapacity: 3
privateNetworking: true
volumeSize: 30
通过以下命令创建集群:
eksctl create cluster -f my-cluster.yaml
集群创建完成后,使用以下命令检查集群是否就绪:
# 更新 kubeconfig 的凭证文件
aws eks update-kubeconfig --name LAB-1-30 --region ap-northeast-1
kubectl get node
[ec2-user@ip-10-0-0-84 ~]$ kubectl get node
NAME STATUS ROLES AGE VERSION
ip-10-0-100-132.ap-northeast-1.compute.internal Ready <none> 16m v1.30.2-eks-1552ad0
ip-10-0-101-148.ap-northeast-1.compute.internal Ready <none> 16m v1.30.2-eks-1552ad0
安装 EBS-CSI-Driver 插件,后续部署时可以指定 StorageClass 来使用亚马逊云的 EBS 块存储服务:
eksctl utils associate-iam-oidc-provider --region=ap-northeast-1 --cluster=LAB-1-30 --approve
eksctl create iamserviceaccount \
--name ebs-csi-controller-sa \
--namespace kube-system \
--cluster LAB-1-30 \
--region ap-northeast-1 \
--role-name AmazonEKS_EBS_CSI_DriverRole \
--role-only \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
--approve
eksctl create addon --cluster LAB-1-30 --name aws-ebs-csi-driver --version latest --region ap-northeast-1 \
--service-account-role-arn arn:aws:iam::112233445566:role/AmazonEKS_EBS_CSI_DriverRole --force
[ec2-user@ip-10-0-0-84 ~]$ kubectl get pod -n kube-system | grep -i ebs
ebs-csi-controller-868598b64f-pwmxq 6/6 Running 0 11m
ebs-csi-controller-868598b64f-qn2lz 6/6 Running 0 11m
ebs-csi-node-fplxg 3/3 Running 0 11m
ebs-csi-node-v6qwj 3/3 Running 0 11m
安装 AWS LoadBalancer Controller 组件:
eksctl create iamserviceaccount \
--cluster=LAB-1-30 \
--region ap-northeast-1 \
--namespace=kube-system \
--name=aws-load-balancer-controller \
--role-name AmazonEKSLoadBalancerControllerRole_130 \
--attach-policy-arn=arn:aws:iam::112233445566:policy/AWSLoadBalancerControllerIAMPolicy \
--approve
helm repo add eks https://aws.github.io/eks-charts
helm repo update eks
wget https://raw.githubusercontent.com/aws/eks-charts/master/stable/aws-load-balancer-controller/crds/crds.yaml
kubectl apply -f crds.yaml
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
-n kube-system \
--set clusterName=LAB-1-30 \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller \
--set region=ap-northeast-1
# 验证安装
kubectl get deployment -n kube-system aws-load-balancer-controller
NAME READY UP-TO-DATE AVAILABLE AGE
aws-load-balancer-controller 2/2 2 2 39s
至此,我们已经完成了 EKS 集群的配置。
安装 Easysearch 服务
本文中,将通过 AWS LoadBalancer 部署 Console 服务。首先,通过 Helm 将 Console 相关的模板文件拉取到本地,执行以下命令:
helm pull infinilabs/console
tar -zxvf console-0.2.0.tgz
cd console
目录结构如下:
[ec2-user@ip-10-0-0-84 console]$ tree
.
├── Chart.yaml
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── statefulset.yaml
└── values.yaml
我们需要修改 service.yaml
和 values.yaml
中的部分配置:
# serivce.yaml
# 参考 AWS Load Balancer Controller 的文档,配置负载均衡器面向公网
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: instance
service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-11223344, subnet-55667788, subnet-9911223344
# values.yaml
# 使用 GP2 StorageClass,并指定 Service Type 为 LoadBalancer
service:
type: LoadBalancer
storageClassName: gp2
使用 Helm 部署 console 服务:
kubectl create ns Easysearch
helm upgrade --install console . -f values.yaml -n Easysearch
# 检查是否创建了 Service 并获取负载均衡器的 DNS 地址
kubectl get svc -n Easysearch
NAME TYPE CL
USTER-IP EXTERNAL-IP PORT(S) AGE
console LoadBalancer 172.20.237.237 k8s-xxxx.elb.ap-northeast-1.amazonaws.com 9000:32190/TCP 6h49m
接下来是创建 Easysearch 单节点集群服务。创建一个新的 values.yaml
文件并定义使用 GP2 类型的 StorageClass,如下:
cd ~
echo 'storageClassName: gp2' > values.yaml
cat << EOF | kubectl apply -n Easysearch -f -
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: Easysearch-ca-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: Easysearch-ca-certificate
spec:
commonName: Easysearch-ca-certificate
duration: 87600h0m0s
isCA: true
issuerRef:
kind: Issuer
name: Easysearch-ca-issuer
privateKey:
algorithm: ECDSA
size: 256
renewBefore: 2160h0m0s
secretName: Easysearch-ca-secret
EOF
helm install Easysearch infinilabs/Easysearch -n Easysearch -f values.yaml
至此,我们已在 AWS EKS 平台上完成了 Easysearch 的部署。可以通过 Kubernetes 中的 Service DNS 地址在 Console 中验证连接到内部的 Easysearch 服务。本文中使用的地址为:Easysearch.Easysearch.svc.cluster.local:9200
。
也可以在 Easysearch 的 Pod 中使用命令进行连接验证:
kubectl exec -n Easysearch Easysearch-0 -it -- curl -ku 'admin:admin' https://Easysearch.Easysearch.svc.cluster.local:9200
{
"name" : "Easysearch-0",
"cluster_name" : "infinilabs",
"cluster_uuid" : "fq3r_ZaHSFuZDjDtKyJY_w",
"version" : {
"distribution" : "Easysearch",
"number" : "1.6.0",
"distributor" : "INFINI Labs",
"build_hash" : "e5d1ff9067b3dd696d52c61fbca1f8daed931fb7",
"build_date" : "2023-09-22T00:55:32.292580Z",
"build_snapshot" : false,
"lucene_version" : "8.11.2",
"minimum_wire_lucene_version" : "7.7.0",
"minimum_lucene_index_compatibility_version" : "7.7.0"
},
"tagline" : "You Know, For Easy Search!"
}
总结
通过本文的实践操作,我们成功地在 AWS EKS 平台上部署了 Easysearch 服务,验证了其在云环境中的高效运行能力。从 EKS 集群的配置、存储和网络资源的准备,到最终的 Easysearch 部署与测试,整个过程展示了如何利用 AWS 提供的工具和服务,快速构建企业级搜索引擎解决方案。
通过这次部署,我们不仅了解了 Easysearch 在 Kubernetes 环境中的部署方法,还深入体验了 AWS EKS 平台的强大功能。未来,随着企业数据量的不断增长,结合云计算的弹性和容器化技术的优势,将会为企业的数据管理和搜索提供更加高效的解决方案。
参考文档
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://infinilabs.cn/blog/2024/deploy-easysearch-using-aws-eks/
从 Elasticsearch 到 Easysearch:国产搜索型数据库的崛起与未来展望
1. 引言:数据库的定义与作用
1.1 数据库的定义
数据库是一个专门用于组织、存储和管理数据的系统(Database System,简称 DBS),它以高效的方式为用户提供数据的存储、访问和管理功能。数据库的定义涵盖了各种数据模型和结构,主要可以分为关系型数据库(RDBMS)和非关系型数据库(NoSQL)两大类。
-
关系型数据库:以二维表格的形式组织数据,通过主键、外键来维持表与表之间的关系。这种数据库模型擅长处理结构化数据,并且通过 SQL(Structured Query Language)来管理数据。其最大的优势在于数据的一致性和完整性,但在处理大量非结构化数据时可能表现不佳。
- 非关系型数据库:也称为 NoSQL 数据库,适合存储和处理非结构化或半结构化数据,如文档、键值对、图形和列族等。NoSQL 数据库通常具有更高的灵活性和扩展性,尤其适合处理大规模分布式数据集和实时数据处理任务。
1.2 数据库在现代计算中的作用
在现代计算环境中,数据库是信息系统的核心。无论是互联网企业,还是传统行业的数字化转型,都依赖于强大的数据库系统来支撑各种应用程序的运行。数据库的作用包括:
-
数据存储:数据库能够安全地存储大规模数据,无论是结构化数据如表格,还是非结构化数据如图像和文本。
-
数据管理:数据库提供了复杂的查询、排序、更新、删除等操作,确保数据可以被有效地管理和利用。
-
数据分析:借助数据库中的索引和搜索功能,用户可以对海量数据进行快速检索和分析,从而支持实时决策和业务优化。
- 数据安全:数据库系统通常包含访问控制、加密、备份和恢复等功能,保护数据的机密性、完整性和可用性。
数据库已经成为现代企业运作的基石,为电子商务、社交媒体、金融服务、健康医疗等领域提供了不可或缺的数据支持。
2. 数据库的演变
2.1 关系型数据库的崛起
数据库的发展主要历经三个阶段,前关系型、关系型和后关系型。
20 世纪 70 年代,埃德加·科德提出了关系型数据库模型的概念,这一创新彻底改变了数据管理的方式。关系型数据库以关系代数为理论基础,将数据组织为多个相互关联的二维表格,这种模型极大简化了数据存储与检索的复杂性。
-
表格结构:数据以表的形式存储,每个表由行和列组成,行代表记录,列代表字段。表与表之间通过主键和外键来建立关系。
-
SQL 的引入:为了管理关系型数据库,科德引入了结构化查询语言(SQL),这是一种强大的数据操作语言,允许用户通过简单的语句执行复杂的查询操作。
- 数据的一致性和完整性:关系型数据库通过事务处理机制(ACID 特性:原子性、一致性、隔离性和持久性),确保数据在并发操作和系统故障情况下保持一致性和完整性。
由于其高效的数据管理能力和强大的查询功能,关系型数据库迅速成为企业级应用的主流选择,在银行、保险、制造业等领域得到了广泛应用。
2.2 关系型数据库的局限性
随着信息技术的飞速发展,数据量呈现爆炸式增长,数据类型也日益多样化,这使得关系型数据库逐渐暴露出其局限性。
-
扩展性不足:关系型数据库通常依赖垂直扩展(增加单个服务器的硬件能力)来提升性能,但这种方式在面对海量数据时成本高昂且效率有限。而对于需要分布式处理的大规模数据集,关系型数据库的横向扩展能力(增加服务器节点)较弱,难以满足分布式系统的需求。
-
非结构化数据处理困难:关系型数据库擅长处理结构化数据,但对于文本、图像、视频等非结构化数据的处理效率较低,需要额外的处理步骤和存储空间。这种局限性使其在面对现代大数据环境时显得捉襟见肘。
- 灵活性不足:关系型数据库的表结构和模式是预定义的,这意味着在数据模型发生变化时,修改数据库结构的成本和风险都较高,影响了系统的灵活性和适应性。
这些局限性推动了新型数据库技术的发展,尤其是 NoSQL 数据库的兴起,它们能够更好地处理分布式环境下的大规模非结构化数据。
3. 搜索型数据库的兴起
3.1 非结构化数据处理的需求
随着互联网和信息技术的发展,数据的类型和规模发生了巨大变化。除了传统的结构化数据,非结构化数据(如文本、图像、音频、视频等)也在迅速增长。这类数据并不适合存储在传统的关系型数据库中,因为它们无法以固定的表格形式进行有效的组织和管理。
在这种背景下,企业和组织对非结构化数据的处理和分析需求日益强烈。例如,社交媒体平台需要实时分析大量用户生成的文本内容,电子商务网站需要对用户的搜索和购买历史进行个性化推荐。这些需求促使数据库技术朝着更灵活和高效的方向发展。
为了应对这一挑战,NoSQL 数据库应运而生。NoSQL 数据库不依赖于固定的表格结构,而是支持多种数据模型,如文档、键值对、列族和图数据库等。它们在处理大规模分布式数据和非结构化数据时表现优异,尤其是在扩展性和灵活性方面。
然而,随着搜索需求的日益复杂,简单的 NoSQL 数据库已无法满足企业对快速全文检索、实时分析以及复杂查询的需求。这时,搜索型数据库逐渐成为焦点。它们不仅能够处理大规模数据,还能在数秒内从庞大的数据集中检索出相关信息,大大提升了数据的利用价值。
3.2 搜索型数据库的定义与特点
搜索型数据库是一类专门设计用于处理和检索大量非结构化数据的数据库系统。与传统的关系型数据库不同,搜索型数据库的主要功能是快速、准确地进行全文检索和复杂查询,尤其是在处理文本数据时表现出色。
核心技术与特点:
-
倒排索引:这是搜索型数据库的核心技术,它通过为每个单词建立索引来加速查询过程。当用户输入查询时,系统可以直接通过索引定位相关文档,而无需逐个扫描整个数据库。
-
分布式架构:搜索型数据库通常采用分布式架构,以便能够处理大规模的数据集。它们将数据分布在多个节点上,确保即使在高并发或大数据量的情况下,系统仍然能够高效运行。
-
实时数据处理:现代搜索型数据库不仅支持批量数据处理,还能处理实时数据,这使得它们非常适合用于日志管理、监控和数据流分析等场景。
- 可扩展性:由于采用了分布式设计,搜索型数据库可以通过增加节点轻松扩展,从而处理日益增长的数据量和查询需求。
通过这些特点,搜索型数据库已经成为处理海量非结构化数据的关键工具,为企业和组织提供了强大的数据检索和分析能力。
4. Elasticsearch:革命性的搜索型数据库
4.1 Elasticsearch 的背景与发展
Elasticsearch 是由 Shay Banon 于 2010 年基于开源搜索引擎库 Apache Lucene 开发的。它的出现,标志着搜索型数据库进入了一个新的时代。Elasticsearch 旨在为现代数据驱动的应用程序提供高效、灵活的搜索和分析功能。由于其强大的功能和易用性,Elasticsearch 迅速在全球范围内获得了广泛的采用。
Elasticsearch 的诞生源于对大规模数据处理和全文检索的需求。随着互联网的快速发展,企业需要一种能够高效处理和搜索海量数据的工具,而传统的关系型数据库和早期的 NoSQL 解决方案无法满足这一需求。Elasticsearch 在此背景下应运而生,成为解决这些挑战的理想选择。
4.2 核心特性与架构
Elasticsearch 之所以能够在众多搜索型数据库中脱颖而出,主要得益于其强大的核心特性和先进的架构设计。
核心特性:
-
分布式架构:Elasticsearch 的分布式设计使其能够在多个节点上分片存储数据,从而实现高可用性和可扩展性。每个分片都是一个独立的搜索引擎,可以在多个节点之间进行复制,以确保数据的冗余和安全。
-
RESTful API:Elasticsearch 提供了一个易于使用的 RESTful API,开发者可以通过简单的 HTTP 请求与其进行交互。这种设计使得 Elasticsearch 可以轻松集成到各种应用程序中。
-
实时索引和搜索:Elasticsearch 支持实时数据索引,这意味着数据在写入后几乎可以立即被搜索到。这一特性使其非常适合用于日志管理、监控和实时分析等需要快速响应的场景。
- 灵活的查询语言:Elasticsearch 提供了功能强大的查询 DSL(Domain Specific Language),允许用户进行复杂的查询操作,如布尔查询、范围查询、模糊查询等。它还支持聚合查询,使用户能够对数据进行高级分析。
架构设计:
Elasticsearch 的架构基于分片(Shard)和副本(Replica)的概念。每个索引被划分为若干个分片,每个分片可以有一个或多个副本。这种设计不仅提高了数据的可用性和容错性,还使得系统能够轻松处理大规模数据集。
此外,Elasticsearch 还使用了 Apache Lucene 作为底层搜索库,充分利用了 Lucene 强大的全文检索能力和索引机制。这使得 Elasticsearch 在处理复杂搜索任务时表现得非常高效。
4.3 典型应用场景
Elasticsearch 在多个行业和场景中得到了广泛应用,其灵活性和强大的搜索能力使其成为许多企业的首选解决方案。
-
日志和基础设施监控:在 IT 运维中,Elasticsearch 常用于收集和分析系统日志、应用日志和安全日志。通过与 Kibana(一个开源的分析和可视化平台)结合,用户可以实时监控系统状态,并快速识别和解决问题。
-
企业搜索:Elasticsearch 被广泛应用于企业内部文档和数据的搜索管理。无论是知识管理系统还是文档管理平台,Elasticsearch 都能够提供高效的全文检索和信息聚合能力,帮助企业提升工作效率。
- 电子商务搜索:在电子商务领域,Elasticsearch 用于实现快速、精确的产品搜索和推荐系统。它不仅可以处理大量产品数据,还能根据用户行为提供个性化推荐,提升用户体验和转化率。
5. Elasticsearch 的挑战与发展
5.1 扩展性问题
尽管 Elasticsearch 在处理大规模数据方面表现优异,但在面对极端大规模的应用场景时,其扩展性仍然是一个挑战。由于分布式系统的复杂性,网络分区、节点故障等问题可能导致数据不一致,甚至影响系统的整体性能。
为了应对这些挑战,开发者们引入了多种扩展性优化措施,例如改进分片管理策略、优化分布式查询算法等。这些改进旨在提高 Elasticsearch 在大规模集群中的稳定性和效率,但随着数据量的持续增长,扩展性问题仍然是一个需要持续关注和解决的问题。
5.2 性能优化
随着使用 Elasticsearch 的企业和应用越来越多,性能优化成为了一个关键议题。为了保证 Elasticsearch 在大规模数据处理中的高效性,开发者们采取了多种优化手段,包括改进索引策略、调整缓存机制、优化查询执行路径等。
此外,为了满足不同场景下的性能需求,Elasticsearch 还引入了多种配置选项,允许用户根据具体应用场景进行调整。例如,通过调整分片数量和副本数,用户可以在性能和数据冗余之间找到平衡。
5.3 安全与合规
随着全球数据隐私和安全法律法规的日益严格,Elasticsearch 在安全和合规性方面的挑战也日益凸显。企业在使用 Elasticsearch 时,必须确保数据的安全性和合规性,尤其是在处理敏感数据时。
为了解决这些问题,Elasticsearch 提供了一系列安全功能,如访问控制、数据加密、审计日志等。此外,开发者们还可以通过配置和插件,实现更高级别的安全措施,以满足特定行业和地区的合规要求。
但是,Elasticsearch 的安全性和合规性仍然是一个需要不断优化的领域。近几年 ES 数据泄露事件频发,很多 ES 库连基本的安全认证都没有,导致很多企业直接把 ES 当做存储库,数据泄露后直接被黑客利用。
结合今年 OpenAi 停止对中国内地和香港地区提供 API 服务可以看出,依赖国外技术可能带来技术封锁风险,一旦国外企业因政治或经济原因停止服务,中国企业的业务连续性和数据安全性将受到威胁。
6. 国内搜索型数据库的发展
6.1 中国搜索数据库的发展背景
随着国家对科技自主创新的重视,中国的数据库技术在过去十年中取得了显著进展。尤其是在中美技术竞争加剧的背景下,减少对国外技术的依赖成为了中国科技发展的战略目标。这种背景促使了国产数据库的加速发展,特别是在搜索型数据库领域。众多中国企业开始自主研发具备核心技术的数据库产品,试图在这一领域实现突破。
政策推动与市场需求
中国政府出台了一系列政策,鼓励本土企业在关键技术领域实现自主可控。这些政策不仅为企业提供了资金支持和政策优惠,还明确了在一些关键行业中优先使用国产软件的导向。同时,随着中国企业在互联网、电子商务、智能制造等领域的快速发展,对高效搜索和数据处理的需求愈发迫切,这也成为国产搜索型数据库发展的强大推动力。
6.2 Easysearch 的兴起
在此背景下,Easysearch 作为中国本土开发的搜索型数据库脱颖而出。Easysearch 的设计目标是为中国企业提供一个高效、可靠且适应本土需求的搜索与数据分析解决方案。与国外的 Elasticsearch 相似,Easysearch 基于分布式架构和倒排索引技术,能够处理大规模数据,并支持复杂的全文搜索和分析。
然而,Easysearch 并非只是简单的模仿或复制 Elasticsearch。它在多个方面进行了本地化优化,以更好地适应中国市场的独特需求。例如,在处理中文文本时,Easysearch 针对中文的特殊语法结构进行了优化,增强了中文分词的准确性和查询效率。此外,Easysearch 还在性能和可扩展性上进行了改进,使其能够更好地应对大规模企业级应用的需求。
不仅如此,Easysearch 还是国内首个通过搜索型数据库产品能力测试的国产搜索型数据库。自 2023 年 10 月起,Easysearch 凭借其卓越的性能和深度的本土化优化,成功在墨天轮搜索型数据库排行榜上长期占据榜首位置。这一成绩不仅体现了 Easysearch 在技术层面的突破,也反映了市场对其产品的高度认可。在短短几个月的时间里,Easysearch 以其稳定的表现和不断创新的步伐,赢得了众多企业用户的信赖。
6.3 Easysearch 与 Elasticsearch 的对比
虽然 Easysearch 与 Elasticsearch 在架构和基本功能上有很多相似之处,但它们在具体的实现和应用场景中表现出了一些显著的差异。
-
中文文本处理:Elasticsearch 虽然支持多语言环境,但其在中文处理上的表现并不如 Easysearch 那么出色。Easysearch 针对中文的语法和分词进行了专门的优化,尤其是在处理同义词、短语匹配和模糊查询时,能够提供更高的准确性。
-
本地化支持:Easysearch 提供了更强的本地化支持,包括符合中国法律法规的安全和合规性功能。此外,它还集成了许多国内常用的第三方系统,简化了企业的集成和部署过程。
-
性能优化:在处理大规模数据集时,Easysearch 通过定制化的优化策略,如特定的索引压缩技术和内存管理方案,提升了系统的响应速度和资源利用率。这使得它在某些特定应用场景下,能够提供比 Elasticsearch 更高的性能和稳定性。
- 安全可靠:Easysearch 提供了多种安全和合规性功能,如 TLS 加密、磁盘加密等。此外,它还支持多种第三方认证方式,如 LDAP、AD
6.4 国产搜索型数据库的未来
根据第一新声研究,2022-2027 年中国数据库整体市场将维持增长态势 ,2024 年整体市场规模预计为 543.1 亿,到 2027 年将增长至 1183.8 亿,2022-2027 年复合增长率达到 30.67%。
随着全球对数据安全和本地化需求的不断增加,国产搜索型数据库在未来有望占据更大的市场份额。
Easysearch 及其他国产数据库将进一步提升技术水平,持续创新,以满足不断变化的市场需求。
全球化与竞争力
虽然当前 Easysearch 主要面向国内市场,但其潜在的全球化前景不容小觑。通过持续的技术创新和市场拓展,Easysearch 及其他国产数据库有望在全球范围内与国际巨头展开竞争,特别是在亚非拉等新兴市场。这不仅有助于提升中国数据库技术的国际影响力,也将推动全球数据库产业的多样化发展。
7. 结论
通过对搜索型数据库的发展历程和未来趋势的探讨,可以看出,随着大数据和人工智能技术的不断进步,搜索型数据库将在更多领域发挥重要作用。Elasticsearch 作为全球领先的搜索型数据库,其开创性的架构和功能为行业树立了标杆。而以 Easysearch 为代表的国产数据库,也正在迅速崛起,展现出强大的竞争力。未来,搜索型数据库将继续朝着多模态、智能化、本地化的方向发展,为全球信息技术的发展提供更加坚实的基础。
参考资料
- 搜索引擎数据库
- 搜索型数据库的技术发展历程与趋势前瞻
- 数据库行业分析:国产数据库百花齐放,搜索引擎数据库风口已至
- 浅谈搜索引擎和传统数据库(ES,solr)
- 什么是 Elasticsearch?
- INFINI Labs 产品更新 | 重磅推出 Easysearch v1.1
- 墨天轮中国数据库流行度排行
- 喜讯!INFINI Easysearch 在墨天轮搜索型数据库排名中荣登榜首
- 《2024 年中国数据库市场研究报告》重磅发布 | 第一新声
- 国内首家 | 极限科技率先完成信通院搜索型数据库行业标准测试
- 危险!超 9000 个 Elasticsearch 集群暴露在公网上
- 从 OpenAI 停服看中国市场:国产替代崛起的机遇与挑战
- 什么是数据库
- 数据库发展史
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:李家兴
1. 引言:数据库的定义与作用
1.1 数据库的定义
数据库是一个专门用于组织、存储和管理数据的系统(Database System,简称 DBS),它以高效的方式为用户提供数据的存储、访问和管理功能。数据库的定义涵盖了各种数据模型和结构,主要可以分为关系型数据库(RDBMS)和非关系型数据库(NoSQL)两大类。
-
关系型数据库:以二维表格的形式组织数据,通过主键、外键来维持表与表之间的关系。这种数据库模型擅长处理结构化数据,并且通过 SQL(Structured Query Language)来管理数据。其最大的优势在于数据的一致性和完整性,但在处理大量非结构化数据时可能表现不佳。
- 非关系型数据库:也称为 NoSQL 数据库,适合存储和处理非结构化或半结构化数据,如文档、键值对、图形和列族等。NoSQL 数据库通常具有更高的灵活性和扩展性,尤其适合处理大规模分布式数据集和实时数据处理任务。
1.2 数据库在现代计算中的作用
在现代计算环境中,数据库是信息系统的核心。无论是互联网企业,还是传统行业的数字化转型,都依赖于强大的数据库系统来支撑各种应用程序的运行。数据库的作用包括:
-
数据存储:数据库能够安全地存储大规模数据,无论是结构化数据如表格,还是非结构化数据如图像和文本。
-
数据管理:数据库提供了复杂的查询、排序、更新、删除等操作,确保数据可以被有效地管理和利用。
-
数据分析:借助数据库中的索引和搜索功能,用户可以对海量数据进行快速检索和分析,从而支持实时决策和业务优化。
- 数据安全:数据库系统通常包含访问控制、加密、备份和恢复等功能,保护数据的机密性、完整性和可用性。
数据库已经成为现代企业运作的基石,为电子商务、社交媒体、金融服务、健康医疗等领域提供了不可或缺的数据支持。
2. 数据库的演变
2.1 关系型数据库的崛起
数据库的发展主要历经三个阶段,前关系型、关系型和后关系型。
20 世纪 70 年代,埃德加·科德提出了关系型数据库模型的概念,这一创新彻底改变了数据管理的方式。关系型数据库以关系代数为理论基础,将数据组织为多个相互关联的二维表格,这种模型极大简化了数据存储与检索的复杂性。
-
表格结构:数据以表的形式存储,每个表由行和列组成,行代表记录,列代表字段。表与表之间通过主键和外键来建立关系。
-
SQL 的引入:为了管理关系型数据库,科德引入了结构化查询语言(SQL),这是一种强大的数据操作语言,允许用户通过简单的语句执行复杂的查询操作。
- 数据的一致性和完整性:关系型数据库通过事务处理机制(ACID 特性:原子性、一致性、隔离性和持久性),确保数据在并发操作和系统故障情况下保持一致性和完整性。
由于其高效的数据管理能力和强大的查询功能,关系型数据库迅速成为企业级应用的主流选择,在银行、保险、制造业等领域得到了广泛应用。
2.2 关系型数据库的局限性
随着信息技术的飞速发展,数据量呈现爆炸式增长,数据类型也日益多样化,这使得关系型数据库逐渐暴露出其局限性。
-
扩展性不足:关系型数据库通常依赖垂直扩展(增加单个服务器的硬件能力)来提升性能,但这种方式在面对海量数据时成本高昂且效率有限。而对于需要分布式处理的大规模数据集,关系型数据库的横向扩展能力(增加服务器节点)较弱,难以满足分布式系统的需求。
-
非结构化数据处理困难:关系型数据库擅长处理结构化数据,但对于文本、图像、视频等非结构化数据的处理效率较低,需要额外的处理步骤和存储空间。这种局限性使其在面对现代大数据环境时显得捉襟见肘。
- 灵活性不足:关系型数据库的表结构和模式是预定义的,这意味着在数据模型发生变化时,修改数据库结构的成本和风险都较高,影响了系统的灵活性和适应性。
这些局限性推动了新型数据库技术的发展,尤其是 NoSQL 数据库的兴起,它们能够更好地处理分布式环境下的大规模非结构化数据。
3. 搜索型数据库的兴起
3.1 非结构化数据处理的需求
随着互联网和信息技术的发展,数据的类型和规模发生了巨大变化。除了传统的结构化数据,非结构化数据(如文本、图像、音频、视频等)也在迅速增长。这类数据并不适合存储在传统的关系型数据库中,因为它们无法以固定的表格形式进行有效的组织和管理。
在这种背景下,企业和组织对非结构化数据的处理和分析需求日益强烈。例如,社交媒体平台需要实时分析大量用户生成的文本内容,电子商务网站需要对用户的搜索和购买历史进行个性化推荐。这些需求促使数据库技术朝着更灵活和高效的方向发展。
为了应对这一挑战,NoSQL 数据库应运而生。NoSQL 数据库不依赖于固定的表格结构,而是支持多种数据模型,如文档、键值对、列族和图数据库等。它们在处理大规模分布式数据和非结构化数据时表现优异,尤其是在扩展性和灵活性方面。
然而,随着搜索需求的日益复杂,简单的 NoSQL 数据库已无法满足企业对快速全文检索、实时分析以及复杂查询的需求。这时,搜索型数据库逐渐成为焦点。它们不仅能够处理大规模数据,还能在数秒内从庞大的数据集中检索出相关信息,大大提升了数据的利用价值。
3.2 搜索型数据库的定义与特点
搜索型数据库是一类专门设计用于处理和检索大量非结构化数据的数据库系统。与传统的关系型数据库不同,搜索型数据库的主要功能是快速、准确地进行全文检索和复杂查询,尤其是在处理文本数据时表现出色。
核心技术与特点:
-
倒排索引:这是搜索型数据库的核心技术,它通过为每个单词建立索引来加速查询过程。当用户输入查询时,系统可以直接通过索引定位相关文档,而无需逐个扫描整个数据库。
-
分布式架构:搜索型数据库通常采用分布式架构,以便能够处理大规模的数据集。它们将数据分布在多个节点上,确保即使在高并发或大数据量的情况下,系统仍然能够高效运行。
-
实时数据处理:现代搜索型数据库不仅支持批量数据处理,还能处理实时数据,这使得它们非常适合用于日志管理、监控和数据流分析等场景。
- 可扩展性:由于采用了分布式设计,搜索型数据库可以通过增加节点轻松扩展,从而处理日益增长的数据量和查询需求。
通过这些特点,搜索型数据库已经成为处理海量非结构化数据的关键工具,为企业和组织提供了强大的数据检索和分析能力。
4. Elasticsearch:革命性的搜索型数据库
4.1 Elasticsearch 的背景与发展
Elasticsearch 是由 Shay Banon 于 2010 年基于开源搜索引擎库 Apache Lucene 开发的。它的出现,标志着搜索型数据库进入了一个新的时代。Elasticsearch 旨在为现代数据驱动的应用程序提供高效、灵活的搜索和分析功能。由于其强大的功能和易用性,Elasticsearch 迅速在全球范围内获得了广泛的采用。
Elasticsearch 的诞生源于对大规模数据处理和全文检索的需求。随着互联网的快速发展,企业需要一种能够高效处理和搜索海量数据的工具,而传统的关系型数据库和早期的 NoSQL 解决方案无法满足这一需求。Elasticsearch 在此背景下应运而生,成为解决这些挑战的理想选择。
4.2 核心特性与架构
Elasticsearch 之所以能够在众多搜索型数据库中脱颖而出,主要得益于其强大的核心特性和先进的架构设计。
核心特性:
-
分布式架构:Elasticsearch 的分布式设计使其能够在多个节点上分片存储数据,从而实现高可用性和可扩展性。每个分片都是一个独立的搜索引擎,可以在多个节点之间进行复制,以确保数据的冗余和安全。
-
RESTful API:Elasticsearch 提供了一个易于使用的 RESTful API,开发者可以通过简单的 HTTP 请求与其进行交互。这种设计使得 Elasticsearch 可以轻松集成到各种应用程序中。
-
实时索引和搜索:Elasticsearch 支持实时数据索引,这意味着数据在写入后几乎可以立即被搜索到。这一特性使其非常适合用于日志管理、监控和实时分析等需要快速响应的场景。
- 灵活的查询语言:Elasticsearch 提供了功能强大的查询 DSL(Domain Specific Language),允许用户进行复杂的查询操作,如布尔查询、范围查询、模糊查询等。它还支持聚合查询,使用户能够对数据进行高级分析。
架构设计:
Elasticsearch 的架构基于分片(Shard)和副本(Replica)的概念。每个索引被划分为若干个分片,每个分片可以有一个或多个副本。这种设计不仅提高了数据的可用性和容错性,还使得系统能够轻松处理大规模数据集。
此外,Elasticsearch 还使用了 Apache Lucene 作为底层搜索库,充分利用了 Lucene 强大的全文检索能力和索引机制。这使得 Elasticsearch 在处理复杂搜索任务时表现得非常高效。
4.3 典型应用场景
Elasticsearch 在多个行业和场景中得到了广泛应用,其灵活性和强大的搜索能力使其成为许多企业的首选解决方案。
-
日志和基础设施监控:在 IT 运维中,Elasticsearch 常用于收集和分析系统日志、应用日志和安全日志。通过与 Kibana(一个开源的分析和可视化平台)结合,用户可以实时监控系统状态,并快速识别和解决问题。
-
企业搜索:Elasticsearch 被广泛应用于企业内部文档和数据的搜索管理。无论是知识管理系统还是文档管理平台,Elasticsearch 都能够提供高效的全文检索和信息聚合能力,帮助企业提升工作效率。
- 电子商务搜索:在电子商务领域,Elasticsearch 用于实现快速、精确的产品搜索和推荐系统。它不仅可以处理大量产品数据,还能根据用户行为提供个性化推荐,提升用户体验和转化率。
5. Elasticsearch 的挑战与发展
5.1 扩展性问题
尽管 Elasticsearch 在处理大规模数据方面表现优异,但在面对极端大规模的应用场景时,其扩展性仍然是一个挑战。由于分布式系统的复杂性,网络分区、节点故障等问题可能导致数据不一致,甚至影响系统的整体性能。
为了应对这些挑战,开发者们引入了多种扩展性优化措施,例如改进分片管理策略、优化分布式查询算法等。这些改进旨在提高 Elasticsearch 在大规模集群中的稳定性和效率,但随着数据量的持续增长,扩展性问题仍然是一个需要持续关注和解决的问题。
5.2 性能优化
随着使用 Elasticsearch 的企业和应用越来越多,性能优化成为了一个关键议题。为了保证 Elasticsearch 在大规模数据处理中的高效性,开发者们采取了多种优化手段,包括改进索引策略、调整缓存机制、优化查询执行路径等。
此外,为了满足不同场景下的性能需求,Elasticsearch 还引入了多种配置选项,允许用户根据具体应用场景进行调整。例如,通过调整分片数量和副本数,用户可以在性能和数据冗余之间找到平衡。
5.3 安全与合规
随着全球数据隐私和安全法律法规的日益严格,Elasticsearch 在安全和合规性方面的挑战也日益凸显。企业在使用 Elasticsearch 时,必须确保数据的安全性和合规性,尤其是在处理敏感数据时。
为了解决这些问题,Elasticsearch 提供了一系列安全功能,如访问控制、数据加密、审计日志等。此外,开发者们还可以通过配置和插件,实现更高级别的安全措施,以满足特定行业和地区的合规要求。
但是,Elasticsearch 的安全性和合规性仍然是一个需要不断优化的领域。近几年 ES 数据泄露事件频发,很多 ES 库连基本的安全认证都没有,导致很多企业直接把 ES 当做存储库,数据泄露后直接被黑客利用。
结合今年 OpenAi 停止对中国内地和香港地区提供 API 服务可以看出,依赖国外技术可能带来技术封锁风险,一旦国外企业因政治或经济原因停止服务,中国企业的业务连续性和数据安全性将受到威胁。
6. 国内搜索型数据库的发展
6.1 中国搜索数据库的发展背景
随着国家对科技自主创新的重视,中国的数据库技术在过去十年中取得了显著进展。尤其是在中美技术竞争加剧的背景下,减少对国外技术的依赖成为了中国科技发展的战略目标。这种背景促使了国产数据库的加速发展,特别是在搜索型数据库领域。众多中国企业开始自主研发具备核心技术的数据库产品,试图在这一领域实现突破。
政策推动与市场需求
中国政府出台了一系列政策,鼓励本土企业在关键技术领域实现自主可控。这些政策不仅为企业提供了资金支持和政策优惠,还明确了在一些关键行业中优先使用国产软件的导向。同时,随着中国企业在互联网、电子商务、智能制造等领域的快速发展,对高效搜索和数据处理的需求愈发迫切,这也成为国产搜索型数据库发展的强大推动力。
6.2 Easysearch 的兴起
在此背景下,Easysearch 作为中国本土开发的搜索型数据库脱颖而出。Easysearch 的设计目标是为中国企业提供一个高效、可靠且适应本土需求的搜索与数据分析解决方案。与国外的 Elasticsearch 相似,Easysearch 基于分布式架构和倒排索引技术,能够处理大规模数据,并支持复杂的全文搜索和分析。
然而,Easysearch 并非只是简单的模仿或复制 Elasticsearch。它在多个方面进行了本地化优化,以更好地适应中国市场的独特需求。例如,在处理中文文本时,Easysearch 针对中文的特殊语法结构进行了优化,增强了中文分词的准确性和查询效率。此外,Easysearch 还在性能和可扩展性上进行了改进,使其能够更好地应对大规模企业级应用的需求。
不仅如此,Easysearch 还是国内首个通过搜索型数据库产品能力测试的国产搜索型数据库。自 2023 年 10 月起,Easysearch 凭借其卓越的性能和深度的本土化优化,成功在墨天轮搜索型数据库排行榜上长期占据榜首位置。这一成绩不仅体现了 Easysearch 在技术层面的突破,也反映了市场对其产品的高度认可。在短短几个月的时间里,Easysearch 以其稳定的表现和不断创新的步伐,赢得了众多企业用户的信赖。
6.3 Easysearch 与 Elasticsearch 的对比
虽然 Easysearch 与 Elasticsearch 在架构和基本功能上有很多相似之处,但它们在具体的实现和应用场景中表现出了一些显著的差异。
-
中文文本处理:Elasticsearch 虽然支持多语言环境,但其在中文处理上的表现并不如 Easysearch 那么出色。Easysearch 针对中文的语法和分词进行了专门的优化,尤其是在处理同义词、短语匹配和模糊查询时,能够提供更高的准确性。
-
本地化支持:Easysearch 提供了更强的本地化支持,包括符合中国法律法规的安全和合规性功能。此外,它还集成了许多国内常用的第三方系统,简化了企业的集成和部署过程。
-
性能优化:在处理大规模数据集时,Easysearch 通过定制化的优化策略,如特定的索引压缩技术和内存管理方案,提升了系统的响应速度和资源利用率。这使得它在某些特定应用场景下,能够提供比 Elasticsearch 更高的性能和稳定性。
- 安全可靠:Easysearch 提供了多种安全和合规性功能,如 TLS 加密、磁盘加密等。此外,它还支持多种第三方认证方式,如 LDAP、AD
6.4 国产搜索型数据库的未来
根据第一新声研究,2022-2027 年中国数据库整体市场将维持增长态势 ,2024 年整体市场规模预计为 543.1 亿,到 2027 年将增长至 1183.8 亿,2022-2027 年复合增长率达到 30.67%。
随着全球对数据安全和本地化需求的不断增加,国产搜索型数据库在未来有望占据更大的市场份额。
Easysearch 及其他国产数据库将进一步提升技术水平,持续创新,以满足不断变化的市场需求。
全球化与竞争力
虽然当前 Easysearch 主要面向国内市场,但其潜在的全球化前景不容小觑。通过持续的技术创新和市场拓展,Easysearch 及其他国产数据库有望在全球范围内与国际巨头展开竞争,特别是在亚非拉等新兴市场。这不仅有助于提升中国数据库技术的国际影响力,也将推动全球数据库产业的多样化发展。
7. 结论
通过对搜索型数据库的发展历程和未来趋势的探讨,可以看出,随着大数据和人工智能技术的不断进步,搜索型数据库将在更多领域发挥重要作用。Elasticsearch 作为全球领先的搜索型数据库,其开创性的架构和功能为行业树立了标杆。而以 Easysearch 为代表的国产数据库,也正在迅速崛起,展现出强大的竞争力。未来,搜索型数据库将继续朝着多模态、智能化、本地化的方向发展,为全球信息技术的发展提供更加坚实的基础。
参考资料
- 搜索引擎数据库
- 搜索型数据库的技术发展历程与趋势前瞻
- 数据库行业分析:国产数据库百花齐放,搜索引擎数据库风口已至
- 浅谈搜索引擎和传统数据库(ES,solr)
- 什么是 Elasticsearch?
- INFINI Labs 产品更新 | 重磅推出 Easysearch v1.1
- 墨天轮中国数据库流行度排行
- 喜讯!INFINI Easysearch 在墨天轮搜索型数据库排名中荣登榜首
- 《2024 年中国数据库市场研究报告》重磅发布 | 第一新声
- 国内首家 | 极限科技率先完成信通院搜索型数据库行业标准测试
- 危险!超 9000 个 Elasticsearch 集群暴露在公网上
- 从 OpenAI 停服看中国市场:国产替代崛起的机遇与挑战
- 什么是数据库
- 数据库发展史
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »作者:李家兴
【第2期】INFINI Easysearch 免费认证培训开放报名啦
探索 Easysearch 的无限可能,与 INFINI Labs 共赴搜索技术前沿!
随着数字化转型的加速,搜索技术已成为企业数据洞察的核心。INFINI Labs 作为搜索创新技术的引领者,诚邀所有对 Easysearch 搜索引擎感兴趣的开发者、技术爱好者及合作伙伴,参加我们即将于 2024 年 8 月 17 日至 18 日举办的 第二期 Easysearch 线上免费培训活动。这不仅是一场知识的盛宴,更是技能提升的加速器,将助您在职业道路上迈出坚实的一步!
活动亮点
- 系统课程,全面深入:从 Easysearch 的基本概念到环境搭建,再到高级功能的实战应用,INFINI Labs 的技术专家将为您带来全面而深入的讲解,确保每位参与者都能收获满满。
- 实战导向,解决痛点:课程设计紧贴实际需求,旨在帮助学员掌握 Easysearch 的核心技术,有效解决工作中的搜索需求和技术难题,让理论知识迅速转化为实践能力。
- 认证证书,助力进阶:后期 INFINI Labs 将推出 Easysearch 认证考试。通过考试的学员将获得官方认证的 Easysearch 证书,为您的职业发展增添强力背书,开启职业生涯的新篇章。
培训时间
2024 年 8 月 17 日至 18 日(周六、周日)共两天,每天具体培训时间:
- 上午 09:30 ~ 11:30
- 下午 14:00 ~ 16:00
培训内容概览
第一阶段:初识 Easysearch
- Easysearch 环境搭建与对比,了解其与 Elasticsearch 的差异;
- 功能初探:身份验证、数据脱敏、权限控制等,全面掌握 Easysearch 的基础功能;
- 容灾技术:兼容性验证、跨集群复制等,确保您的搜索服务稳定可靠;
第二阶段:Easysearch 高阶使用
- 深度探析:性能压测、数据迁移、请求管理等,提升 Easysearch 的使用效率;
- 高级功能:快照管理、可视化看板、告警功能等,让您的搜索服务更加智能;
- 生态集成:Filebeat、Logstash、LangChain 等,轻松实现 Easysearch 与其他工具的集成;
参与方式
本次活动完全免费,名额有限,请尽快报名,同时微信扫码添加小助手进群(培训会议地址将在微信群公布),锁定您的学习席位!
扫码或点击 我要报名
👉 立即行动:不要错过这次提升自我、与行业精英共成长的宝贵机会。让我们相聚云端,共同探索 Easysearch 的无限可能,开启技术进阶的新篇章!
参会提示
- 培训内容涉及动手实践,请务必自备电脑(Windows 系统环境请提前安装好 Linux 虚拟机);
- 请提前在 INFINI Labs 官网下载对应平台最新安装包(INFINI Easysearch、INFINI Gateway、INFINI Console);
- 下载地址:https://infinilabs.cn/download
联系我们
如有任何疑问,欢迎通过微信添加 [小助手:INFINI-Labs] 与我们联系。
INFINI Labs 期待与您相约,共赴这场技术盛宴!
关于 Easysearch
Easysearch 是一个分布式的近实时搜索与分析引擎,基于开源的 Apache Lucene 构建。它旨在提供一个自主可控、轻量级的 Elasticsearch 可替代版本,并不断完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更注重搜索业务场景的优化,同时保持其产品的简洁与易用性。
详情参见:Easysearch 介绍
Easysearch 有奖征文活动推荐
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
关于极限科技(INFINI Labs)
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
探索 Easysearch 的无限可能,与 INFINI Labs 共赴搜索技术前沿!
随着数字化转型的加速,搜索技术已成为企业数据洞察的核心。INFINI Labs 作为搜索创新技术的引领者,诚邀所有对 Easysearch 搜索引擎感兴趣的开发者、技术爱好者及合作伙伴,参加我们即将于 2024 年 8 月 17 日至 18 日举办的 第二期 Easysearch 线上免费培训活动。这不仅是一场知识的盛宴,更是技能提升的加速器,将助您在职业道路上迈出坚实的一步!
活动亮点
- 系统课程,全面深入:从 Easysearch 的基本概念到环境搭建,再到高级功能的实战应用,INFINI Labs 的技术专家将为您带来全面而深入的讲解,确保每位参与者都能收获满满。
- 实战导向,解决痛点:课程设计紧贴实际需求,旨在帮助学员掌握 Easysearch 的核心技术,有效解决工作中的搜索需求和技术难题,让理论知识迅速转化为实践能力。
- 认证证书,助力进阶:后期 INFINI Labs 将推出 Easysearch 认证考试。通过考试的学员将获得官方认证的 Easysearch 证书,为您的职业发展增添强力背书,开启职业生涯的新篇章。
培训时间
2024 年 8 月 17 日至 18 日(周六、周日)共两天,每天具体培训时间:
- 上午 09:30 ~ 11:30
- 下午 14:00 ~ 16:00
培训内容概览
第一阶段:初识 Easysearch
- Easysearch 环境搭建与对比,了解其与 Elasticsearch 的差异;
- 功能初探:身份验证、数据脱敏、权限控制等,全面掌握 Easysearch 的基础功能;
- 容灾技术:兼容性验证、跨集群复制等,确保您的搜索服务稳定可靠;
第二阶段:Easysearch 高阶使用
- 深度探析:性能压测、数据迁移、请求管理等,提升 Easysearch 的使用效率;
- 高级功能:快照管理、可视化看板、告警功能等,让您的搜索服务更加智能;
- 生态集成:Filebeat、Logstash、LangChain 等,轻松实现 Easysearch 与其他工具的集成;
参与方式
本次活动完全免费,名额有限,请尽快报名,同时微信扫码添加小助手进群(培训会议地址将在微信群公布),锁定您的学习席位!
扫码或点击 我要报名
👉 立即行动:不要错过这次提升自我、与行业精英共成长的宝贵机会。让我们相聚云端,共同探索 Easysearch 的无限可能,开启技术进阶的新篇章!
参会提示
- 培训内容涉及动手实践,请务必自备电脑(Windows 系统环境请提前安装好 Linux 虚拟机);
- 请提前在 INFINI Labs 官网下载对应平台最新安装包(INFINI Easysearch、INFINI Gateway、INFINI Console);
- 下载地址:https://infinilabs.cn/download
联系我们
如有任何疑问,欢迎通过微信添加 [小助手:INFINI-Labs] 与我们联系。
INFINI Labs 期待与您相约,共赴这场技术盛宴!
关于 Easysearch
Easysearch 是一个分布式的近实时搜索与分析引擎,基于开源的 Apache Lucene 构建。它旨在提供一个自主可控、轻量级的 Elasticsearch 可替代版本,并不断完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更注重搜索业务场景的优化,同时保持其产品的简洁与易用性。
详情参见:Easysearch 介绍
Easysearch 有奖征文活动推荐
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
关于极限科技(INFINI Labs)
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
收起阅读 »Easysearch、Elasticsearch、Amazon OpenSearch 快照兼容对比
在当今的数据驱动时代,搜索引擎的快照功能在数据保护和灾难恢复中至关重要。本文将对 Easysearch、Elasticsearch 和 Amazon OpenSearch 的快照兼容性进行比较,分析它们在快照创建、恢复、存储格式和跨平台兼容性等方面的特点,帮助大家更好地理解这些搜索引擎的差异,从而选择最适合自己需求的解决方案。
启动集群
Easysearch
服务器一般情况下默认参数都是很低的,而 Easysearch/Elasticsearch 是内存大户,所以就需要进行系统调优。
sysctl -w vm.max_map_count=262144
vm.max_map_count
是一个 Linux 内核参数,用于控制单个进程可以拥有的最大内存映射区域(VMA,Virtual Memory Areas)的数量。内存映射区域是指通过内存映射文件或匿名内存映射创建的虚拟内存区域。
这个参数在一些应用程序中非常重要,尤其是那些需要大量内存映射的应用程序,比如 Elasticsearch。Elasticsearch 使用内存映射文件来索引和搜索数据,这可能需要大量的内存映射区域。如果 vm.max_map_count
设置得太低,Elasticsearch 可能无法正常工作,并会出现错误信息。
调整 vm.max_map_count
参数的一些常见原因:
-
支持大型数据集: 应用程序(如 Elasticsearch)在处理大型数据集时可能需要大量内存映射区域。增加
vm.max_map_count
可以确保这些应用程序有足够的内存映射区域来处理数据。 -
防止内存错误: 如果
vm.max_map_count
设置得太低,当应用程序尝试创建超过限制的内存映射时,会出现错误,导致应用程序崩溃或无法正常工作。 - 优化性能:
适当地设置
vm.max_map_count
可以优化应用程序的性能,确保内存映射操作顺利进行。
检查当前的 vm.max_map_count
值:
sysctl vm.max_map_count
或者查看 /proc/sys/vm/max_map_count
文件:
cat /proc/sys/vm/max_map_count
Elasticsearch 官方建议将 vm.max_map_count
设置为至少 262144。对于其他应用程序。
Easysearch 具体安装步骤见 INFINI Easysearch 尝鲜 Hands on
Amazon OpenSearch
使用 Amazon Web Services 控制台进行创建。
Elasticsearch
使用如下 docker compose 部署一个三节点的 ES 集群:
version: "2.2"
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- elastic
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: es02
environment:
- node.name=es02
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data02:/usr/share/elasticsearch/data
networks:
- elastic
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: es03
environment:
- node.name=es03
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data03:/usr/share/elasticsearch/data
networks:
- elastic
volumes:
data01:
driver: local
data02:
driver: local
data03:
driver: local
networks:
elastic:
driver: bridge
由于这个 docker compose 没有关于 kibana 的配置,所以我们还是用 Console 添加原生的 Elasticsearch 集群!
集群信息
快照还原的步骤
快照前的准备
插件安装
本次测试选择把索引快照备份到 Amazon S3,所以需要使用 S3 repository plugin,这个插件添加了对使用 Amazon S3 作为快照/恢复存储库的支持。
Easysearch 和 OpenSearch 集群自带了这个插件,所以无需额外安装。
对于自己部署的三节点 Elasticsearch 则需要进入每一个节点运行安装命令然后再重启集群,建议使用自动化运维工具来做这步,安装命令如下:
sudo bin/elasticsearch-plugin install repository-s3
如果不再需要这个插件,可以这样删除。
sudo bin/elasticsearch-plugin remove repository-s3
由于需要和 Amazon Web Services 打交道,所以我们需要设置 IAM 凭证,这个插件可以从 EC2 IAM instance profile,ECS task role 以及 EKS 的 Service account 读取相应的凭证。
对于托管的 Amazon OpenSearch 来说,我们无法在托管的 EC2 上绑定我们的凭证,所以需要新建一个 OpenSearchSnapshotRole,然后通过当前的用户把这个角色传递给服务,也就是我们说的 IAM:PassRole。
创建 OpenSearchSnapshotRole,策略如下:
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-name"
]
},
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-name/*"
]
}
]
}
信任关系如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "es.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
然后在我们的 IAM user 上加上 PassRole 的权限,这样我们就可以把 OpenSearchSnapshotRole 传递给 OpenSearch 集群。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
}
]
}
注册存储库
在源集群执行注册
PUT /_snapshot/snapshot-repo-name
{
"type": "s3",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
在目标集群同样执行这个语句,为了防止覆盖源集群存储库的数据,将 "readonly": true 添加到"settings" PUT 请求中,这样就只有一个集群具有对存储库的写入权限。
PUT /_snapshot/snapshot-repo-name
{
"type": "s3",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
"readonly": true,
对于 OpenSearch 来说,还需要执行 passrole,所以还需要添加role_arn这个字段,由于 IAM:PassRole 需要对 HTTP 请求做 signV4 日签名,所以这部常常使用 Postman 来完成。把角色传递过去之后,接下来的快照还原操作就可以在 OpenSearch Dashboard 中进行操作了。
需要注意的是,需要在 auth 这里输入 AccessKey,SecretKey,AWS Region,Service Name(es)来做 SignV4 的签名。
请求体如下:
{
"type": "s3",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
"readonly": true,
"role_arn": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
}
}
- 查看所有注册的存储库:
GET _snapshot
:这个命令返回所有已注册的快照存储库列表及其基本信息。
GET _snapshot
{
"es_repository": {
"type": "s3",
"settings": {
"bucket": "your-s3-bucket-name",
"region": "your-s3-bucket-region"
}
}
}
- 查看特定存储库的详细信息:
GET _snapshot/es_repository
:这个命令返回名为es_repository
的存储库的详细配置信息,包括存储桶名称、区域和其他设置。
GET _snapshot/es_repository
{
"es_repository": {
"type": "s3",
"settings": {
"bucket": "your-s3-bucket-name",
"region": "your-s3-bucket-region",
"access_key": "your-access-key",
"secret_key": "your-secret-key"
}
}
}
- 查看特定存储库中的快照:
GET _cat/snapshots/es_repository?v
:这个命令返回es_repository
存储库中的所有快照及其详细信息,包括快照 ID、状态、开始时间、结束时间、持续时间、包含的索引数量、成功和失败的分片数量等。
GET _cat/snapshots/es_repository?v
id status start_epoch start_time end_epoch end_time duration indices successful_shards failed_shards total_shards
snapshot_1 SUCCESS 1628884800 08:00:00 1628888400 09:00:00 1h 3 10 0 10
snapshot_2 SUCCESS 1628971200 08:00:00 1628974800 09:00:00 1h 3 10 0 10
创建索引快照
# PUT _snapshot/my_repository/<my_snapshot_{now/d}>
PUT _snapshot/my_repository/my_snapshot
{
"indices": "my-index,logs-my_app-default",
}
根据快照的大小不同,完成快照可能需要一些时间。默认情况下,create snapshot API 只会异步启动快照过程,该过程在后台运行。要更改为同步调用,可以将 wait_for_completion
查询参数设置为 true
。
PUT _snapshot/my_repository/my_snapshot?wait_for_completion=true
另外还可以使用 clone snapshot API 克隆现有的快照。要监控当前正在运行的快照,可以使用带有 _current
请求路径参数的 get snapshot API。
GET _snapshot/my_repository/_current
如果要获取参与当前运行快照的每个分片的完整详细信息,可以使用 get snapshot status API。
GET _snapshot/_status
成功创建快照之后,就可以在 S3 上看到备份的数据块文件,这个是正确的快照层级结构:
需要注意的是, "base_path": "
所以在 Open Search 中还原 Elasticsearch 就遇到了这个问题:
{
"error": {
"root_cause": [
{
"type": "snapshot_missing_exception",
"reason": "[easy_repository:2/-jOQ0oucQDGF3hJMNz-vKQ] is missing"
}
],
"type": "snapshot_missing_exception",
"reason": "[easy_repository:2/-jOQ0oucQDGF3hJMNz-vKQ] is missing",
"caused_by": {
"type": "no_such_file_exception",
"reason": "Blob object [11111/indices/7fv2zAi4Rt203JfsczUrBg/meta-YGnzxZABRBxW-2vqcmci.dat] not found: The specified key does not exist. (Service: S3, Status Code: 404, Request ID: R71DDHX4XXM0434T, Extended Request ID: d9M/HWvPvMFdPhB6KX+wYCW3ZFqeFo9EoscWPkulOXWa+TnovAE5PlemtuVzKXjlC+rrgskXAus=)"
}
},
"status": 404
}
恢复索引快照
POST _snapshot/my_repository/my_snapshot_2099.05.06/_restore
{
"indices": "my-index,logs-my_app-default",
}
各个集群的还原
-
Elasticsearch 7.10.2 的快照可以还原到 Easysearch 和 Amazon OpenSearch
- 从 Easysearch 1.8.2 还原到 Elasticsearch 7.10.2 报错如下:
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[s3_repository:1/a2qV4NYIReqvgW6BX_nxxw] cannot restore index [my_indexs] because it cannot be upgraded"
}
],
"type": "snapshot_restore_exception",
"reason": "[s3_repository:1/a2qV4NYIReqvgW6BX_nxxw] cannot restore index [my_indexs] because it cannot be upgraded",
"caused_by": {
"type": "illegal_state_exception",
"reason": "The index [[my_indexs/ALlTCIr0RJqtP06ouQmf0g]] was created with version [1.8.2] but the minimum compatible version is [6.0.0-beta1]. It should be re-indexed in Elasticsearch 6.x before upgrading to 7.10.2."
}
},
"status": 500
}
- 从 Amazon OpenSearch 2.1.3 还原到 Elasticsearch 7.10.2 报错如下(无论是否开启兼容模式):
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[aos:2/D-oyYSscSdCbZFcmPZa_yg] the snapshot was created with Elasticsearch version [36.34.78-beta2] which is higher than the version of this node [7.10.2]"
}
],
"type": "snapshot_restore_exception",
"reason": "[aos:2/D-oyYSscSdCbZFcmPZa_yg] the snapshot was created with Elasticsearch version [36.34.78-beta2] which is higher than the version of this node [7.10.2]"
},
"status": 500
}
- 从 Easysearch 1.8.2 还原到 Amazon OpenSearch2.13 报错如下(无论是否开启兼容模式):
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[easy_repository:2/LE18AWHlRJu9rpz9BJatUQ] cannot restore index [my_indexs] because it cannot be upgraded"
}
],
"type": "snapshot_restore_exception",
"reason": "[easy_repository:2/LE18AWHlRJu9rpz9BJatUQ] cannot restore index [my_indexs] because it cannot be upgraded",
"caused_by": {
"type": "illegal_state_exception",
"reason": "The index [[my_indexs/VHOo7yfDTRa48uhQvquFzQ]] was created with version [1.8.2] but the minimum compatible version is OpenSearch 1.0.0 (or Elasticsearch 7.0.0). It should be re-indexed in OpenSearch 1.x (or Elasticsearch 7.x) before upgrading to 2.13.0."
}
},
"status": 500
}
- Amazon OpenSearch 还原到 Easysearch 同样失败
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[aoss:2/D-oyYSscSdCbZFcmPZa_yg] cannot restore index [aos] because it cannot be upgraded"
}
],
"type": "snapshot_restore_exception",
"reason": "[aoss:2/D-oyYSscSdCbZFcmPZa_yg] cannot restore index [aos] because it cannot be upgraded",
"caused_by": {
"type": "illegal_state_exception",
"reason": "The index [[aos/864WjTAXQCaxJ829V5ktaw]] was created with version [36.34.78-beta2] but the minimum compatible version is [6.0.0]. It should be re-indexed in Easysearch 6.x before upgrading to 1.8.2."
}
},
"status": 500
}
- Elasticsearch 8.14.3 迁移到 Amazon OpenSearch 或者 Elasticsearch 都是有这个报错:
{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "Failed to parse object: unknown field [uuid] found",
"line": 1,
"col": 25
}
],
"type": "repository_exception",
"reason": "[snap] Unexpected exception when loading repository data",
"caused_by": {
"type": "parsing_exception",
"reason": "Failed to parse object: unknown field [uuid] found",
"line": 1,
"col": 25
}
},
"status": 500
}
这是由于 Elasticsearch 8 在创建快照的时候会默认加上一个 UUID 的字段,所以我们低版本的 Easysearch、Amazon OpenSearch 中会找不到这个字段,在执行GET _cat/snapshots/snap?v
的时候就报错,及时在注册存储库的时候显示加上 UUID 的字段也无事无补。
{
"snapshot-repo-name": {
"type": "s3",
"uuid": "qlJ0uqErRmW6aww2Fyt4Fg",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
}
},
以下是兼容性对比,每行第一列代表源集群,第一行代表目标集群:
快照兼容对比 | Easysearch 1.8.2 | Elasticsearch 7.10.2 | OpenSearch 2.13 |
---|---|---|---|
Easysearch 1.8.2 | 兼容 | 不兼容 | 不兼容 |
Elasticsearch 7.10.2 | 兼容 | 兼容 | 兼容 |
OpenSearch 2.13 | 不兼容 | 不兼容 | 兼容 |
Elasticsearch 的兼容列表官方的列表如下:
参考文献
-
开始使用 Elastic Stack 和 Docker Compose:第 1 部分
https://www.elastic.co/cn/blog/getting-started-with-the-elastic-stack-and-docker-compose -
Docker Compose 部署多节点 Elasticsearch
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docker.html#docker-compose-file -
repository-s3 教程
https://www.elastic.co/guide/en/elasticsearch/reference/8.14/repository-s3.html
https://www.elastic.co/guide/en/elasticsearch/plugins/7.10/repository-s3.html -
snapshot-restore
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/snapshot-restore.html -
在亚马逊 OpenSearch 服务中创建索引快照
https://docs.amazonaws.cn/zh_cn/opensearch-service/latest/developerguide/managedomains-snapshots.html#managedomains-snapshot-restore - 教程:迁移至 Amazon OpenSearch Service
https://docs.amazonaws.cn/zh_cn/opensearch-service/latest/developerguide/migration.html
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
在当今的数据驱动时代,搜索引擎的快照功能在数据保护和灾难恢复中至关重要。本文将对 Easysearch、Elasticsearch 和 Amazon OpenSearch 的快照兼容性进行比较,分析它们在快照创建、恢复、存储格式和跨平台兼容性等方面的特点,帮助大家更好地理解这些搜索引擎的差异,从而选择最适合自己需求的解决方案。
启动集群
Easysearch
服务器一般情况下默认参数都是很低的,而 Easysearch/Elasticsearch 是内存大户,所以就需要进行系统调优。
sysctl -w vm.max_map_count=262144
vm.max_map_count
是一个 Linux 内核参数,用于控制单个进程可以拥有的最大内存映射区域(VMA,Virtual Memory Areas)的数量。内存映射区域是指通过内存映射文件或匿名内存映射创建的虚拟内存区域。
这个参数在一些应用程序中非常重要,尤其是那些需要大量内存映射的应用程序,比如 Elasticsearch。Elasticsearch 使用内存映射文件来索引和搜索数据,这可能需要大量的内存映射区域。如果 vm.max_map_count
设置得太低,Elasticsearch 可能无法正常工作,并会出现错误信息。
调整 vm.max_map_count
参数的一些常见原因:
-
支持大型数据集: 应用程序(如 Elasticsearch)在处理大型数据集时可能需要大量内存映射区域。增加
vm.max_map_count
可以确保这些应用程序有足够的内存映射区域来处理数据。 -
防止内存错误: 如果
vm.max_map_count
设置得太低,当应用程序尝试创建超过限制的内存映射时,会出现错误,导致应用程序崩溃或无法正常工作。 - 优化性能:
适当地设置
vm.max_map_count
可以优化应用程序的性能,确保内存映射操作顺利进行。
检查当前的 vm.max_map_count
值:
sysctl vm.max_map_count
或者查看 /proc/sys/vm/max_map_count
文件:
cat /proc/sys/vm/max_map_count
Elasticsearch 官方建议将 vm.max_map_count
设置为至少 262144。对于其他应用程序。
Easysearch 具体安装步骤见 INFINI Easysearch 尝鲜 Hands on
Amazon OpenSearch
使用 Amazon Web Services 控制台进行创建。
Elasticsearch
使用如下 docker compose 部署一个三节点的 ES 集群:
version: "2.2"
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- elastic
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: es02
environment:
- node.name=es02
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data02:/usr/share/elasticsearch/data
networks:
- elastic
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:7.10.2
container_name: es03
environment:
- node.name=es03
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data03:/usr/share/elasticsearch/data
networks:
- elastic
volumes:
data01:
driver: local
data02:
driver: local
data03:
driver: local
networks:
elastic:
driver: bridge
由于这个 docker compose 没有关于 kibana 的配置,所以我们还是用 Console 添加原生的 Elasticsearch 集群!
集群信息
快照还原的步骤
快照前的准备
插件安装
本次测试选择把索引快照备份到 Amazon S3,所以需要使用 S3 repository plugin,这个插件添加了对使用 Amazon S3 作为快照/恢复存储库的支持。
Easysearch 和 OpenSearch 集群自带了这个插件,所以无需额外安装。
对于自己部署的三节点 Elasticsearch 则需要进入每一个节点运行安装命令然后再重启集群,建议使用自动化运维工具来做这步,安装命令如下:
sudo bin/elasticsearch-plugin install repository-s3
如果不再需要这个插件,可以这样删除。
sudo bin/elasticsearch-plugin remove repository-s3
由于需要和 Amazon Web Services 打交道,所以我们需要设置 IAM 凭证,这个插件可以从 EC2 IAM instance profile,ECS task role 以及 EKS 的 Service account 读取相应的凭证。
对于托管的 Amazon OpenSearch 来说,我们无法在托管的 EC2 上绑定我们的凭证,所以需要新建一个 OpenSearchSnapshotRole,然后通过当前的用户把这个角色传递给服务,也就是我们说的 IAM:PassRole。
创建 OpenSearchSnapshotRole,策略如下:
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-name"
]
},
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::bucket-name/*"
]
}
]
}
信任关系如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "es.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
然后在我们的 IAM user 上加上 PassRole 的权限,这样我们就可以把 OpenSearchSnapshotRole 传递给 OpenSearch 集群。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
}
]
}
注册存储库
在源集群执行注册
PUT /_snapshot/snapshot-repo-name
{
"type": "s3",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
在目标集群同样执行这个语句,为了防止覆盖源集群存储库的数据,将 "readonly": true 添加到"settings" PUT 请求中,这样就只有一个集群具有对存储库的写入权限。
PUT /_snapshot/snapshot-repo-name
{
"type": "s3",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
"readonly": true,
对于 OpenSearch 来说,还需要执行 passrole,所以还需要添加role_arn这个字段,由于 IAM:PassRole 需要对 HTTP 请求做 signV4 日签名,所以这部常常使用 Postman 来完成。把角色传递过去之后,接下来的快照还原操作就可以在 OpenSearch Dashboard 中进行操作了。
需要注意的是,需要在 auth 这里输入 AccessKey,SecretKey,AWS Region,Service Name(es)来做 SignV4 的签名。
请求体如下:
{
"type": "s3",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
"readonly": true,
"role_arn": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
}
}
- 查看所有注册的存储库:
GET _snapshot
:这个命令返回所有已注册的快照存储库列表及其基本信息。
GET _snapshot
{
"es_repository": {
"type": "s3",
"settings": {
"bucket": "your-s3-bucket-name",
"region": "your-s3-bucket-region"
}
}
}
- 查看特定存储库的详细信息:
GET _snapshot/es_repository
:这个命令返回名为es_repository
的存储库的详细配置信息,包括存储桶名称、区域和其他设置。
GET _snapshot/es_repository
{
"es_repository": {
"type": "s3",
"settings": {
"bucket": "your-s3-bucket-name",
"region": "your-s3-bucket-region",
"access_key": "your-access-key",
"secret_key": "your-secret-key"
}
}
}
- 查看特定存储库中的快照:
GET _cat/snapshots/es_repository?v
:这个命令返回es_repository
存储库中的所有快照及其详细信息,包括快照 ID、状态、开始时间、结束时间、持续时间、包含的索引数量、成功和失败的分片数量等。
GET _cat/snapshots/es_repository?v
id status start_epoch start_time end_epoch end_time duration indices successful_shards failed_shards total_shards
snapshot_1 SUCCESS 1628884800 08:00:00 1628888400 09:00:00 1h 3 10 0 10
snapshot_2 SUCCESS 1628971200 08:00:00 1628974800 09:00:00 1h 3 10 0 10
创建索引快照
# PUT _snapshot/my_repository/<my_snapshot_{now/d}>
PUT _snapshot/my_repository/my_snapshot
{
"indices": "my-index,logs-my_app-default",
}
根据快照的大小不同,完成快照可能需要一些时间。默认情况下,create snapshot API 只会异步启动快照过程,该过程在后台运行。要更改为同步调用,可以将 wait_for_completion
查询参数设置为 true
。
PUT _snapshot/my_repository/my_snapshot?wait_for_completion=true
另外还可以使用 clone snapshot API 克隆现有的快照。要监控当前正在运行的快照,可以使用带有 _current
请求路径参数的 get snapshot API。
GET _snapshot/my_repository/_current
如果要获取参与当前运行快照的每个分片的完整详细信息,可以使用 get snapshot status API。
GET _snapshot/_status
成功创建快照之后,就可以在 S3 上看到备份的数据块文件,这个是正确的快照层级结构:
需要注意的是, "base_path": "
所以在 Open Search 中还原 Elasticsearch 就遇到了这个问题:
{
"error": {
"root_cause": [
{
"type": "snapshot_missing_exception",
"reason": "[easy_repository:2/-jOQ0oucQDGF3hJMNz-vKQ] is missing"
}
],
"type": "snapshot_missing_exception",
"reason": "[easy_repository:2/-jOQ0oucQDGF3hJMNz-vKQ] is missing",
"caused_by": {
"type": "no_such_file_exception",
"reason": "Blob object [11111/indices/7fv2zAi4Rt203JfsczUrBg/meta-YGnzxZABRBxW-2vqcmci.dat] not found: The specified key does not exist. (Service: S3, Status Code: 404, Request ID: R71DDHX4XXM0434T, Extended Request ID: d9M/HWvPvMFdPhB6KX+wYCW3ZFqeFo9EoscWPkulOXWa+TnovAE5PlemtuVzKXjlC+rrgskXAus=)"
}
},
"status": 404
}
恢复索引快照
POST _snapshot/my_repository/my_snapshot_2099.05.06/_restore
{
"indices": "my-index,logs-my_app-default",
}
各个集群的还原
-
Elasticsearch 7.10.2 的快照可以还原到 Easysearch 和 Amazon OpenSearch
- 从 Easysearch 1.8.2 还原到 Elasticsearch 7.10.2 报错如下:
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[s3_repository:1/a2qV4NYIReqvgW6BX_nxxw] cannot restore index [my_indexs] because it cannot be upgraded"
}
],
"type": "snapshot_restore_exception",
"reason": "[s3_repository:1/a2qV4NYIReqvgW6BX_nxxw] cannot restore index [my_indexs] because it cannot be upgraded",
"caused_by": {
"type": "illegal_state_exception",
"reason": "The index [[my_indexs/ALlTCIr0RJqtP06ouQmf0g]] was created with version [1.8.2] but the minimum compatible version is [6.0.0-beta1]. It should be re-indexed in Elasticsearch 6.x before upgrading to 7.10.2."
}
},
"status": 500
}
- 从 Amazon OpenSearch 2.1.3 还原到 Elasticsearch 7.10.2 报错如下(无论是否开启兼容模式):
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[aos:2/D-oyYSscSdCbZFcmPZa_yg] the snapshot was created with Elasticsearch version [36.34.78-beta2] which is higher than the version of this node [7.10.2]"
}
],
"type": "snapshot_restore_exception",
"reason": "[aos:2/D-oyYSscSdCbZFcmPZa_yg] the snapshot was created with Elasticsearch version [36.34.78-beta2] which is higher than the version of this node [7.10.2]"
},
"status": 500
}
- 从 Easysearch 1.8.2 还原到 Amazon OpenSearch2.13 报错如下(无论是否开启兼容模式):
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[easy_repository:2/LE18AWHlRJu9rpz9BJatUQ] cannot restore index [my_indexs] because it cannot be upgraded"
}
],
"type": "snapshot_restore_exception",
"reason": "[easy_repository:2/LE18AWHlRJu9rpz9BJatUQ] cannot restore index [my_indexs] because it cannot be upgraded",
"caused_by": {
"type": "illegal_state_exception",
"reason": "The index [[my_indexs/VHOo7yfDTRa48uhQvquFzQ]] was created with version [1.8.2] but the minimum compatible version is OpenSearch 1.0.0 (or Elasticsearch 7.0.0). It should be re-indexed in OpenSearch 1.x (or Elasticsearch 7.x) before upgrading to 2.13.0."
}
},
"status": 500
}
- Amazon OpenSearch 还原到 Easysearch 同样失败
{
"error": {
"root_cause": [
{
"type": "snapshot_restore_exception",
"reason": "[aoss:2/D-oyYSscSdCbZFcmPZa_yg] cannot restore index [aos] because it cannot be upgraded"
}
],
"type": "snapshot_restore_exception",
"reason": "[aoss:2/D-oyYSscSdCbZFcmPZa_yg] cannot restore index [aos] because it cannot be upgraded",
"caused_by": {
"type": "illegal_state_exception",
"reason": "The index [[aos/864WjTAXQCaxJ829V5ktaw]] was created with version [36.34.78-beta2] but the minimum compatible version is [6.0.0]. It should be re-indexed in Easysearch 6.x before upgrading to 1.8.2."
}
},
"status": 500
}
- Elasticsearch 8.14.3 迁移到 Amazon OpenSearch 或者 Elasticsearch 都是有这个报错:
{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "Failed to parse object: unknown field [uuid] found",
"line": 1,
"col": 25
}
],
"type": "repository_exception",
"reason": "[snap] Unexpected exception when loading repository data",
"caused_by": {
"type": "parsing_exception",
"reason": "Failed to parse object: unknown field [uuid] found",
"line": 1,
"col": 25
}
},
"status": 500
}
这是由于 Elasticsearch 8 在创建快照的时候会默认加上一个 UUID 的字段,所以我们低版本的 Easysearch、Amazon OpenSearch 中会找不到这个字段,在执行GET _cat/snapshots/snap?v
的时候就报错,及时在注册存储库的时候显示加上 UUID 的字段也无事无补。
{
"snapshot-repo-name": {
"type": "s3",
"uuid": "qlJ0uqErRmW6aww2Fyt4Fg",
"settings": {
"bucket": "<bucket-name>",
"base_path": "<bucket-prefix>",
}
},
以下是兼容性对比,每行第一列代表源集群,第一行代表目标集群:
快照兼容对比 | Easysearch 1.8.2 | Elasticsearch 7.10.2 | OpenSearch 2.13 |
---|---|---|---|
Easysearch 1.8.2 | 兼容 | 不兼容 | 不兼容 |
Elasticsearch 7.10.2 | 兼容 | 兼容 | 兼容 |
OpenSearch 2.13 | 不兼容 | 不兼容 | 兼容 |
Elasticsearch 的兼容列表官方的列表如下:
参考文献
-
开始使用 Elastic Stack 和 Docker Compose:第 1 部分
https://www.elastic.co/cn/blog/getting-started-with-the-elastic-stack-and-docker-compose -
Docker Compose 部署多节点 Elasticsearch
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docker.html#docker-compose-file -
repository-s3 教程
https://www.elastic.co/guide/en/elasticsearch/reference/8.14/repository-s3.html
https://www.elastic.co/guide/en/elasticsearch/plugins/7.10/repository-s3.html -
snapshot-restore
https://www.elastic.co/guide/en/elasticsearch/reference/7.10/snapshot-restore.html -
在亚马逊 OpenSearch 服务中创建索引快照
https://docs.amazonaws.cn/zh_cn/opensearch-service/latest/developerguide/managedomains-snapshots.html#managedomains-snapshot-restore - 教程:迁移至 Amazon OpenSearch Service
https://docs.amazonaws.cn/zh_cn/opensearch-service/latest/developerguide/migration.html
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
使用 Easysearch 打造企业内部知识问答系统
大家可能都有这样的经历,刚入职一家企业时,同事往往会给你分享一些文档资料,有可能是产品信息、规章制度等等。这些文档有的过于冗长,很难第一时间找到想要的内容。有的已经有了新版本,但员工使用的还是老版本。
基于这种背景,我们可以利用 Easysearch 加 LLM 实现一个内部知识的 QA 问答系统。这个系统将利用 LangChain 框架调用本地部署的大模型和 Easysearch,实现理解员工的提问,并基于最新的文档,给出精准答案。
开发框架
整个框架分为四个部分:
- 数据源:数据可以有很多种,可以是非结构化的,比如 PDF、docx、txt 等。也可以是结构化的数据,甚至代码也行。在本次示例中,我们使用 PDF 的非结构化数据。
- 大模型应用:应用与大模型交互,生成我们需要的答案。
- 大模型:系统执行相关任务需要用到的大模型,可以有多个。
- Q&A 场景:基于大模型为引擎的 QA 场景,使用 web 框架,构建一个交互界面。
数据准备
本次我们使用的资料是 "INFINI 产品安装手册.pdf" ,文档部分内容展示如下:
首先我们使用 LangChain 的 document_loaders 来加载文件。document_loaders 集成了数百种数据源格式,可以很方便的加载数据。我们的数据的 pdf 格式的,导入 PyPDFLoader 类来进行处理。代码如下:
import os
# 导入 Document Loaders
from langchain_community.document_loaders import PyPDFLoader
# Load Pdf
base_dir = '.\\easysearch' # 文档的存放目录
docs = []
for file in os.listdir(base_dir):
file_path = os.path.join(base_dir, file)
if file.endswith('.pdf'):
loader = PyPDFLoader(file_path)
documents.extend(loader.load())
上面的代码将 pdf 文件的内容存储在 docs 这个列表中,以便后续进行处理。
文本分割
一个文件的文本内容可能很大,无法适应许多模型的上下文窗口,也不利于检索和存储。因此,通常我们会将文本内容分割成更小的块,这将帮助我们在运行时只检索文档中最相关的部分。LangChain 提供了工具来进行处理文本分割,非常方便。 我们将把文档分割成 1000 个字符的块,每个块之间有 200 个重叠字符。这种重叠有助于减少将语句与相关的重要上下文分离的可能性。
# 2.将Documents切分成块
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20)
chunked_documents = text_splitter.split_documents(docs)
上面的代码将 docs 的内容按 1000 字符大小进行切分,存储在 chunked_documents 中,以便后续进行处理。
注意,实际运行中,切分及重叠的大小,都会影响应用效果,需自行调试。
向量库 Easysearch
接下来,我们将这些文本块转换成向量的形式,并存储在一个向量数据库中。在本示例中,我们使用 mxbai-embed-large 模型来生成向量,然后将向量和原始内容存入 easysearch 。
本地部署模型,我使用的是 ollama ,大家可以使用自己喜欢的工具。
# 3. 定义embedding模型
from langchain_community.embeddings import OllamaEmbeddings
ollama_emb = OllamaEmbeddings(
model="mxbai-embed-large",
)
# 4. 定义 easysearch 集群的信息,以及存放向量的索引名称 infini
from langchain_community.vectorstores import EcloudESVectorStore
ES_URL = "https://192.168.56.3:9200"
USER = "admin"
PASSWORD = "e5ac1b537785ae27c187"
indexname = "infini"
docsearch = EcloudESVectorStore.from_documents(
chunked_documents,
ollama_emb,
es_url=ES_URL,
user=USER,
password=PASSWORD,
index_name=indexname,
verify_certs=False,
)
通过上面的步骤,我们成功将文本块转换成了向量,并存入到了 easysearch 集群的 infini 索引中。 我们看看 infini 索引内容是怎样的 text 字段存放了文本块的原始内容,vector 字段存放着对应的向量表示。
检索及生成答案
在这一步,我们会定义一个生成式大模型。然后创建一个 RetrievalQA 链,它是一个检索式问答模型,用于生成问题的答案。
在 RetrievalQA 链中有下面两大重要组成部分。
- LLM 是大模型,负责回答问题。
- retriever(vectorstore.as_retriever())负责根据用户的问题检索相关的信息。先是找最近似的“向量块”,再把”向量块“对应的“文档块”作为知识信息,和问题一起传递进入大模型。之所以要先检索,是因为从互联网信息训练而来的大模型不可能拥有一个私营企业的内部知识。
# 5. Retrieval 准备模型和Retrieval链
import logging
# MultiQueryRetriever工具
from langchain.retrievers.multi_query import MultiQueryRetriever
# RetrievalQA链
from langchain.chains import RetrievalQA
# # 设置Logging
logging.basicConfig()
logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)
# # 实例化一个大模型工具
from langchain_community.chat_models import ChatOllama
llm = ChatOllama(model="qwen2:latest")
from langchain.prompts import PromptTemplate
my_template = PromptTemplate(
input_variables=["question"],
template="""You are an AI language model assistant. Your task is
to generate 3 different versions of the given user
question in Chinese to retrieve relevant documents from a vector database.
By generating multiple perspectives on the user question,
your goal is to help the user overcome some of the limitations
of distance-based similarity search. Provide these alternative
questions separated by newlines. Original question: {question}""",
)
# # 实例化一个MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=docsearch.as_retriever(), llm=llm,prompt=my_template,include_original=True)
# # 实例化一个RetrievalQA链
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm)
这里我们使用 ollama 在本地部署一个 qwen2 大模型,负责问题改写和生成答案。
启动 qwen2 大模型:ollama run qwen2
我们获取到用户问题后,先通过 MultiQueryRetriever 类调用大模型 qwen2 进行改写,生成 3 个同样语义的问题,然后再调用 easyearch 进行向量检索,搜索相关内容。
最后把所有相关内容,合并、去重后,与原始问题一起提交给大模型 qwen2,进行答案生成。
虽然这里使用的是向量检索,但实际上我们可以同时使用全文检索和向量检索。这也是使用 easysearch 作为检索库的优势之一。
前端展示
这一步我们创建一个 Flask 应用(需要安装 Flask 包)来接收用户的问题,并生成相应的答案,最后通过 index.html 对答案进行渲染和呈现。
在这个步骤中,我们使用了之前创建的 RetrievalQA 链来获取相关的文档和生成答案。然后,将这些信息返回给用户,显示在网页上。
# 6. Q&A系统的UI实现
from flask import Flask, request, render_template
app = Flask(__name__) # Flask APP
@app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST':
# 接收用户输入作为问题
question = request.form.get('question')
# RetrievalQA链 - 读入问题,生成答案
result = qa_chain({"query": question})
# 把大模型的回答结果返回网页进行渲染
return render_template('index.html', result=result)
return render_template('index.html')
if __name__ == "__main__":
app.run(host='0.0.0.0',debug=True,port=5000)
效果演示
我们模仿用户进行提问。 Q&A 系统进行回答,回答速度取决于本地的计算资源。 内容校验,在原始文档内用 ctrl+F 搜索关键字 LOGGING_ES_ENDPOINT 得到如下内容。 嗯,回答的还不错,达到预期目的。如果还有其他要求,可修改 my_template 中的提示词或者替换成别的大模型也是可以的。
小结
通过这次示例,我们演示了如何基于 LangChain 和 easysearch 以及大模型,快速开发出一个内部知识问答系统。怎么样,是不是觉得整个流程特别简单易懂?
如有任何问题,请随时联系我,期待与您交流!
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
大家可能都有这样的经历,刚入职一家企业时,同事往往会给你分享一些文档资料,有可能是产品信息、规章制度等等。这些文档有的过于冗长,很难第一时间找到想要的内容。有的已经有了新版本,但员工使用的还是老版本。
基于这种背景,我们可以利用 Easysearch 加 LLM 实现一个内部知识的 QA 问答系统。这个系统将利用 LangChain 框架调用本地部署的大模型和 Easysearch,实现理解员工的提问,并基于最新的文档,给出精准答案。
开发框架
整个框架分为四个部分:
- 数据源:数据可以有很多种,可以是非结构化的,比如 PDF、docx、txt 等。也可以是结构化的数据,甚至代码也行。在本次示例中,我们使用 PDF 的非结构化数据。
- 大模型应用:应用与大模型交互,生成我们需要的答案。
- 大模型:系统执行相关任务需要用到的大模型,可以有多个。
- Q&A 场景:基于大模型为引擎的 QA 场景,使用 web 框架,构建一个交互界面。
数据准备
本次我们使用的资料是 "INFINI 产品安装手册.pdf" ,文档部分内容展示如下:
首先我们使用 LangChain 的 document_loaders 来加载文件。document_loaders 集成了数百种数据源格式,可以很方便的加载数据。我们的数据的 pdf 格式的,导入 PyPDFLoader 类来进行处理。代码如下:
import os
# 导入 Document Loaders
from langchain_community.document_loaders import PyPDFLoader
# Load Pdf
base_dir = '.\\easysearch' # 文档的存放目录
docs = []
for file in os.listdir(base_dir):
file_path = os.path.join(base_dir, file)
if file.endswith('.pdf'):
loader = PyPDFLoader(file_path)
documents.extend(loader.load())
上面的代码将 pdf 文件的内容存储在 docs 这个列表中,以便后续进行处理。
文本分割
一个文件的文本内容可能很大,无法适应许多模型的上下文窗口,也不利于检索和存储。因此,通常我们会将文本内容分割成更小的块,这将帮助我们在运行时只检索文档中最相关的部分。LangChain 提供了工具来进行处理文本分割,非常方便。 我们将把文档分割成 1000 个字符的块,每个块之间有 200 个重叠字符。这种重叠有助于减少将语句与相关的重要上下文分离的可能性。
# 2.将Documents切分成块
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20)
chunked_documents = text_splitter.split_documents(docs)
上面的代码将 docs 的内容按 1000 字符大小进行切分,存储在 chunked_documents 中,以便后续进行处理。
注意,实际运行中,切分及重叠的大小,都会影响应用效果,需自行调试。
向量库 Easysearch
接下来,我们将这些文本块转换成向量的形式,并存储在一个向量数据库中。在本示例中,我们使用 mxbai-embed-large 模型来生成向量,然后将向量和原始内容存入 easysearch 。
本地部署模型,我使用的是 ollama ,大家可以使用自己喜欢的工具。
# 3. 定义embedding模型
from langchain_community.embeddings import OllamaEmbeddings
ollama_emb = OllamaEmbeddings(
model="mxbai-embed-large",
)
# 4. 定义 easysearch 集群的信息,以及存放向量的索引名称 infini
from langchain_community.vectorstores import EcloudESVectorStore
ES_URL = "https://192.168.56.3:9200"
USER = "admin"
PASSWORD = "e5ac1b537785ae27c187"
indexname = "infini"
docsearch = EcloudESVectorStore.from_documents(
chunked_documents,
ollama_emb,
es_url=ES_URL,
user=USER,
password=PASSWORD,
index_name=indexname,
verify_certs=False,
)
通过上面的步骤,我们成功将文本块转换成了向量,并存入到了 easysearch 集群的 infini 索引中。 我们看看 infini 索引内容是怎样的 text 字段存放了文本块的原始内容,vector 字段存放着对应的向量表示。
检索及生成答案
在这一步,我们会定义一个生成式大模型。然后创建一个 RetrievalQA 链,它是一个检索式问答模型,用于生成问题的答案。
在 RetrievalQA 链中有下面两大重要组成部分。
- LLM 是大模型,负责回答问题。
- retriever(vectorstore.as_retriever())负责根据用户的问题检索相关的信息。先是找最近似的“向量块”,再把”向量块“对应的“文档块”作为知识信息,和问题一起传递进入大模型。之所以要先检索,是因为从互联网信息训练而来的大模型不可能拥有一个私营企业的内部知识。
# 5. Retrieval 准备模型和Retrieval链
import logging
# MultiQueryRetriever工具
from langchain.retrievers.multi_query import MultiQueryRetriever
# RetrievalQA链
from langchain.chains import RetrievalQA
# # 设置Logging
logging.basicConfig()
logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)
# # 实例化一个大模型工具
from langchain_community.chat_models import ChatOllama
llm = ChatOllama(model="qwen2:latest")
from langchain.prompts import PromptTemplate
my_template = PromptTemplate(
input_variables=["question"],
template="""You are an AI language model assistant. Your task is
to generate 3 different versions of the given user
question in Chinese to retrieve relevant documents from a vector database.
By generating multiple perspectives on the user question,
your goal is to help the user overcome some of the limitations
of distance-based similarity search. Provide these alternative
questions separated by newlines. Original question: {question}""",
)
# # 实例化一个MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=docsearch.as_retriever(), llm=llm,prompt=my_template,include_original=True)
# # 实例化一个RetrievalQA链
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm)
这里我们使用 ollama 在本地部署一个 qwen2 大模型,负责问题改写和生成答案。
启动 qwen2 大模型:ollama run qwen2
我们获取到用户问题后,先通过 MultiQueryRetriever 类调用大模型 qwen2 进行改写,生成 3 个同样语义的问题,然后再调用 easyearch 进行向量检索,搜索相关内容。
最后把所有相关内容,合并、去重后,与原始问题一起提交给大模型 qwen2,进行答案生成。
虽然这里使用的是向量检索,但实际上我们可以同时使用全文检索和向量检索。这也是使用 easysearch 作为检索库的优势之一。
前端展示
这一步我们创建一个 Flask 应用(需要安装 Flask 包)来接收用户的问题,并生成相应的答案,最后通过 index.html 对答案进行渲染和呈现。
在这个步骤中,我们使用了之前创建的 RetrievalQA 链来获取相关的文档和生成答案。然后,将这些信息返回给用户,显示在网页上。
# 6. Q&A系统的UI实现
from flask import Flask, request, render_template
app = Flask(__name__) # Flask APP
@app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST':
# 接收用户输入作为问题
question = request.form.get('question')
# RetrievalQA链 - 读入问题,生成答案
result = qa_chain({"query": question})
# 把大模型的回答结果返回网页进行渲染
return render_template('index.html', result=result)
return render_template('index.html')
if __name__ == "__main__":
app.run(host='0.0.0.0',debug=True,port=5000)
效果演示
我们模仿用户进行提问。 Q&A 系统进行回答,回答速度取决于本地的计算资源。 内容校验,在原始文档内用 ctrl+F 搜索关键字 LOGGING_ES_ENDPOINT 得到如下内容。 嗯,回答的还不错,达到预期目的。如果还有其他要求,可修改 my_template 中的提示词或者替换成别的大模型也是可以的。
小结
通过这次示例,我们演示了如何基于 LangChain 和 easysearch 以及大模型,快速开发出一个内部知识问答系统。怎么样,是不是觉得整个流程特别简单易懂?
如有任何问题,请随时联系我,期待与您交流!
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »