
【搜索客社区日报】第1872期 (2024-08-01)
https://www.microsoft.com/en-u ... data/
2.Perplexity 牛逼!50 人团队年入 1.5 亿,这家 AI 独角兽如何在2年内撼动谷歌地位?
https://mp.weixin.qq.com/s/R-JczQeEsDJzV4YnpFCAPA
3.使用 OpenTelemetry 实现基于 LLM 的应用的可观测性介绍
https://mp.weixin.qq.com/s/Y0T4KUyJ3Fl0q5Zbz-bzOA
编辑:Se7en
更多资讯:http://news.searchkit.cn
https://www.microsoft.com/en-u ... data/
2.Perplexity 牛逼!50 人团队年入 1.5 亿,这家 AI 独角兽如何在2年内撼动谷歌地位?
https://mp.weixin.qq.com/s/R-JczQeEsDJzV4YnpFCAPA
3.使用 OpenTelemetry 实现基于 LLM 的应用的可观测性介绍
https://mp.weixin.qq.com/s/Y0T4KUyJ3Fl0q5Zbz-bzOA
编辑:Se7en
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】 第1871期 (2024-07-31)
https://ai.plainenglish.io/inv ... d8ca1
2.2800 份 AI 文档的检索增强生成 — 现场演示(搭梯)
https://medium.com/%40lamslide ... ff732
3.IK分词器原理
https://juejin.cn/post/6845166891120476168
编辑:kin122
更多资讯:http://news.searchkit.cn
https://ai.plainenglish.io/inv ... d8ca1
2.2800 份 AI 文档的检索增强生成 — 现场演示(搭梯)
https://medium.com/%40lamslide ... ff732
3.IK分词器原理
https://juejin.cn/post/6845166891120476168
编辑:kin122
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】第1870期 (2024-07-30)
https://medium.com/%40zagfox/e ... 721a5
2. ES 里的相似性计算知多少
https://medium.com/%40shekhar. ... bf59c
3. Agent让大模型从“解释问题”到“解决问题”
https://zhuanlan.zhihu.com/p/7 ... r%3D0
编辑:斯蒂文
更多资讯:http://news.searchkit.cn
https://medium.com/%40zagfox/e ... 721a5
2. ES 里的相似性计算知多少
https://medium.com/%40shekhar. ... bf59c
3. Agent让大模型从“解释问题”到“解决问题”
https://zhuanlan.zhihu.com/p/7 ... r%3D0
编辑:斯蒂文
更多资讯:http://news.searchkit.cn
收起阅读 »

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 征文活动
收起阅读 »
【搜索客社区日报】第1869期 (2024-07-29)
https://infinilabs.cn/blog/202 ... arch/
2. Timeplus Proton现已原生支持面向ClickHouse的流式处理和ETL
https://mp.weixin.qq.com/s/wygAiRSSaXH06MOP6TZ_BA
3. 有关世界最新的新闻和建议
https://www.zdnet.com/
4. 理解近似最近邻 (ANN) 算法
https://www.elastic.co/cn/blog/understanding-ann
5. 什么是量子技术?它为何重要?
https://blog.emb.global/impact ... logy/
编辑:Muse
更多资讯:http://news.searchkit.cn
https://infinilabs.cn/blog/202 ... arch/
2. Timeplus Proton现已原生支持面向ClickHouse的流式处理和ETL
https://mp.weixin.qq.com/s/wygAiRSSaXH06MOP6TZ_BA
3. 有关世界最新的新闻和建议
https://www.zdnet.com/
4. 理解近似最近邻 (ANN) 算法
https://www.elastic.co/cn/blog/understanding-ann
5. 什么是量子技术?它为何重要?
https://blog.emb.global/impact ... logy/
编辑:Muse
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】第1868期 (2024-07-26)
https://mp.weixin.qq.com/s/dSUEbsZ3gOmLEkQk--RJZw
2、最近硅谷人人都在讨论的GraphRAG到底是什么
https://mp.weixin.qq.com/s/Hx_nZItbwBL0XxckGnyXLg
3、减少 95% 资源的向量搜索 | 使用云搜索的 DiskANN
https://mp.weixin.qq.com/s/ddAv8X4qHKgfgpBkavLCPA
4、OpenSearch 向量检索和大模型方案深度解读
https://blog.51cto.com/u_15316473/8598095
🎉 活动预告:
【7月31日】第1期 | 2024 搜索客社区 Meetup 线上直播活动,主题:《Easysearch 结合大模型实现 RAG》
https://searchkit.cn/article/15209
编辑:Fred
更多资讯:http://news.searchkit.cn
https://mp.weixin.qq.com/s/dSUEbsZ3gOmLEkQk--RJZw
2、最近硅谷人人都在讨论的GraphRAG到底是什么
https://mp.weixin.qq.com/s/Hx_nZItbwBL0XxckGnyXLg
3、减少 95% 资源的向量搜索 | 使用云搜索的 DiskANN
https://mp.weixin.qq.com/s/ddAv8X4qHKgfgpBkavLCPA
4、OpenSearch 向量检索和大模型方案深度解读
https://blog.51cto.com/u_15316473/8598095
🎉 活动预告:
【7月31日】第1期 | 2024 搜索客社区 Meetup 线上直播活动,主题:《Easysearch 结合大模型实现 RAG》
https://searchkit.cn/article/15209
编辑:Fred
更多资讯:http://news.searchkit.cn 收起阅读 »

【第1期】2024 搜索客 Meetup | Easysearch 结合大模型实现 RAG
2024 搜索客社区 Meetup 首期线上活动正式启动,本次活动由 搜索客社区、极限科技(INFINI Labs)联合举办,诚邀广大搜索技术开发者和爱好者参加交流学习。
活动时间:2024 年 7 月 31 日 19:00-20:00 (周三)
活动形式:微信视频号(极限实验室)直播
报名方式:关注或扫码海报中的二维码进行预约
活动简介
在这个人工智能飞速发展的时代,ChatGPT 和 GPT-4 的出现无疑为人类带来了前所未有的震撼。我们不禁思考:通用人工智能的奇点是否真的即将来临?而最前沿的 AI 技术与最实用的落地应用之间的距离,又该如何缩短?
为了深入探讨这些问题,我们特别邀请到了极限科技(INFINI Labs)高级解决方案架构师、《老杨玩搜索》栏目 B 站 UP 主——杨帆先生,为我们带来一场主题为 “Easysearch 结合大模型实现 RAG” 的精彩演讲。
嘉宾介绍
杨帆,拥有十余年金融行业服务工作经验,熟悉 Linux、数据库、网络等领域。目前主要从事 Easysearch、Elasticsearch 等搜索引擎的技术支持工作,服务国内私有化部署的客户。他的丰富经验和深刻见解,将为我们揭开 AI 技术与实际应用之间的神秘面纱。
演讲主题
《Easysearch 结合大模型实现 RAG》
主题摘要
在本次演讲中,杨帆将跟大家分享和探讨以下几个方面:
- LangChain 简介:LangChain 的作用是什么?它由哪些组件构成,优势是什么。
- RAG 的背景及其局限性:RAG 出现以前的我们是如何获取信息的,RAG 解决了什么问题?它就是最终的答案了吗?
- LangChain 下的 RAG 工作流:在 LangChain 的框架下,实现 RAG 的步骤是怎样的。
- RAG Demo:使用 ollama 部署本地模型,利用 LangChain 集成 Easysearch 和 LLM , 开发 QA 问答系统
活动亮点
- 前沿技术分享: 深入了解当前 AI 领域的最新动态和发展趋势。
- 实战经验交流: 学习如何在实际工作中应用这些先进技术。
- 互动问答环节: 与演讲嘉宾直接对话,解答你的疑惑。
参与有奖
本次直播活动中设置了随机抽奖环节,奖品为 INFINI Labs 周边纪念品,包括 T 恤、鸭舌帽、咖啡杯、指甲刀套件等等(图片仅供参考,款式、颜色与尺码随机)。
活动交流
活动交流群二维码 7 天内(8 月 1 日前)有效,如过期请添加小助手微信拉群。活动最新消息也会在群内及时同步,欢迎大家参与,记得先预约,精彩内容不错过!
讲师招募
搜索客社区 Meetup 讲师持续招募中...
这是一个由搜索客社区精心组织策划的线下线上技术交流活动,我们诚挚邀请各位技术大咖、行业精英踊跃提交演讲议题。Meetup 活动将聚焦 AI 与搜索领域的最新动态,以及数据实时搜索分析、向量检索、技术实践与案例分析、日志分析、安全等领域的深度探讨。详情参见:http://cfp.searchkit.cn 。我们热切期待您的精彩分享!
关于 搜索客(SearchKit)社区
搜索客社区由 Elasticsearch 中文社区进行全新的品牌升级,以新的 Slogan:“搜索人自己的社区” 为宣言。汇集搜索领域最新动态、精选干货文章、精华讨论、文档资料、翻译与版本发布等,为广大搜索领域从业者提供更为丰富便捷的学习和交流平台。社区官网:https://searchkit.cn 。
Easysearch 有奖征文活动推荐
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
2024 搜索客社区 Meetup 首期线上活动正式启动,本次活动由 搜索客社区、极限科技(INFINI Labs)联合举办,诚邀广大搜索技术开发者和爱好者参加交流学习。
活动时间:2024 年 7 月 31 日 19:00-20:00 (周三)
活动形式:微信视频号(极限实验室)直播
报名方式:关注或扫码海报中的二维码进行预约
活动简介
在这个人工智能飞速发展的时代,ChatGPT 和 GPT-4 的出现无疑为人类带来了前所未有的震撼。我们不禁思考:通用人工智能的奇点是否真的即将来临?而最前沿的 AI 技术与最实用的落地应用之间的距离,又该如何缩短?
为了深入探讨这些问题,我们特别邀请到了极限科技(INFINI Labs)高级解决方案架构师、《老杨玩搜索》栏目 B 站 UP 主——杨帆先生,为我们带来一场主题为 “Easysearch 结合大模型实现 RAG” 的精彩演讲。
嘉宾介绍
杨帆,拥有十余年金融行业服务工作经验,熟悉 Linux、数据库、网络等领域。目前主要从事 Easysearch、Elasticsearch 等搜索引擎的技术支持工作,服务国内私有化部署的客户。他的丰富经验和深刻见解,将为我们揭开 AI 技术与实际应用之间的神秘面纱。
演讲主题
《Easysearch 结合大模型实现 RAG》
主题摘要
在本次演讲中,杨帆将跟大家分享和探讨以下几个方面:
- LangChain 简介:LangChain 的作用是什么?它由哪些组件构成,优势是什么。
- RAG 的背景及其局限性:RAG 出现以前的我们是如何获取信息的,RAG 解决了什么问题?它就是最终的答案了吗?
- LangChain 下的 RAG 工作流:在 LangChain 的框架下,实现 RAG 的步骤是怎样的。
- RAG Demo:使用 ollama 部署本地模型,利用 LangChain 集成 Easysearch 和 LLM , 开发 QA 问答系统
活动亮点
- 前沿技术分享: 深入了解当前 AI 领域的最新动态和发展趋势。
- 实战经验交流: 学习如何在实际工作中应用这些先进技术。
- 互动问答环节: 与演讲嘉宾直接对话,解答你的疑惑。
参与有奖
本次直播活动中设置了随机抽奖环节,奖品为 INFINI Labs 周边纪念品,包括 T 恤、鸭舌帽、咖啡杯、指甲刀套件等等(图片仅供参考,款式、颜色与尺码随机)。
活动交流
活动交流群二维码 7 天内(8 月 1 日前)有效,如过期请添加小助手微信拉群。活动最新消息也会在群内及时同步,欢迎大家参与,记得先预约,精彩内容不错过!
讲师招募
搜索客社区 Meetup 讲师持续招募中...
这是一个由搜索客社区精心组织策划的线下线上技术交流活动,我们诚挚邀请各位技术大咖、行业精英踊跃提交演讲议题。Meetup 活动将聚焦 AI 与搜索领域的最新动态,以及数据实时搜索分析、向量检索、技术实践与案例分析、日志分析、安全等领域的深度探讨。详情参见:http://cfp.searchkit.cn 。我们热切期待您的精彩分享!
关于 搜索客(SearchKit)社区
搜索客社区由 Elasticsearch 中文社区进行全新的品牌升级,以新的 Slogan:“搜索人自己的社区” 为宣言。汇集搜索领域最新动态、精选干货文章、精华讨论、文档资料、翻译与版本发布等,为广大搜索领域从业者提供更为丰富便捷的学习和交流平台。社区官网:https://searchkit.cn 。
Easysearch 有奖征文活动推荐
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »
【搜索客社区日报】第1867期 (2024-07-25)
https://mp.weixin.qq.com/s/yXz5kuiUNQFdTUdHQITL2Q
2.开源仅 1 天就斩获近万星!超越 RAG、让大模型拥有超强记忆力的 Mem0 火了!
https://mp.weixin.qq.com/s/ZJUD2n5RZ6XCF3aZ53SpGw
3.MySQL新版恶性Bug,表太多就崩给你看
https://mp.weixin.qq.com/s/LTlR65SY7ZOpPFGH0kUsVg
编辑:Se7en
更多资讯:http://news.searchkit.cn
https://mp.weixin.qq.com/s/yXz5kuiUNQFdTUdHQITL2Q
2.开源仅 1 天就斩获近万星!超越 RAG、让大模型拥有超强记忆力的 Mem0 火了!
https://mp.weixin.qq.com/s/ZJUD2n5RZ6XCF3aZ53SpGw
3.MySQL新版恶性Bug,表太多就崩给你看
https://mp.weixin.qq.com/s/LTlR65SY7ZOpPFGH0kUsVg
编辑:Se7en
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】 第1866期 (2024-07-24)
https://mp.weixin.qq.com/s/z8CcFi03kQMGoEEQbuHzxw
2.Elasticsearch 中的位向量
https://blog.csdn.net/UbuntuTo ... 22765
3.介绍 Elasticsearch 中的 Learning to Tank - 学习排名
https://blog.csdn.net/UbuntuTo ... 64162
编辑:kin122
更多资讯:http://news.searchkit.cn
https://mp.weixin.qq.com/s/z8CcFi03kQMGoEEQbuHzxw
2.Elasticsearch 中的位向量
https://blog.csdn.net/UbuntuTo ... 22765
3.介绍 Elasticsearch 中的 Learning to Tank - 学习排名
https://blog.csdn.net/UbuntuTo ... 64162
编辑:kin122
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】第1865期 (2024-07-23)
1. 没想到吧,我还能在树莓派上搭ES
https://medium.com/%40npan1990 ... 49770
2. 我是怎么在k8s上搭建elk全家的?
https://medium.com/%40degola/i ... bf199
3. 用RAG进一步提升AI powered searching的能力
https://medium.com/gitconnecte ... 4b1f8
编辑:斯蒂文
更多资讯:http://news.searchkit.cn
1. 没想到吧,我还能在树莓派上搭ES
https://medium.com/%40npan1990 ... 49770
2. 我是怎么在k8s上搭建elk全家的?
https://medium.com/%40degola/i ... bf199
3. 用RAG进一步提升AI powered searching的能力
https://medium.com/gitconnecte ... 4b1f8
编辑:斯蒂文
更多资讯:http://news.searchkit.cn
收起阅读 »

【搜索客社区日报】第1864期 (2024-07-22)
https://developer.nvidia.com/b ... -ran/
2. 2024 年最值得关注的 8 个 AI 博客
https://www.greataiprompts.com ... logs/
3. 什么是 AI 代理?
https://www.technologyreview.c ... ents/
4. GPT-4o mini:推进成本效益型智能
https://openai.com/index/gpt-4 ... ence/
5. 2024 年数据库管理的未来
https://www.knowledgehut.com/b ... uture
编辑:Muse
更多资讯:http://news.searchkit.cn
https://developer.nvidia.com/b ... -ran/
2. 2024 年最值得关注的 8 个 AI 博客
https://www.greataiprompts.com ... logs/
3. 什么是 AI 代理?
https://www.technologyreview.c ... ents/
4. GPT-4o mini:推进成本效益型智能
https://openai.com/index/gpt-4 ... ence/
5. 2024 年数据库管理的未来
https://www.knowledgehut.com/b ... uture
编辑:Muse
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】第1863期 (2024-07-19)
https://infinilabs.cn/blog/2024/news-20240718/
2、较 ClickHouse 降低 50% 成本,湖仓一体在B站的演进
https://dbaplus.cn/news-131-5889-1.html
3、LangChain 实战:RAG 遇上大模型,运维革命就开始了……
https://dbaplus.cn/news-73-5978-1.html
4、OpenSearch 的演进与语义检索技术革新
https://blog.csdn.net/kunpengt ... 16513
编辑:Fred
更多资讯:http://news.searchkit.cn
https://infinilabs.cn/blog/2024/news-20240718/
2、较 ClickHouse 降低 50% 成本,湖仓一体在B站的演进
https://dbaplus.cn/news-131-5889-1.html
3、LangChain 实战:RAG 遇上大模型,运维革命就开始了……
https://dbaplus.cn/news-73-5978-1.html
4、OpenSearch 的演进与语义检索技术革新
https://blog.csdn.net/kunpengt ... 16513
编辑:Fred
更多资讯:http://news.searchkit.cn 收起阅读 »

【搜索客社区日报】第1862期 (2024-07-18)
https://mp.weixin.qq.com/s/lpT-8yQA8wAcxdjuBc88Ew
2.AIGC 提示词可视化编辑器 OPS
https://github.com/Moonvy/OpenPromptStudio
3.Facebook 为什么要弃用 Git?
https://mp.weixin.qq.com/s/n2UVEx8giKROJR9NWZB8pA
4.机场出租车恶性循环与国产数据库怪圈
https://mp.weixin.qq.com/s/uccjOkAR1zgur6tftHkzMg
5.被AI加持后的夸克,强大的让我有些陌生
https://mp.weixin.qq.com/s/RZ6J3v79bLOv6vhAm4nYLw
编辑:Se7en
更多资讯:http://news.searchkit.cn
https://mp.weixin.qq.com/s/lpT-8yQA8wAcxdjuBc88Ew
2.AIGC 提示词可视化编辑器 OPS
https://github.com/Moonvy/OpenPromptStudio
3.Facebook 为什么要弃用 Git?
https://mp.weixin.qq.com/s/n2UVEx8giKROJR9NWZB8pA
4.机场出租车恶性循环与国产数据库怪圈
https://mp.weixin.qq.com/s/uccjOkAR1zgur6tftHkzMg
5.被AI加持后的夸克,强大的让我有些陌生
https://mp.weixin.qq.com/s/RZ6J3v79bLOv6vhAm4nYLw
编辑:Se7en
更多资讯:http://news.searchkit.cn 收起阅读 »

Easysearch 新特性:写入限流功能介绍
背景
在 Easysearch 的各种使用场景中,高写入吞吐量的场景占了很大一部分,由此也带来了一些使用上的问题,很多用户由于使用经验不足,对集群的写入压测进行的不够充分,不能很好的规划集群的写入量。
导致经常发生以下问题:
- 写入吞吐量过大对内存影响巨大,引发节点 OOM,节点掉线问题。
- 对 CPU 和内存的占用严重影响了其他的查询业务的响应。
- 以及磁盘 IO 负载增加,挤占集群的网络带宽等问题。
之前就有某金融保险类客户遇到了因业务端写入量突然猛增导致数据节点不停的 Full GC,进而掉入了不停的掉线,上线,又掉线的恶性循环中。当时只能建议用户增加一个类似“挡板”的服务,在数据进入到集群之前进行拦截,对客户端写入进行干预限流:
这样做虽然有效,但是也增加了整个系统的部署复杂性,提高了运维成本。
根据客户的实际场景,Easysearch 从 1.8.0 版本开始引入了节点和 Shard 级别的限流功能,不用依赖第三方就可以限制写入压力,并在 1.8.2 版本增加了索引级别的写入限流。 注意:所有写入限流都是针对各数据节点的 Primary Shard 写入进行限流的,算上副本的话吞吐量要乘以 2。
限流示意图:
下面是限流前后相同数据节点的吞吐量和 CPU 对比:
测试环境:
ip name http port version role master
10.0.0.3 node-3 10.0.0.3:9209 9303 1.8.0 dimr -
10.0.0.3 node-4 10.0.0.3:9210 9304 1.8.0 im -
10.0.0.3 node-2 10.0.0.3:9208 9302 1.8.0 dimr -
10.0.0.3 node-1 10.0.0.3:9207 9301 1.8.0 dimr *
测试索引配置:
PUT test_0
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 3
}
}
压测工具:采用极限科技的 INFINI Loadgen 压测,这款压测工具使用简单,可以方便对任何支持 Rest 接口的库进行压测。
压测命令:
./loadgen-linux-amd64 -d 180 -c 10 -config loadgen-easy-1.8.yml
压测 180 秒,10 个并发,每个 bulk 请求 5000 条。
节点级别限流
通过 INFINI Console 监控指标可以看到,限流之前的某个数据节点,CPU 占用 10%,每秒写入 40000 条左右:
在 Cluster Settings 里配置,启用节点级别限流,限制每个节点的每秒最大写入 10000 条,并在默认的 1 秒间隔内进行重试,超过默认间隔后直接拒绝。
PUT _cluster/settings
{
"transient": {
"cluster.throttle.node.write": true,
"cluster.throttle.node.write.max_requests": 10000,
"cluster.throttle.node.write.action": "retry"
}
}
限流后,CPU 占用降低了约 50%,算上副本一共 20000 条每秒:
Shard 级别限流
设置每个分片最大写入条数为 2000 条每秒
PUT _cluster/settings
{
"transient": {
"cluster.throttle.shard.write": true,
"cluster.throttle.shard.write.max_requests": 2000,
"cluster.throttle.shard.write.action": "retry"
}
}
集群级别的监控,同样是只针对主 Shard。
从 Console 的监控指标可以看出,索引 test_0 的 Primary indexing 维持在 6000 左右,正好是 3 个主分片限制的 2000 的写入之和。
再看下数据节点监控,Total Shards 表示主分片和副本分片的写入总和即 4000,单看主分片的话,正好是 2000.
索引级别限流
有时,集群中可能某个索引的写入吞吐过大而影响了其他业务,也可以针对特定的索引配置写入限制。 可以在索引的 Settings 里设置当前索引每秒写入最大条数为 6000:
PUT test_0
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 3,
"index.throttle.write.max_requests": 6000,
"index.throttle.write.action": "retry",
"index.throttle.write.enable": true
}
}
下图索引的 Primary indexing 在 6000 左右,表示索引的所有主分片的写入速度限制在了 6000。
总结
通过本次测试对比,可以看出限流的好处:
-
有效控制写入压力: 写入限流功能能够有效限制每个节点和每个 Shard 的写入吞吐量,防止因写入量过大而导致系统资源被过度消耗的问题。
-
降低系统资源占用: 在限流前,某数据节点的 CPU 占用率约为 10%。限流后,CPU 占用率显著降低至约 5%,减少了约 50%。这表明在高并发写入场景下,写入限流功能显著降低了系统的 CPU 负载。
-
提高系统稳定性: 通过控制写入吞吐量,避免了频繁的 Full GC 和节点掉线问题,从而提升了系统的整体稳定性和可靠性。
- 保障查询业务性能: 写入限流功能减少了写入操作对 CPU 和内存的占用,确保其他查询业务的响应性能不受影响。
综上所述,写入限流功能在高并发写入场景下表现出色,不仅有效控制了写入压力,还显著降低了系统资源占用,从而提高了系统的稳定性和查询业务的性能。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:张磊
原文:https://infinilabs.cn/blog/2024/easysearch-new-feature-write-throttling-introduction/
背景
在 Easysearch 的各种使用场景中,高写入吞吐量的场景占了很大一部分,由此也带来了一些使用上的问题,很多用户由于使用经验不足,对集群的写入压测进行的不够充分,不能很好的规划集群的写入量。
导致经常发生以下问题:
- 写入吞吐量过大对内存影响巨大,引发节点 OOM,节点掉线问题。
- 对 CPU 和内存的占用严重影响了其他的查询业务的响应。
- 以及磁盘 IO 负载增加,挤占集群的网络带宽等问题。
之前就有某金融保险类客户遇到了因业务端写入量突然猛增导致数据节点不停的 Full GC,进而掉入了不停的掉线,上线,又掉线的恶性循环中。当时只能建议用户增加一个类似“挡板”的服务,在数据进入到集群之前进行拦截,对客户端写入进行干预限流:
这样做虽然有效,但是也增加了整个系统的部署复杂性,提高了运维成本。
根据客户的实际场景,Easysearch 从 1.8.0 版本开始引入了节点和 Shard 级别的限流功能,不用依赖第三方就可以限制写入压力,并在 1.8.2 版本增加了索引级别的写入限流。 注意:所有写入限流都是针对各数据节点的 Primary Shard 写入进行限流的,算上副本的话吞吐量要乘以 2。
限流示意图:
下面是限流前后相同数据节点的吞吐量和 CPU 对比:
测试环境:
ip name http port version role master
10.0.0.3 node-3 10.0.0.3:9209 9303 1.8.0 dimr -
10.0.0.3 node-4 10.0.0.3:9210 9304 1.8.0 im -
10.0.0.3 node-2 10.0.0.3:9208 9302 1.8.0 dimr -
10.0.0.3 node-1 10.0.0.3:9207 9301 1.8.0 dimr *
测试索引配置:
PUT test_0
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 3
}
}
压测工具:采用极限科技的 INFINI Loadgen 压测,这款压测工具使用简单,可以方便对任何支持 Rest 接口的库进行压测。
压测命令:
./loadgen-linux-amd64 -d 180 -c 10 -config loadgen-easy-1.8.yml
压测 180 秒,10 个并发,每个 bulk 请求 5000 条。
节点级别限流
通过 INFINI Console 监控指标可以看到,限流之前的某个数据节点,CPU 占用 10%,每秒写入 40000 条左右:
在 Cluster Settings 里配置,启用节点级别限流,限制每个节点的每秒最大写入 10000 条,并在默认的 1 秒间隔内进行重试,超过默认间隔后直接拒绝。
PUT _cluster/settings
{
"transient": {
"cluster.throttle.node.write": true,
"cluster.throttle.node.write.max_requests": 10000,
"cluster.throttle.node.write.action": "retry"
}
}
限流后,CPU 占用降低了约 50%,算上副本一共 20000 条每秒:
Shard 级别限流
设置每个分片最大写入条数为 2000 条每秒
PUT _cluster/settings
{
"transient": {
"cluster.throttle.shard.write": true,
"cluster.throttle.shard.write.max_requests": 2000,
"cluster.throttle.shard.write.action": "retry"
}
}
集群级别的监控,同样是只针对主 Shard。
从 Console 的监控指标可以看出,索引 test_0 的 Primary indexing 维持在 6000 左右,正好是 3 个主分片限制的 2000 的写入之和。
再看下数据节点监控,Total Shards 表示主分片和副本分片的写入总和即 4000,单看主分片的话,正好是 2000.
索引级别限流
有时,集群中可能某个索引的写入吞吐过大而影响了其他业务,也可以针对特定的索引配置写入限制。 可以在索引的 Settings 里设置当前索引每秒写入最大条数为 6000:
PUT test_0
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 3,
"index.throttle.write.max_requests": 6000,
"index.throttle.write.action": "retry",
"index.throttle.write.enable": true
}
}
下图索引的 Primary indexing 在 6000 左右,表示索引的所有主分片的写入速度限制在了 6000。
总结
通过本次测试对比,可以看出限流的好处:
-
有效控制写入压力: 写入限流功能能够有效限制每个节点和每个 Shard 的写入吞吐量,防止因写入量过大而导致系统资源被过度消耗的问题。
-
降低系统资源占用: 在限流前,某数据节点的 CPU 占用率约为 10%。限流后,CPU 占用率显著降低至约 5%,减少了约 50%。这表明在高并发写入场景下,写入限流功能显著降低了系统的 CPU 负载。
-
提高系统稳定性: 通过控制写入吞吐量,避免了频繁的 Full GC 和节点掉线问题,从而提升了系统的整体稳定性和可靠性。
- 保障查询业务性能: 写入限流功能减少了写入操作对 CPU 和内存的占用,确保其他查询业务的响应性能不受影响。
综上所述,写入限流功能在高并发写入场景下表现出色,不仅有效控制了写入压力,还显著降低了系统资源占用,从而提高了系统的稳定性和查询业务的性能。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
收起阅读 »作者:张磊
原文:https://infinilabs.cn/blog/2024/easysearch-new-feature-write-throttling-introduction/