征文系列
使用 AWS EKS 部署 Easysearch
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2721 次浏览 • 2024-08-15 15:47
随着企业对数据搜索和分析需求的增加,高效的搜索引擎解决方案变得越来越重要。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:国产搜索型数据库的崛起与未来展望
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 3350 次浏览 • 2024-08-14 12:17
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 征文活动
作者:李家兴
玩转 Easysearch 语法
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2936 次浏览 • 2024-07-11 12:11
什么是 Easysearch
Elasticsearch 是一个基于 Apache Lucene 的开源分布式搜索和分析引擎,它被广泛应用于全文搜索、结构化搜索和分析等多种场景中。作为 Elasticsearch 的国产化替代方案,Easysearch 不仅保持了与原生 Elasticsearch 的高度兼容性,还在功能、性能、稳定性和扩展性方面进行了全面提升。对于开发团队来说,从 Elasticsearch 切换到 Easysearch 不需要做任何业务代码的调整,确保了无缝衔接和平滑迁移。
Easysearch 是基于 Elasticsearch 7.10.2 开源版本二次开发,所以支持 Elasticsearch 原始的 Query DSL 语法,基本的 SQL 语法,并且兼容现有 Elasticsearch 的 SDK,使得应用无需修改代码即可进行迁移。其平滑的迁移特性,如基于网关的无缝跨版本迁移与升级,提供了随时安全回退的能力。
在之前的文章中,我们已经介绍了 Easysearch 的搭建 和 可视化工具的使用,今天我们将探讨 Easysearch 集群的基本概念和常用的 API。
Easysearch 集群的核心概念
Easysearch 集群由以下几个核心概念构成:
- 节点(Node):集群中的单个服务器,负责存储数据并参与集群的索引和搜索功能。
- 集群(Cluster):由一个或多个节点组成,拥有唯一的集群名,协同完成数据索引和查询任务。
- 索引(Index):存储相关数据的容器,类似于关系数据库中的数据库,一个索引包含多个文档。
- 文档(Document):索引中的基本数据单位,相当于关系数据库中的行。
- 字段(Field):文档中的一个属性,相当于数据库中的列。
- 分片(Shard):为了提高性能和扩展性,索引可以被分割成多个分片,每个分片是索引的一个部分。
- 副本(Replica):分片的副本,用于提高数据的可靠性和在节点出现故障时的可用性。
通过多个 API,例如 _cluster/health
和 _cluster/stats
,用户可以轻松查看集群的健康状态和详细信息,这些信息对于维护和优化 Easysearch 集群至关重要。
无论是在性能的提升,还是在功能的兼容性方面,Easysearch 都为用户提供了一个强大的搜索引擎平台,让从 Elasticsearch 到 Easysearch 的迁移变得无缝且高效。掌握其核心概念和 API 的使用,将帮助开发者更好地利用这些工具来构建和优化他们的搜索解决方案。
查看集群信息
在 Easysearch 中,可以通过多个 API 来查看集群的各种信息,包括集群的健康状况、节点信息和索引状态。以下是一些常用的查看集群信息的 API 和示例:
查看集群健康状况
_cluster/health
API 可以查看集群的健康状态,包括集群是否处于正常状态、节点数量、分片状态等。
GET /_cluster/health
示例响应:
{
"cluster_name": "my_cluster",
"status": "green",
"timed_out": false,
"number_of_nodes": 3,
"number_of_data_nodes": 3,
"active_primary_shards": 5,
"active_shards": 10,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 100.0
}
查看集群状态
_cluster/stats
API 可以查看集群的详细状态,包括索引、节点、分片等信息。
GET /_cluster/stats
示例响应:
{
"cluster_name": "my_cluster",
"status": "green",
"indices": {
"count": 10,
"shards": {
"total": 20,
"primaries": 10,
"replication": 1.0,
"index": {
"shards": {
"min": 1,
"max": 5,
"avg": 2.0
}
}
}
},
"nodes": {
"count": {
"total": 3,
"data": 3,
"coordinating_only": 0,
"master": 1,
"ingest": 2
},
"os": {
"available_processors": 12,
"allocated_processors": 12
},
"process": {
"cpu": {
"percent": 10
},
"open_file_descriptors": {
"min": 100,
"max": 300,
"avg": 200
}
}
}
}
查看节点信息
_nodes
API 可以查看集群中节点的详细信息,包括节点角色、IP 地址、内存使用情况等。
GET /_nodes
示例响应:
{
"cluster_name": "my_cluster",
"nodes": {
"node_id_1": {
"name": "node_1",
"transport_address": "192.168.1.1:9300",
"host": "192.168.1.1",
"ip": "192.168.1.1",
"roles": ["master", "data", "ingest"],
"os": {
"available_processors": 4,
"allocated_processors": 4
},
"process": {
"cpu": {
"percent": 10
},
"open_file_descriptors": 200
}
},
"node_id_2": {
"name": "node_2",
"transport_address": "192.168.1.2:9300",
"host": "192.168.1.2",
"ip": "192.168.1.2",
"roles": ["data"],
"os": {
"available_processors": 4,
"allocated_processors": 4
},
"process": {
"cpu": {
"percent": 15
},
"open_file_descriptors": 150
}
}
}
}
查看索引状态
_cat/indices
API 可以查看集群中所有索引的状态,包括文档数、存储大小、分片数等信息。
GET /_cat/indices?v
示例响应:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open index_1 SxNUd84vRl6QH5P7g0T4Vg 1 1 0 0 230b 230b
green open index_2 NxEYib4yToCnA1PpQ8P4Xw 5 1 100 1 10mb 5mb
这些 API 可以帮助你全面了解 Easysearch 集群的状态和健康状况,从而更好地管理和维护集群。
增删改查操作
在 Easysearch 中,增删改查操作是管理数据和索引的基本功能。以下是如何使用这些操作的详细示例。
创建索引
创建一个新的索引,并指定分片和副本的数量:
PUT /my_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
删除索引
删除一个不再需要的索引:
DELETE /my_index
添加文档
通过 POST 或 PUT 请求向索引中添加文档:
POST /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
PUT /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
POST
和 PUT
方法用于不同的操作,尽管它们都可以用于添加或更新文档,但它们的行为有所不同。
POST /my_index/_doc/1
方法用于创建或替换一个文档。如果指定的文档 ID 已经存在,POST
请求将更新整个文档(不会合并字段)。如果文档 ID 不存在,它将创建一个新的文档。
POST /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
PUT /my_index/_doc/1
方法通常用于创建一个新的文档,或者完全替换一个已存在的文档。与 POST
类似,如果指定的文档 ID 已经存在,PUT
请求将替换整个文档。
PUT /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
1.使用场景:
POST
:更适合用于添加或部分更新文档,即使文档 ID 已经存在。PUT
:更适合用于创建或完全替换文档。
2.ID 自动生成:
POST
请求可以不提供文档 ID,此时 Easysearch 会自动生成一个文档 ID。PUT
请求必须提供文档 ID,如果未提供,则会返回错误。
3.部分更新:
POST
请求可以用于部分更新(通过_update
API)。PUT
请求用于完全替换文档,不支持部分更新。
如果文档 ID 已经存在,POST
和 PUT
都会覆盖整个文档,并且效果是一样的。但是,通常 POST
用于提交数据,而 PUT
用于上传和替换资源。
1.使用 POST
方法添加或更新文档:
POST /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
2.使用 PUT
方法添加或更新文档:
PUT /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
在这两个示例中,结果都是在索引 my_index
中创建或更新文档 ID 为 1
的文档。无论使用 POST
还是 PUT,如果文档 ID 已存在,都会覆盖原有的文档内容。
新建文档
使用 _create
方法新建文档,如果文档已经存在则返回错误:
PUT /my_index/_create/1
{
"a": 1
}
如果尝试新建已存在的文档,将会出现如下错误:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [1])",
"index_uuid": "1xWdHLTaTm6l6HbqACaIEA",
"shard": "0",
"index": "my_index"
}
],
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [1])",
"index_uuid": "1xWdHLTaTm6l6HbqACaIEA",
"shard": "0",
"index": "my_index"
},
"status": 409
}
获取文档
通过 ID 获取文档的详细信息:
GET /my_index/_doc/1
更新文档
更新文档的特定字段,保留原有字段:
POST /my_index/_update/1
{
"doc": {
"age": 31
}
}
删除文档
通过 ID 删除指定的文档:
DELETE /my_index/_doc/1
查询所有文档
查询索引中的所有文档:
GET /my_index/_search
{
"query": {
"match_all": {}
}
}
这个是 《老杨玩搜索》中总结的图,可以作为“小抄”来记忆:
批量操作 (_bulk API)
_bulk API
用于在一次请求中执行多个索引、删除和更新操作,这对于批量处理大规模数据非常有用,可以显著提高性能和效率。以下是 _bulk API
的基本使用示例:
POST /my_index/_bulk
{ "index": { "_id": "1" } }
{ "name": "John Doe", "age": 30, "occupation": "Engineer" }
{ "index": { "_id": "2" } }
{ "name": "Jane Doe", "age": 25, "occupation": "Designer" }
{ "update": { "_id": "1" } }
{ "doc": { "age": 31 } }
_bulk API
的请求体由多个操作和文档组成。每个操作行包含一个动作描述行和一个可选的源文档行。动作描述行指明了操作的类型(例如,index、create、delete、update)以及操作的元数据。源文档行则包含了实际的数据。
每个操作之间需要用换行符分隔,并且请求体最后必须以换行符结尾。
POST /_bulk
{ "index": { "_index": "a", "_id": "1" } }
{ "name": "John Doe", "age": 30, "occupation": "Engineer" }
{ "index": { "_index": "b", "_id": "2" } }
{ "name": "Jane Doe", "age": 25, "occupation": "Designer" }
{ "update": { "_index": "a", "_id": "1" } }
{ "doc": { "age": 31 } }
分词器
在 Easysearch 中,分词器(Analyzer)用于将文本分解为词项(terms),是全文搜索和文本分析的基础。分词器通常由字符过滤器(Character Filters)、分词器(Tokenizer)和词项过滤器(Token Filters)组成。以下是关于分词器的详细介绍:
1.字符过滤器(Character Filters):在分词之前对文本进行预处理。例如,去除 HTML 标签,替换字符等。
2.分词器(Tokenizer):将文本分解为词项(tokens)。这是分词过程的核心。
3.词项过滤器(Token Filters):对词项进行处理,如小写化、去除停用词、词干提取等。
只有 text 字段支持全文检索,返回的结果根据相似度打分,我们一起看下
POST /index/_mapping
{
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
.POST /index/_mapping
- 这个部分表示要向名为
index
的索引添加或更新映射设置。
2.“properties”
properties
定义了索引中文档的字段结构。在这个例子中,定义了一个名为content
的字段。
3.“content”
- 定义了名为
content
的字段。
4.“type”: “text”
type
字段指定 content
字段的数据类型为 text
。text
类型适用于需要分词和全文搜索的字段。
5.“analyzer”: “ik_max_word”
analyzer
字段指定索引时使用的分词器为ik_max_word
。ik_max_word
是 IK 分词器中的一种,它会尽可能多地将文本分解为更多的词项。
6.“search_analyzer”: “ik_smart”
search_analyzer
字段指定搜索时使用的分词器为ik_smart
。ik_smart
是 IK 分词器中的另一种,它会更智能地进行分词,以提高搜索的准确性。
当然,在设置这个 mapping 的时候可以使用同样的分词器,也可以使用不同的分词器。这里介绍下 IK 分词器:
- IK 分词器是一种中文分词器,适用于中文文本的分词。IK 分词器有两种分词模式:
ik_max_word
和ik_smart
。ik_max_word
:将文本尽可能多地切分成词项,适用于需要更高召回率的场景。ik_smart
:进行最智能的分词,适用于需要更高精度的搜索场景。
这个 DSL 的设置意味着,在向这个索引添加或更新文档时,content
字段的文本会使用ik_max_word
分词器进行分词处理,以确保文本被尽可能多地切分成词项。而在搜索时,content
字段的文本会使用ik_smart
分词器进行分词处理,以提高搜索的准确性和相关性。
以下是关于 standard,ik_smart,ik_max_word 这几个分词器的对比:
GET /_analyze
{
"tokenizer": "standard",
"text": "我,机器人"
}
GET /_analyze
{
"tokenizer": "ik_smart",
"text": "我,机器人"
}
GET /_analyze
{
"tokenizer": "ik_max_word",
"text": "我,机器人"
}
结果如下:
# GET /_analyze (standard)
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "机",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "器",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "人",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 3
}
]
}
# GET /_analyze(ik_smart)
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "机器人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 1
}
]
}
# GET /_analyze (ik_max_word)
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "机器人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 1
},
{
"token": "机器",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 2
},
{
"token": "人",
"start_offset": 4,
"end_offset": 5,
"type": "CN_CHAR",
"position": 3
}
]
}
如果使用了不存在的分词器会出现这个错误。
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "failed to find global tokenizer under [simple]"
}
],
"type": "illegal_argument_exception",
"reason": "failed to find global tokenizer under [simple]"
},
"status": 400
}
精确搜索/正则表达式搜索/通配符
在 Easysearch 中,精确搜索、正则表达式搜索和通配符搜索是三种不同的搜索方式,各有其应用场景和特点:
1.精确搜索 (Term Query):
- 精确搜索用于查找与搜索词完全匹配的文档。
- 不进行分词处理,通常用于关键字、ID、标签等字段的精确匹配。
- 适用于结构化数据或不需要分词的字段(如数字、日期、布尔值等)。
{
"query": {
"term": {
"status": "active"
}
}
}
2.正则表达式搜索 (Regexp Query):
- 正则表达式搜索用于基于正则表达式模式匹配的文档搜索。
- 支持复杂的字符串匹配模式,但性能可能较低,特别是当数据量较大时。
- 适用于需要灵活且复杂匹配条件的搜索。
{
"query": {
"regexp": {
"content": "Easysearch .*powerful"
}
}
}
3.通配符搜索 (Wildcard Query):
- 通配符搜索用于通过通配符模式匹配文档。
- 支持 ?(匹配单个字符)和 *(匹配零个或多个字符)。
- 性能相对较差,因为通配符搜索可能需要扫描大量数据。
{
"query": {
"wildcard": {
"username": "john*"
}
}
}
- 精确搜索:用于需要绝对匹配特定词语或不需要分词的字段。例如,查找特定用户 ID 或状态。
- 正则表达式搜索:用于需要复杂字符串模式匹配的场景,但要谨慎使用,避免性能问题。
- 通配符搜索:用于简单模式匹配,但同样需要注意性能影响,尽量避免在大数据集上频繁使用。
接下来看这个例子,我们将使用批量导入数据,然后进行几种不同类型的查询,包括精确查询、通配符查询和正则表达式查询。
POST /users/_bulk
{ "index": { "_index": "users", "_id": 1 }}
{ "username": "john_doe", "status": "active", "email": "john.doe@example.com", "bio": "John loves Easysearch and open-source technologies." }
{ "index": { "_index": "users", "_id": 2 }}
{ "username": "jane_doe", "status": "inactive", "email": "jane.doe@example.com", "bio": "Jane is a data scientist working with big data." }
{ "index": { "_index": "users", "_id": 3 }}
{ "username": "john_smith", "status": "active", "email": "john.smith@example.com", "bio": "John enjoys hiking and nature." }
{ "index": { "_index": "users", "_id": 4 }}
{ "username": "alice_jones", "status": "active", "email": "alice.jones@example.com", "bio": "Alice is a software engineer specialized in JavaScript." }
{ "index": { "_index": "users", "_id": 5 }}
{ "username": "bob_jones", "status": "inactive", "email": "bob.jones@example.com", "bio": "Bob is an AI enthusiast and machine learning expert." }
1.精确查询:查询状态为 “active” 的用户。
GET /users/_search
{
"query": {
"term": {
"status": "active"
}
}
}
2.通配符查询:查询 bio 字段中包含 “John” 开头的词。
GET /users/_search
{
"query": {
"wildcard": {
"bio": "John*"
}
}
}
3.正则表达式查询:查询用户名以 “john” 开头的用户
GET /users/_search
{
"query": {
"regexp": {
"username": "john.*"
}
}
}
通过这些例子,你可以看到如何在 Easysearch 中使用批量导入数据,然后使用各种查询方法来检索特定条件的数据。这些查询方法可以帮助你高效地搜索和分析数据,以满足不同的业务需求。
这里同样是《老杨玩搜索》中总结的“小抄”来方便记忆:
多字段查询
在 Easysearch 中,多字段查询允许您在多个字段上同时执行搜索,以获取更精确的结果。最常用的多字段查询类型是 multi_match
查询。multi_match
查询是 match
查询的扩展,能够在多个字段中搜索指定的关键词。
multi_match
查询支持多种匹配模式,如 best_fields
、most_fields
、cross_fields
、phrase
和 phrase_prefix
。以下是各模式的简要介绍:
- best_fields:默认模式,选择匹配度最高的字段。
- most_fields:计算每个字段的匹配度,然后将匹配度相加。
- cross_fields:将多个字段视为一个字段进行匹配,适用于分析文本被分散到多个字段的情况。
- phrase:短语匹配,确保词项顺序与查询相同。
- phrase_prefix:短语前缀匹配,允许词项的部分匹配。
我们先导入一些示例数据到一个索引 documents
中:
POST /documents/_bulk
{ "index": { "_id": 1 } }
{ "title": "Easysearch Guide", "content": "This is an introductory guide to Easysearch ." }
{ "index": { "_id": 2 } }
{ "title": "Advanced Easysearch ", "content": "This guide covers advanced topics in Easysearch ." }
{ "index": { "_id": 3 } }
{ "title": "Easysearch in Action", "content": "Practical guide to Easysearch usage." }
{ "index": { "_id": 4 } }
{ "title": "Learning Easysearch ", "content": "Beginner's guide to learning Easysearch ." }
我们将使用 multi_match
查询在 title
和 content
字段中同时搜索关键词。
1.基本 multi_match 查询:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "guide",
"fields": ["title", "content"]
}
}
}
2.指定匹配模式为 best_fields:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "guide",
"fields": ["title", "content"],
"type": "best_fields"
}
}
}
3.指定匹配模式为 most_fields:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "guide",
"fields": ["title", "content"],
"type": "most_fields"
}
}
}
4.使用 cross_fields 模式:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "Easysearch guide",
"fields": ["title", "content"],
"type": "cross_fields"
}
}
}
5.短语匹配 (phrase):
POST /documents/_search
{
"query": {
"multi_match": {
"query": "introductory guide",
"fields": ["title", "content"],
"type": "phrase"
}
}
}
6.短语前缀匹配 (phrase_prefix):
POST /documents/_search
{
"query": {
"multi_match": {
"query": "introductory gui",
"fields": ["title", "content"],
"type": "phrase_prefix"
}
}
}
- query:要搜索的关键词或短语。
- fields:要搜索的字段列表,可以包含一个或多个字段。
- type:指定匹配模式,默认为 best_fields。
使用 multi_match
查询,您可以在多个字段上同时执行搜索,获得更精确和全面的结果。通过指定不同的匹配模式,您可以调整查询行为以满足特定的搜索需求。无论是基本关键词匹配、短语匹配还是跨字段匹配,multi_match
查询都提供了强大的功能来处理复杂的搜索场景。
除此之外,还可以使用 boost 参数用于调整特定字段的权重,从而影响搜索结果的相关性评分。multi_match
查询支持为不同字段设置不同的 boost 值,以便在搜索结果中优先显示某些字段的匹配项。
布尔查询
布尔查询是 Easysearch 中非常强大且灵活的一种查询方式,它允许用户通过组合多个查询条件来实现复杂的搜索需求。布尔查询使用 bool
查询类型,可以包含以下几种子句:must
、filter
、must_not
和 should
。每种子句都有其特定的用途和语义。
1.must:
- 包含在
must
数组中的查询条件必须匹配,类似于逻辑上的 AND 操作。 - 如果有多个条件,所有条件都必须满足,文档才会被包含在结果集中。
2.filter:
- 包含在
filter
数组中的查询条件必须匹配,但它不会影响评分。 filter
子句通常用于对性能要求较高的过滤操作,因为它不计算相关性评分。
3.must_not:
- 包含在
must_not
数组中的查询条件必须不匹配,类似于逻辑上的 NOT 操作。 - 如果有任何一个条件匹配,文档就会被排除在结果集之外。
4.should:
- 包含在
should
数组中的查询条件至少匹配一个。 - 如果布尔查询中没有
must
子句,则至少要匹配一个should
子句。 should
子句在计算相关性评分时也有影响。
5.minimum_should_match:
- 指定
should
子句中至少需要满足的条件数量。
首先,我们需要创建一个名为 books
的索引,并定义它的映射(mappings)。映射用于指定每个字段的数据类型。在这个例子中,类别
和书名
字段都被定义为 keyword
类型,这是因为我们需要进行精确匹配查询。
PUT /books
{
"mappings": {
"properties": {
"类别": { "type": "keyword" },
"书名": { "type": "keyword" }
}
}
}
接下来,我们使用批量操作(bulk API)将一些示例数据导入到 books
索引中。这些数据包括不同类别的书籍。
POST /books/_bulk
{ "index": { "_id": 1 } }
{ "类别": "文学", "书名": "我的阿勒泰" }
{ "index": { "_id": 2 } }
{ "类别": "文学", "书名": "平凡的世界" }
{ "index": { "_id": 3 } }
{ "类别": "科学", "书名": "时间简史" }
{ "index": { "_id": 4 } }
{ "类别": "文学", "书名": "百年孤独" }
{ "index": { "_id": 5 } }
{ "类别": "文学", "书名": "红楼梦" }
现在,我们使用布尔查询来搜索类别
为“文学”并且书名
为“我的阿勒泰”的文档。这里使用的是 must
子句,表示查询结果必须满足所有条件。
POST /books/_search
{
"query": {
"bool": {
"must": [
{ "term": { "类别": "文学" } },
{ "term": { "书名": "我的阿勒泰" } }
]
}
}
}
我们还可以使用 filter
子句来执行相同的查询。filter
子句用于过滤文档,且不会影响文档的相关性评分。这在不需要计算相关性评分时可以提高查询性能。
POST /books/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "类别": "文学" } },
{ "term": { "书名": "我的阿勒泰" } }
]
}
}
}
当我们执行上述查询时,期望返回的结果是 books
索引中类别为“文学”且书名为“我的阿勒泰”的文档。无论是使用 must
还是 filter
子句,结果应该都是:
{
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"hits": [
{
"_index": "books",
"_id": "1",
"_source": {
"类别": "文学",
"书名": "我的阿勒泰"
}
}
]
}
}
POST /_search
{
"query": {
"bool": {
"must": [
{ "term": { "user.id": "kimchy" } }
],
"filter": [
{ "term": { "tags": "production" } }
],
"must_not": [
{
"range": {
"age": { "gte": 10, "lte": 20 }
}
}
],
"should": [
{ "term": { "tags": "env1" } },
{ "term": { "tags": "deployed" } }
],
"minimum_should_match": 1,
"boost": 1.0
}
}
}
must
子句:必须匹配的条件,文档必须包含user.id
为kimchy
。filter
子句:过滤条件,文档必须包含tags
为production
,但不会影响评分。must_not
子句:不匹配的条件,文档的age
字段不能在 10 到 20 之间。should
子句:可选匹配条件,至少需要匹配一个should
子句中的条件。这里要求tags
字段匹配env1
或deployed
。minimum_should_match
:至少需要匹配一个 should 子句中的条件。boost
:提升查询的整体评分。
为了展示这个 DSL ,我们需要创建一个索引并导入一些数据。假设我们要在 Easysearch 中创建一个索引 users
,并插入一些测试数据。
创建索引
PUT /users
{
"mappings": {
"properties": {
"user.id": { "type": "keyword" },
"tags": { "type": "keyword" },
"age": { "type": "integer" }
}
}
}
批量导入数据
POST /users/_bulk
{ "index": { "_id": 1 } }
{ "user.id": "kimchy", "tags": ["production", "env1"], "age": 25 }
{ "index": { "_id": 2 } }
{ "user.id": "kimchy", "tags": ["production"], "age": 15 }
{ "index": { "_id": 3 } }
{ "user.id": "kimchy", "tags": ["deployed"], "age": 30 }
{ "index": { "_id": 4 } }
{ "user.id": "kimchy", "tags": ["test"], "age": 35 }
{ "index": { "_id": 5 } }
{ "user.id": "other", "tags": ["production"], "age": 25 }
接下来执行布尔查询:
POST /users/_search
{
"query": {
"bool": {
"must": [
{ "term": { "user.id": "kimchy" } }
],
"filter": [
{ "term": { "tags": "production" } }
],
"must_not": [
{
"range": {
"age": { "gte": 10, "lte": 20 }
}
}
],
"should": [
{ "term": { "tags": "env1" } },
{ "term": { "tags": "deployed" } }
],
"minimum_should_match": 1,
"boost": 1.0
}
}
}
根据以上查询,预期返回的结果应该符合以下条件:
user.id
必须是kimchy
(由must
子句决定)。tags
必须包含production
(由filter
子句决定)。age
字段不在 10 到 20 之间(由must_not
子句决定)。tags
字段中至少包含env1
或deployed
中的一个(由should
子句和minimum_should_match
参数决定)。
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.3769134,
"hits": [
{
"_index": "users",
"_type": "_doc",
"_id": "1",
"_score": 1.3769134,
"_source": {
"user.id": "kimchy",
"tags": ["production", "env1"],
"age": 25
}
}
]
}
}
SQL 搜索
Easysearch 直接支持 SQL 查询,无需额外安装插件,同时兼容 Elasticsearch 的 SQL 调用方式,还可以直接编写原生 SQL 查询。
以下是一些测试 SQL 语句的示例:
SELECT * FROM my_index;
SELECT * FROM my_index LIMIT 2;
SELECT * FROM my_index ORDER BY name;
SELECT name AS full_name, age FROM my_index WHERE age > 25;
SELECT name AS full_name, age FROM my_index WHERE age = 25;
SELECT * FROM my_index WHERE age IS NULL;
SELECT DISTINCT age FROM my_index;
SELECT MIN(age), MAX(age), AVG(age) FROM my_index;
SELECT age, COUNT(*) AS CNT FROM my_index GROUP BY age;
使用 Easysearch 执行 SQL 查询
Easysearch 提供了对直接使用 SQL 查询的支持。以下是如何在 Easysearch 中通过 POST 请求使用 _sql
端点进行查询的示例:
执行 SQL 查询非常简单,只需通过 POST 请求发送 SQL 查询即可。以下是一个示例:
POST /_sql
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age > 25"
}
你也可以规定返回 JSON 格式:
POST /_sql?format=json
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age > 25"
}
和 Elasticsearch 一样,Easysearch 允许你通过 POST 请求直接在集群上运行 SQL 查询,并返回查询结果。以下是一些常见的 SQL 查询示例及其对应的 POST 请求:
1.查询所有文档:
POST /_sql
{
"query": "SELECT * FROM my_index"
}
2.限制返回文档数:
POST /_sql
{
"query": "SELECT * FROM my_index LIMIT 2"
}
3.按字段排序:
POST /_sql
{
"query": "SELECT * FROM my_index ORDER BY name"
}
4.筛选条件查询:
POST /_sql
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age > 25"
}
5.精确值查询:
POST /_sql
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age = 25"
}
6.查询空值:
POST /_sql
{
"query": "SELECT * FROM my_index WHERE age IS NULL"
}
7.查询唯一值:
POST /_sql
{
"query": "SELECT DISTINCT age FROM my_index"
}
8.聚合函数查询:
POST /_sql
{
"query": "SELECT MIN(age), MAX(age), AVG(age) FROM my_index"
}
9.分组统计:
POST /_sql
{
"query": "SELECT age, COUNT(*) AS CNT FROM my_index GROUP BY age"
}
多表操作的 SQL 语句
以下是多表操作的 SQL 语句及其解释:
1.子查询:
SELECT * FROM `table1` t1 WHERE t1.id IN (SELECT id FROM `table2`)
这个查询从 table1
中选择所有字段的记录,其中这些记录的 id
在 table2
表中也存在。
2.内连接:
SELECT * FROM `table1` t1 JOIN `table2` t2 ON t1.id = t2.id
这个查询进行内连接,从 table1
和 table2
中选择所有字段的记录,前提是 table1
和 table2
中 id
相等。
3.左连接:
SELECT * FROM `table1` t1 LEFT JOIN `table2` t2 ON t1.id = t2.id
这个查询进行左连接,从 table1
和 table2
中选择所有字段的记录,即使 table2
中没有匹配的记录,也会返回 table1
中的所有记录,未匹配到的部分会用 NULL 填充。
4.右连接:
SELECT * FROM `table1` t1 RIGHT JOIN `table2` t2 ON t1.id = t2.id
这个查询进行右连接,从 table1
和 table2
中选择所有字段的记录,即使 table1
中没有匹配的记录,也会返回 table2
中的所有记录,未匹配到的部分会用 NULL 填充。
假设我们有两个索引 table1
和 table2
,对应于 SQL 中的两个表。
创建索引 table1
:
PUT /`table1`
{
"mappings": {
"properties": {
"id": { "type": "integer" },
"name": { "type": "text" }
}
}
}
创建索引 table2
:
PUT /`table2`
{
"mappings": {
"properties": {
"id": { "type": "integer" },
"value": { "type": "text" }
}
}
}
导入数据到 table1
:
POST /`table1`/_bulk
{ "index": { "_id": 1 } }
{ "id": 1, "name": "Alice" }
{ "index": { "_id": 2 } }
{ "id": 2, "name": "Bob" }
{ "index": { "_id": 3 } }
{ "id": 3, "name": "Charlie" }
{ "index": { "_id": 4 } }
{ "id": 4, "name": "David" }
导入数据到 table2
:
POST /`table2`/_bulk
{ "index": { "_id": 1 } }
{ "id": 1, "value": "Value1" }
{ "index": { "_id": 2 } }
{ "id": 2, "value": "Value2" }
{ "index": { "_id": 5 } }
{ "id": 5, "value": "Value5" }
{ "index": { "_id": 6 } }
{ "id": 6, "value": "Value6" }
导入数据后,可以使用 SQL 来执行这些查询:
1.子查询:
POST /_sql
{
"query": "SELECT * FROM `table1` WHERE id IN (SELECT id FROM `table2`)"
}
2.内连接:
POST /_sql
{
"query": "SELECT * FROM `table1` t1 JOIN `table2` t2 ON t1.id = t2.id"
}
3.左连接:
POST /_sql
{
"query": "SELECT * FROM `table1` t1 LEFT JOIN `table2` t2 ON t1.id = t2.id"
}
4.右连接:
POST /_sql
{
"query": "SELECT * FROM `table1` t1 RIGHT JOIN `table2` t2 ON t1.id = t2.id"
}
效果如下:
SQL 全文检索
match
和 match_phrase
是 Easysearch 中用于全文搜索的查询类型,它们在处理文本匹配方面有不同的用途:
1.match
查询:
match
查询用于对文档进行全文搜索。- 它将搜索关键词进行分词,并对这些分词后的词项进行搜索。
- 适用于查询单个或多个字段,可以进行布尔操作(如 “AND”, “OR”)。
- 例如,搜索 “Easysearch is powerful” 会被分词为 "Easysearch ", “is”, “powerful” 三个词,然后对这三个词进行搜索,文档中包含这些词的都会被认为是匹配的。
{
"query": {
"match": {
"content": "Easysearch is powerful"
}
}
}
2.match_phrase
查询:
match_phrase
查询用于短语搜索。- 它要求搜索的短语必须在文档中出现且词的顺序相同,词之间的间隔也必须与查询中的短语相同。
- 适用于需要精确匹配短语的场景。
- 例如,搜索 “Easysearch is powerful” 时,只有包含这个确切短语的文档才会被认为是匹配的。
{
"query": {
"match_phrase": {
"content": "Easysearch is powerful"
}
}
}
总结来说,match
更灵活,用于一般的关键词搜索,而 match_phrase
则用于需要精确匹配短语的搜索。
SQL 全文检索示例
我们先造一些数据,然后使用 SQL 来进行全文检索。
批量导入数据:
POST /table3/_bulk
{ "index": { "_id": 1 } }
{ "id": 1, "test": "The quick brown fox jumps over the lazy dog" }
{ "index": { "_id": 2 } }
{ "id": 2, "test": "Foxes are wild animals" }
{ "index": { "_id": 3 } }
{ "id": 3, "test": "Jump high to catch the ball" }
{ "index": { "_id": 4 } }
{ "id": 4, "test": "Some animals can jump very high" }
{ "index": { "_id": 5 } }
{ "id": 5, "test": "The lazy dog sleeps all day" }
{ "index": { "_id": 6 } }
{ "id": 6, "test": "The foxes jump all day" }
执行全文检索的 SQL 查询:
SELECT * FROM table3;
SELECT * FROM table3 WHERE match(test, 'jump');
SELECT * FROM table3 WHERE match_phrase(test, 'foxes jump');
总结
随着数据量的不断增加,高效的数据搜索和分析变得尤为重要。Elasticsearch 以其强大的全文搜索能力和灵活的数据处理能力成为行业标准。Easysearch 作为 Elasticsearch 的优化版本,不仅继承了其强大的功能,还在性能和安全性上做了进一步的提升,为企业提供了一个高效、稳定且易于迁移的搜索引擎解决方案。通过深入了解这些技术和实践其应用,开发者和企业能够更好地利用这些工具来应对现代数据挑战,推动业务的持续发展和创新。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://infinilabs.cn/blog/2024/mastering-easysearch-syntax/
Easysearch 数据可视化和管理平台:INFINI Console 使用介绍
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2847 次浏览 • 2024-07-10 16:26
上次在《INFINI Easysearch 尝鲜 Hands on》中,我们部署了两个节点的 Easysearch,并设置了 Console 进行集群监控。今天,我们将介绍 INFINI Console 的使用。
Dashboard
INFINI Console 是一个功能强大的数据管理和分析平台,其仪表盘页面提供了直观简洁的界面,使用户能够快速了解系统状态并进行管理操作。本文将详细介绍仪表盘页面的各项功能。
仪表盘顶部显示系统的实时告警、通知和待办事项的数量,当前数据显示:
- 告警:0 条
- 通知:0 条
- 待办:0 条
在仪表盘的中心区域,用户可以看到几项关键的系统概览信息:
- 集群数量:当前有 3 个集群正在运行。
- 节点数量:系统中有 16 个节点。
- 主机数量:共有 3 台主机。
- 已用存储:系统已使用存储空间为 2.0GB。
仪表盘页面还提供了几个常用操作的快速入口,方便用户迅速访问常用功能:
- 集群注册:用户可以通过此入口快速注册新的集群。
- 数据探索:用户可以访问数据探索工具,对系统中的数据进行分析和查询。
- 告警管理:提供对告警信息的管理功能,用户可以查看和处理告警。
- 安全管理:安全管理入口帮助用户维护系统的安全设置和策略。
仪表盘右侧显示了集群的动态信息,包括最近的操作日志。例如:
- 2024-07-03 22:43:43,index medcl 在 cluster infiniLabs 中的状态更新。
- 2024-07-03 22:06:43,index medcl 在 cluster infiniLabs 中被创建。
集群管理页面
集群管理页面主要分为几个部分:顶部的功能选项卡、中部的集群列表、以及右侧的筛选和排序选项。
页面顶部的功能选项卡包括以下几项:
- Clusters (集群):显示当前系统中的所有集群。
- Nodes (节点):显示集群中的节点详细信息。
- Indices (索引):显示集群中的索引信息。
- Hosts (主机):显示系统中的主机信息。
集群列表展示了每个集群的详细信息,包括:
- 集群名称:每个集群的名称,如 “infinilabs”、“mycluster”、“INFINI_SYSTEM (JeanGrey)”。
- 集群健康状态:以颜色条的形式显示最近 14 天的集群健康状态(绿色表示健康,黄色表示有警告)。
- 节点数量:集群中包含的节点数量。
- 索引数量:集群中的索引数量。
- 分片数量:集群中的分片数量。
- 文档数量:集群中存储的文档数量。
- 磁盘使用率:集群的磁盘使用情况。
- JVM 堆内存使用率:集群的 JVM 堆内存使用情况。
- 索引速率:当前集群的索引速率(每秒索引数)。
- 搜索速率:当前集群的搜索速率(每秒搜索数)。
页面右侧提供了丰富的筛选和排序选项,可以根据以下条件筛选和排序集群:
- 健康状态 (Health Status):根据集群的健康状态筛选,如绿色(健康)和黄色(警告)。
- 分布 (Distribution):根据集群的分布类型筛选,如 “easysearch” 和 “elasticsearch”。
- 版本 (Version):根据集群使用的软件版本筛选,如 Easysearch 1.8.2 和 Elasticsearch 7.10.2。
- 区域 (Region):根据集群所在的区域筛选,如 “china” 和 “default”。
- 标签 (Tags):根据自定义标签进行筛选。
接下来分别介绍节点、索引和主机层面的信息,这些监控指标与集群层面大同小异。
节点监控
索引监控
主机监控
包括了常规的 CPU、内存、磁盘、网络的监控。
监控指标页面
监控报表页面提供了对集群运行状况的详细监控和分析功能。用户可以选择最近 15 分钟、1 小时、24 小时等不同时间范围查看数据,并手动点击刷新按钮更新数据,以获取最新的监控信息。
概览信息
显示当前集群的基本状态,包括:
- 集群名称:如 “infinilabs”。
- 在线时长:如 “3 天”。
- 集群版本:如 “1.8.2”。
- 健康状态:如 “green”。
- 节点数:如 “2”。
- 索引数:如 “38”。
- 主/总分片:如 “38/76”。
- 未分配分片:如 “0”。
- 文档数:如 “656,803”。
- 存储空间:如 “1007.2MB/385.4GB”。
- JVM 内存:如 “1023.0MB/2.0GB”。
监控报表页面还提供了多个性能指标的图表,包括:
索引吞吐 (doc/s)
- Total Indexing:总索引吞吐量。
- Primary Indexing:主分片的索引吞吐量。
查询吞吐 (query/s)
- Total Query:总查询吞吐量。
索引延迟 (ms)
- Indexing Latency:索引延迟时间。
- Delete Latency:删除操作的延迟时间。
查询延迟 (ms)
- Query Latency:查询延迟时间。
- Fetch Latency:获取操作的延迟时间。
- Scroll Latency:滚动操作的延迟时间。
点击“Advance”可以查看更多监控指标:
节点级别性能监控
包括 CPU、负载、JVM 内存、剩余使用空间及磁盘空间、集群启动时间和索引读写情况。
索引级别监控
包括集群内索引的数量、状态、主分片和副本分片数量、文档条数和占用空间。
集群动态页面
提供集群中各类事件和活动的详细记录和监控功能。
别名管理
别名管理页面提供了对索引别名的管理功能,使用户可以方便地管理和配置 Elasticsearch/EasySearch 的索引别名。
创建别名
可以通过 DSL 创建别名。例如,创建一个名为 my_index_alias 的别名指向 my_index
:
POST /_aliases
{
"actions": [
{
"add": {
"index": "my_index",
"alias": "my_index_alias"
}
}
]
}
删除别名
删除一个别名同样可以通过 REST API 实现:
POST /_aliases
{
"actions": [
{
"remove": {
"index": "my_index",
"alias": "my_index_alias"
}
}
]
}
索引轮换
索引轮换是一种常用的索引管理策略,特别适用于日志和时间序列数据的场景。通过索引轮换,用户可以在索引达到一定条件(如大小或文档数量)时,创建一个新的索引来继续存储数据,而旧的索引可以继续用于查询。
- 设置写别名:创建一个指向当前写入索引的别名,例如 current_write_index。
- 定义索引轮换条件:可以基于索引的大小、文档数量或时间来定义轮换条件。
- 索引并更新写别名指向这个新索引。
创建初始索引并设置写别名:
PUT /my_index-000001
{
"aliases": {
"current_write_index": {}
}
}
使用 /_rollover API 定义轮换条件并执行轮换:
POST /current_write_index/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 1000000
},
"settings": {
"number_of_shards": 1
},
"aliases": {
"current_write_index": {}
}
}
通过这种方式,查询操作可以透明地访问所有历史数据,而写操作总是指向最新的索引。
在 INFINI Console 中提供了可视化创建索引及别名的方式。页面右上角提供了新建按钮,用户可以通过点击该按钮创建新的索引别名,填写别名名称、关联索引、索引路由、搜索路由和过滤查询等配置。
平台监控
展示了多个关键指标的监控图表,包括:
- 健康状态 (Health):显示系统当前的健康状态。如果没有数据,则显示“暂无数据”。
- 引擎分布 (Engines):展示系统中不同搜索引擎的分布情况,例如 EasySearch 和 Elasticsearch 的比例。图表显示当前 EasySearch 占 67%,Elasticsearch 占 33%。
- 提供商 (Providers):显示系统中使用的云服务提供商信息。在示例中,所有资源都托管在 AWS 上。
- JDK 版本 (JDK):显示系统中使用的 JDK 版本信息。在示例中,所有节点都使用 JDK 版本 11.0.20。
- 磁盘使用情况 (Disk Utilization) - Top 10:显示磁盘使用率最高的前 10 个节点。在示例中,easysearch-node1 和 easysearch-node2 的磁盘使用率均为 4%。
- JVM 使用情况 (JVM Utilization) - Top 10:展示 JVM 使用率最高的前 10 个节点。在示例中,infinilabs 集群的 easysearch-node1 和 easysearch-node2 节点的 JVM 使用情况有详细的时间序列数据,显示了不同时间点的使用率变化。
我们还能够看到更多指标:
数据探索
在数据探索里,可以根据时间、字段等条件对索引或者视图下的数据进行搜索查询和分析,类似 Kibana 的 Discover。
这里可以看到集群的警报,目前集群运行良好,没有任何警报。
内部会预设一些警报规则,如下:
点进去一个请求,比如磁盘的警告,可以针对不同的使用量设置不同的警告级别和通知。
这里针对警报设置警报,可以看到现在支持很多平台,Discord、飞书、邮件、微信、Slack 以及钉钉。
点击进去可以查看,对于社交软件而言,其实是使用 Webhook 进行通知,除此之外也支持配置邮件服务器和自定义的 Webhook 进行通知。
开发工具
Console 的开发工具相当于 Kibana DevTool 的升级版,使用上基本没有大的区别,除了支持 DSL 之外,还支持多集群 Tab 切换、常用命令快速 Load、SQL 查询等。
集群连接凭证管理
可以看到连接这三个集群的凭证管理,目前都是有效的。
后台用户授权
可以添加用户以及修改 Console 管理界面的密码。目前设置了 admin 账号。
审计日志
追踪对集群的操作,捕获查看集群监控信息以及集群索引的操作。
结论
INFINI Console 的仪表盘页面集成了系统的关键信息和快捷操作入口,使用户可以高效地管理和监控系统。通过详细的概览信息、实时的告警通知、快速的功能入口和动态日志,用户能够对系统的运行状态一目了然,并快速响应各种管理需求。这个设计不仅提升了用户的工作效率,还确保了系统的安全和稳定运行。
INFINI Console 的集群管理页面提供了对系统集群的全面监控和管理功能。通过详细的集群信息展示、便捷的功能选项卡切换以及丰富的筛选和排序功能,用户可以高效地管理和监控系统中的集群状态。这不仅提升了运维效率,还确保了系统的稳定运行和高效管理。
INFINI Console 的节点管理页面提供了对集群节点的全面监控和管理功能。通过详细的节点信息展示、便捷的功能选项卡切换以及丰富的筛选和搜索功能,用户可以高效地管理和监控系统中的节点状态,从而提升运维效率,确保系统的稳定运行和高效管理。
INFINI Console 的监控报表页面提供了对集群运行状况的全面监控和分析功能。通过详细的概览信息和多个性能指标图表,用户可以高效地监控和管理集群的运行状态。这不仅提升了系统运维效率,还确保了集群的稳定运行和高效管理。
通过这些功能,INFINI Console 为用户提供了全面的系统管理工具,帮助他们高效地应对各种运维挑战,确保系统的高效、安全、稳定运行。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://blog.csdn.net/weixin_38781498/article/details/140077785
INFINI Easysearch 尝鲜 Hands on
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2611 次浏览 • 2024-07-10 14:43
INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个自主可控的轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。
Easysearch 支持原生 Elasticsearch 的 DSL 查询语法,确保原业务代码无需调整即可无缝迁移。同时,极限科技还支持 SQL 查询,为熟悉 SQL 的开发人员提供更加便捷的数据分析方式。此外,Easysearch 兼容 Elasticsearch 的 SDK 和现有索引存储格式,支持冷热架构和索引生命周期管理,确保用户能够轻松实现数据的无缝衔接。
安装
安装脚本
无论是 Linux 还是 Mac 都是这个一键脚本
curl -sSL http://get.infini.cloud | bash -s -- -p easysearch
同时也提供了二进制的安装包:
如果不想整理 JAVA 环境问题,还可以使用这个 https://release.infinilabs.com/easysearch/stable/bundle/
docker 部署
官方提供了 Docker Compose 样例,包括三个服务:
- easysearch-node1
- easysearch-node2
- console
以下是详细说明:
版本控制:
- version: '3' 表示使用 Docker Compose 文件的第 3 版格式。
服务定义:
-
easysearch-node1 和 easysearch-node2:
- 这两个服务使用相同的 Docker 镜像 infinilabs/easysearch:latest 来组成双节点的集群。
- 容器运行时使用用户和组 ID 602:602。
- 设置了 ES_JAVA_OPTS 环境变量以配置 Java 虚拟机的内存。
- ulimits 选项配置了内存锁定和文件描述符的限制,以提升性能。
- 容器内的配置、数据和日志目录通过卷映射到主机目录中,以便于数据持久化。
- 服务暴露特定端口,使外部能够访问容器中的服务。
- 两个节点均加入名为 esnet 的自定义网络中。
-
console:
- 该服务使用镜像 infinilabs/console:1.26.0-1552(该镜像没有 latest,需要手动把 latest 更改位特定的版本号)。
- 同样通过卷将数据和日志目录映射到主机。
- 暴露 9000 端口用于 Web 界面访问。
- 使用 links 功能链接到 easysearch-node1 和 easysearch-node2,简化容器之间的通信。
- 设置了时区环境变量 TZ 为 Asia/Shanghai。
网络配置:
- esnet 网络使用 bridge 驱动,提供一个隔离的网络环境,配置了特定的子网 172.24.0.0/16,以确保服务之间的网络通信。
version: '3'
services:
easysearch-node1:
user: "602:602"
image: infinilabs/easysearch:latest
container_name: easysearch-node1
hostname: easysearch-node1
environment:
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- $PWD/ezs1/config:/app/easysearch/config
- $PWD/ezs1/data:/app/easysearch/data
- $PWD/ezs1/logs:/app/easysearch/logs
ports:
- 9201:9200
- 9301:9300
networks:
- esnet
easysearch-node2:
user: "602:602"
image: infinilabs/easysearch:latest
container_name: easysearch-node2
hostname: easysearch-node2
environment:
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- $PWD/ezs2/config:/app/easysearch/config
- $PWD/ezs2/data:/app/easysearch/data
- $PWD/ezs2/logs:/app/easysearch/logs
ports:
- 9202:9200
- 9302:9300
networks:
- esnet
console:
image: infinilabs/console:1.26.0-1552
container_name: console
hostname: console
volumes:
- $PWD/console/data:/data
- $PWD/console/log:/log
networks:
- esnet
ports:
- 9000:9000
links:
- easysearch-node1:es1
- easysearch-node2:es2
environment:
- TZ=Asia/Shanghai
networks:
esnet:
driver: bridge
ipam:
config:
- subnet: 172.24.0.0/16
尽管在这里官方提供了详细的命令,完全可以使用这个 docker-compose up 来进行替代。其他的脚本解释如下:
init.sh
#!/bin/bash
# 获取当前脚本所在目录的绝对路径
CUR_DIR=$(cd $(dirname $0); pwd)
# 创建必要的目录结构
mkdir -p $CUR_DIR/console/{data,log}
mkdir -p $CUR_DIR/{ezs1,ezs2}/{data,logs}
# 设置目录的拥有者和权限
chown -R 1000:1000 $CUR_DIR/console
chown -R 602:602 $CUR_DIR/{ezs1,ezs2}
chmod -R 0600 $CUR_DIR/{ezs1,ezs2}/config
# 设置 config 目录的子目录权限
find $CUR_DIR/{ezs1,ezs2}/config -type d -print0 | xargs -0 chmod 750
reset.sh
#!/bin/bash
# 获取当前脚本所在目录的绝对路径
CUR_DIR=$(cd $(dirname $0); pwd)
# 定义确认函数
function confirm() {
display_str=$1
default_ans=$2
if [[ $default_ans == 'y/N' ]]; then
must_match='[yY]'
else
must_match='[nN]'
fi
read -p"${display_str} [${default_ans}]:" ans
[[ $ans == $must_match ]]
}
# 提示用户确认删除所有数据
confirm "RISK WARN: Delete all data!!!" 'y/N' && echo || exit
# 删除 console、ezs1 和 ezs2 的数据和日志文件
rm -rvf $CUR_DIR/console/{data,log}/*
rm -rvf $CUR_DIR/{ezs1,ezs2}/{data,logs}/*
start.sh
#!/bin/bash
# 使用 Docker Compose 启动 ezs2 项目中的服务
docker-compose -p ezs2 up
stop.sh
#!/bin/bash
# 使用 Docker Compose 关闭并移除 ezs2 项目中的所有服务
docker-compose -p ezs2 down
在我的电脑中,可以看到成功启动的容器。
https://infinilabs.cn/docs/latest/easysearch/getting-started/install/docker-compose/
Console 连接
设置集群连接参数,比如域名端口,用户名密码。
初始化,这里会新建索引,写一些 sample 数据。
设置后台管理的密码,后期使用这个登录控制台。
检查配置,完成集群关联。
这个是后台管理界面,除了用户名密码之外,也支持单点登录:
跨引擎、跨版本、跨集群 独一份!
使用自带的面板进行查看节点数量:
同时也支持 REST 风格的 API 来进行查询。
接下来使用 Console 连接 Amazon 的 OpenSearch:
同样是输入集群的 URL,用户名和密码。
然后可以拿到集群的信息,比如地址,版本号,集群状态,节点数量。
最后看到连接成功的信息。
我们可以在集群管理中看到 Easysearch 的集群和我们刚刚添加的 OpenSearch 集群。
是否开源?目前还没有开放源代码。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://blog.csdn.net/weixin_38781498/article/details/140077785
使用 AWS EKS 部署 Easysearch
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2721 次浏览 • 2024-08-15 15:47
随着企业对数据搜索和分析需求的增加,高效的搜索引擎解决方案变得越来越重要。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:国产搜索型数据库的崛起与未来展望
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 3350 次浏览 • 2024-08-14 12:17
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 征文活动
作者:李家兴
玩转 Easysearch 语法
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2936 次浏览 • 2024-07-11 12:11
什么是 Easysearch
Elasticsearch 是一个基于 Apache Lucene 的开源分布式搜索和分析引擎,它被广泛应用于全文搜索、结构化搜索和分析等多种场景中。作为 Elasticsearch 的国产化替代方案,Easysearch 不仅保持了与原生 Elasticsearch 的高度兼容性,还在功能、性能、稳定性和扩展性方面进行了全面提升。对于开发团队来说,从 Elasticsearch 切换到 Easysearch 不需要做任何业务代码的调整,确保了无缝衔接和平滑迁移。
Easysearch 是基于 Elasticsearch 7.10.2 开源版本二次开发,所以支持 Elasticsearch 原始的 Query DSL 语法,基本的 SQL 语法,并且兼容现有 Elasticsearch 的 SDK,使得应用无需修改代码即可进行迁移。其平滑的迁移特性,如基于网关的无缝跨版本迁移与升级,提供了随时安全回退的能力。
在之前的文章中,我们已经介绍了 Easysearch 的搭建 和 可视化工具的使用,今天我们将探讨 Easysearch 集群的基本概念和常用的 API。
Easysearch 集群的核心概念
Easysearch 集群由以下几个核心概念构成:
- 节点(Node):集群中的单个服务器,负责存储数据并参与集群的索引和搜索功能。
- 集群(Cluster):由一个或多个节点组成,拥有唯一的集群名,协同完成数据索引和查询任务。
- 索引(Index):存储相关数据的容器,类似于关系数据库中的数据库,一个索引包含多个文档。
- 文档(Document):索引中的基本数据单位,相当于关系数据库中的行。
- 字段(Field):文档中的一个属性,相当于数据库中的列。
- 分片(Shard):为了提高性能和扩展性,索引可以被分割成多个分片,每个分片是索引的一个部分。
- 副本(Replica):分片的副本,用于提高数据的可靠性和在节点出现故障时的可用性。
通过多个 API,例如 _cluster/health
和 _cluster/stats
,用户可以轻松查看集群的健康状态和详细信息,这些信息对于维护和优化 Easysearch 集群至关重要。
无论是在性能的提升,还是在功能的兼容性方面,Easysearch 都为用户提供了一个强大的搜索引擎平台,让从 Elasticsearch 到 Easysearch 的迁移变得无缝且高效。掌握其核心概念和 API 的使用,将帮助开发者更好地利用这些工具来构建和优化他们的搜索解决方案。
查看集群信息
在 Easysearch 中,可以通过多个 API 来查看集群的各种信息,包括集群的健康状况、节点信息和索引状态。以下是一些常用的查看集群信息的 API 和示例:
查看集群健康状况
_cluster/health
API 可以查看集群的健康状态,包括集群是否处于正常状态、节点数量、分片状态等。
GET /_cluster/health
示例响应:
{
"cluster_name": "my_cluster",
"status": "green",
"timed_out": false,
"number_of_nodes": 3,
"number_of_data_nodes": 3,
"active_primary_shards": 5,
"active_shards": 10,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0,
"delayed_unassigned_shards": 0,
"number_of_pending_tasks": 0,
"number_of_in_flight_fetch": 0,
"task_max_waiting_in_queue_millis": 0,
"active_shards_percent_as_number": 100.0
}
查看集群状态
_cluster/stats
API 可以查看集群的详细状态,包括索引、节点、分片等信息。
GET /_cluster/stats
示例响应:
{
"cluster_name": "my_cluster",
"status": "green",
"indices": {
"count": 10,
"shards": {
"total": 20,
"primaries": 10,
"replication": 1.0,
"index": {
"shards": {
"min": 1,
"max": 5,
"avg": 2.0
}
}
}
},
"nodes": {
"count": {
"total": 3,
"data": 3,
"coordinating_only": 0,
"master": 1,
"ingest": 2
},
"os": {
"available_processors": 12,
"allocated_processors": 12
},
"process": {
"cpu": {
"percent": 10
},
"open_file_descriptors": {
"min": 100,
"max": 300,
"avg": 200
}
}
}
}
查看节点信息
_nodes
API 可以查看集群中节点的详细信息,包括节点角色、IP 地址、内存使用情况等。
GET /_nodes
示例响应:
{
"cluster_name": "my_cluster",
"nodes": {
"node_id_1": {
"name": "node_1",
"transport_address": "192.168.1.1:9300",
"host": "192.168.1.1",
"ip": "192.168.1.1",
"roles": ["master", "data", "ingest"],
"os": {
"available_processors": 4,
"allocated_processors": 4
},
"process": {
"cpu": {
"percent": 10
},
"open_file_descriptors": 200
}
},
"node_id_2": {
"name": "node_2",
"transport_address": "192.168.1.2:9300",
"host": "192.168.1.2",
"ip": "192.168.1.2",
"roles": ["data"],
"os": {
"available_processors": 4,
"allocated_processors": 4
},
"process": {
"cpu": {
"percent": 15
},
"open_file_descriptors": 150
}
}
}
}
查看索引状态
_cat/indices
API 可以查看集群中所有索引的状态,包括文档数、存储大小、分片数等信息。
GET /_cat/indices?v
示例响应:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open index_1 SxNUd84vRl6QH5P7g0T4Vg 1 1 0 0 230b 230b
green open index_2 NxEYib4yToCnA1PpQ8P4Xw 5 1 100 1 10mb 5mb
这些 API 可以帮助你全面了解 Easysearch 集群的状态和健康状况,从而更好地管理和维护集群。
增删改查操作
在 Easysearch 中,增删改查操作是管理数据和索引的基本功能。以下是如何使用这些操作的详细示例。
创建索引
创建一个新的索引,并指定分片和副本的数量:
PUT /my_index
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
删除索引
删除一个不再需要的索引:
DELETE /my_index
添加文档
通过 POST 或 PUT 请求向索引中添加文档:
POST /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
PUT /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
POST
和 PUT
方法用于不同的操作,尽管它们都可以用于添加或更新文档,但它们的行为有所不同。
POST /my_index/_doc/1
方法用于创建或替换一个文档。如果指定的文档 ID 已经存在,POST
请求将更新整个文档(不会合并字段)。如果文档 ID 不存在,它将创建一个新的文档。
POST /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
PUT /my_index/_doc/1
方法通常用于创建一个新的文档,或者完全替换一个已存在的文档。与 POST
类似,如果指定的文档 ID 已经存在,PUT
请求将替换整个文档。
PUT /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
1.使用场景:
POST
:更适合用于添加或部分更新文档,即使文档 ID 已经存在。PUT
:更适合用于创建或完全替换文档。
2.ID 自动生成:
POST
请求可以不提供文档 ID,此时 Easysearch 会自动生成一个文档 ID。PUT
请求必须提供文档 ID,如果未提供,则会返回错误。
3.部分更新:
POST
请求可以用于部分更新(通过_update
API)。PUT
请求用于完全替换文档,不支持部分更新。
如果文档 ID 已经存在,POST
和 PUT
都会覆盖整个文档,并且效果是一样的。但是,通常 POST
用于提交数据,而 PUT
用于上传和替换资源。
1.使用 POST
方法添加或更新文档:
POST /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
2.使用 PUT
方法添加或更新文档:
PUT /my_index/_doc/1
{
"name": "John Doe",
"age": 30,
"occupation": "Engineer"
}
在这两个示例中,结果都是在索引 my_index
中创建或更新文档 ID 为 1
的文档。无论使用 POST
还是 PUT,如果文档 ID 已存在,都会覆盖原有的文档内容。
新建文档
使用 _create
方法新建文档,如果文档已经存在则返回错误:
PUT /my_index/_create/1
{
"a": 1
}
如果尝试新建已存在的文档,将会出现如下错误:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [1])",
"index_uuid": "1xWdHLTaTm6l6HbqACaIEA",
"shard": "0",
"index": "my_index"
}
],
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [1])",
"index_uuid": "1xWdHLTaTm6l6HbqACaIEA",
"shard": "0",
"index": "my_index"
},
"status": 409
}
获取文档
通过 ID 获取文档的详细信息:
GET /my_index/_doc/1
更新文档
更新文档的特定字段,保留原有字段:
POST /my_index/_update/1
{
"doc": {
"age": 31
}
}
删除文档
通过 ID 删除指定的文档:
DELETE /my_index/_doc/1
查询所有文档
查询索引中的所有文档:
GET /my_index/_search
{
"query": {
"match_all": {}
}
}
这个是 《老杨玩搜索》中总结的图,可以作为“小抄”来记忆:
批量操作 (_bulk API)
_bulk API
用于在一次请求中执行多个索引、删除和更新操作,这对于批量处理大规模数据非常有用,可以显著提高性能和效率。以下是 _bulk API
的基本使用示例:
POST /my_index/_bulk
{ "index": { "_id": "1" } }
{ "name": "John Doe", "age": 30, "occupation": "Engineer" }
{ "index": { "_id": "2" } }
{ "name": "Jane Doe", "age": 25, "occupation": "Designer" }
{ "update": { "_id": "1" } }
{ "doc": { "age": 31 } }
_bulk API
的请求体由多个操作和文档组成。每个操作行包含一个动作描述行和一个可选的源文档行。动作描述行指明了操作的类型(例如,index、create、delete、update)以及操作的元数据。源文档行则包含了实际的数据。
每个操作之间需要用换行符分隔,并且请求体最后必须以换行符结尾。
POST /_bulk
{ "index": { "_index": "a", "_id": "1" } }
{ "name": "John Doe", "age": 30, "occupation": "Engineer" }
{ "index": { "_index": "b", "_id": "2" } }
{ "name": "Jane Doe", "age": 25, "occupation": "Designer" }
{ "update": { "_index": "a", "_id": "1" } }
{ "doc": { "age": 31 } }
分词器
在 Easysearch 中,分词器(Analyzer)用于将文本分解为词项(terms),是全文搜索和文本分析的基础。分词器通常由字符过滤器(Character Filters)、分词器(Tokenizer)和词项过滤器(Token Filters)组成。以下是关于分词器的详细介绍:
1.字符过滤器(Character Filters):在分词之前对文本进行预处理。例如,去除 HTML 标签,替换字符等。
2.分词器(Tokenizer):将文本分解为词项(tokens)。这是分词过程的核心。
3.词项过滤器(Token Filters):对词项进行处理,如小写化、去除停用词、词干提取等。
只有 text 字段支持全文检索,返回的结果根据相似度打分,我们一起看下
POST /index/_mapping
{
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
.POST /index/_mapping
- 这个部分表示要向名为
index
的索引添加或更新映射设置。
2.“properties”
properties
定义了索引中文档的字段结构。在这个例子中,定义了一个名为content
的字段。
3.“content”
- 定义了名为
content
的字段。
4.“type”: “text”
type
字段指定 content
字段的数据类型为 text
。text
类型适用于需要分词和全文搜索的字段。
5.“analyzer”: “ik_max_word”
analyzer
字段指定索引时使用的分词器为ik_max_word
。ik_max_word
是 IK 分词器中的一种,它会尽可能多地将文本分解为更多的词项。
6.“search_analyzer”: “ik_smart”
search_analyzer
字段指定搜索时使用的分词器为ik_smart
。ik_smart
是 IK 分词器中的另一种,它会更智能地进行分词,以提高搜索的准确性。
当然,在设置这个 mapping 的时候可以使用同样的分词器,也可以使用不同的分词器。这里介绍下 IK 分词器:
- IK 分词器是一种中文分词器,适用于中文文本的分词。IK 分词器有两种分词模式:
ik_max_word
和ik_smart
。ik_max_word
:将文本尽可能多地切分成词项,适用于需要更高召回率的场景。ik_smart
:进行最智能的分词,适用于需要更高精度的搜索场景。
这个 DSL 的设置意味着,在向这个索引添加或更新文档时,content
字段的文本会使用ik_max_word
分词器进行分词处理,以确保文本被尽可能多地切分成词项。而在搜索时,content
字段的文本会使用ik_smart
分词器进行分词处理,以提高搜索的准确性和相关性。
以下是关于 standard,ik_smart,ik_max_word 这几个分词器的对比:
GET /_analyze
{
"tokenizer": "standard",
"text": "我,机器人"
}
GET /_analyze
{
"tokenizer": "ik_smart",
"text": "我,机器人"
}
GET /_analyze
{
"tokenizer": "ik_max_word",
"text": "我,机器人"
}
结果如下:
# GET /_analyze (standard)
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "机",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "器",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "人",
"start_offset": 4,
"end_offset": 5,
"type": "<IDEOGRAPHIC>",
"position": 3
}
]
}
# GET /_analyze(ik_smart)
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "机器人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 1
}
]
}
# GET /_analyze (ik_max_word)
{
"tokens": [
{
"token": "我",
"start_offset": 0,
"end_offset": 1,
"type": "CN_CHAR",
"position": 0
},
{
"token": "机器人",
"start_offset": 2,
"end_offset": 5,
"type": "CN_WORD",
"position": 1
},
{
"token": "机器",
"start_offset": 2,
"end_offset": 4,
"type": "CN_WORD",
"position": 2
},
{
"token": "人",
"start_offset": 4,
"end_offset": 5,
"type": "CN_CHAR",
"position": 3
}
]
}
如果使用了不存在的分词器会出现这个错误。
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "failed to find global tokenizer under [simple]"
}
],
"type": "illegal_argument_exception",
"reason": "failed to find global tokenizer under [simple]"
},
"status": 400
}
精确搜索/正则表达式搜索/通配符
在 Easysearch 中,精确搜索、正则表达式搜索和通配符搜索是三种不同的搜索方式,各有其应用场景和特点:
1.精确搜索 (Term Query):
- 精确搜索用于查找与搜索词完全匹配的文档。
- 不进行分词处理,通常用于关键字、ID、标签等字段的精确匹配。
- 适用于结构化数据或不需要分词的字段(如数字、日期、布尔值等)。
{
"query": {
"term": {
"status": "active"
}
}
}
2.正则表达式搜索 (Regexp Query):
- 正则表达式搜索用于基于正则表达式模式匹配的文档搜索。
- 支持复杂的字符串匹配模式,但性能可能较低,特别是当数据量较大时。
- 适用于需要灵活且复杂匹配条件的搜索。
{
"query": {
"regexp": {
"content": "Easysearch .*powerful"
}
}
}
3.通配符搜索 (Wildcard Query):
- 通配符搜索用于通过通配符模式匹配文档。
- 支持 ?(匹配单个字符)和 *(匹配零个或多个字符)。
- 性能相对较差,因为通配符搜索可能需要扫描大量数据。
{
"query": {
"wildcard": {
"username": "john*"
}
}
}
- 精确搜索:用于需要绝对匹配特定词语或不需要分词的字段。例如,查找特定用户 ID 或状态。
- 正则表达式搜索:用于需要复杂字符串模式匹配的场景,但要谨慎使用,避免性能问题。
- 通配符搜索:用于简单模式匹配,但同样需要注意性能影响,尽量避免在大数据集上频繁使用。
接下来看这个例子,我们将使用批量导入数据,然后进行几种不同类型的查询,包括精确查询、通配符查询和正则表达式查询。
POST /users/_bulk
{ "index": { "_index": "users", "_id": 1 }}
{ "username": "john_doe", "status": "active", "email": "john.doe@example.com", "bio": "John loves Easysearch and open-source technologies." }
{ "index": { "_index": "users", "_id": 2 }}
{ "username": "jane_doe", "status": "inactive", "email": "jane.doe@example.com", "bio": "Jane is a data scientist working with big data." }
{ "index": { "_index": "users", "_id": 3 }}
{ "username": "john_smith", "status": "active", "email": "john.smith@example.com", "bio": "John enjoys hiking and nature." }
{ "index": { "_index": "users", "_id": 4 }}
{ "username": "alice_jones", "status": "active", "email": "alice.jones@example.com", "bio": "Alice is a software engineer specialized in JavaScript." }
{ "index": { "_index": "users", "_id": 5 }}
{ "username": "bob_jones", "status": "inactive", "email": "bob.jones@example.com", "bio": "Bob is an AI enthusiast and machine learning expert." }
1.精确查询:查询状态为 “active” 的用户。
GET /users/_search
{
"query": {
"term": {
"status": "active"
}
}
}
2.通配符查询:查询 bio 字段中包含 “John” 开头的词。
GET /users/_search
{
"query": {
"wildcard": {
"bio": "John*"
}
}
}
3.正则表达式查询:查询用户名以 “john” 开头的用户
GET /users/_search
{
"query": {
"regexp": {
"username": "john.*"
}
}
}
通过这些例子,你可以看到如何在 Easysearch 中使用批量导入数据,然后使用各种查询方法来检索特定条件的数据。这些查询方法可以帮助你高效地搜索和分析数据,以满足不同的业务需求。
这里同样是《老杨玩搜索》中总结的“小抄”来方便记忆:
多字段查询
在 Easysearch 中,多字段查询允许您在多个字段上同时执行搜索,以获取更精确的结果。最常用的多字段查询类型是 multi_match
查询。multi_match
查询是 match
查询的扩展,能够在多个字段中搜索指定的关键词。
multi_match
查询支持多种匹配模式,如 best_fields
、most_fields
、cross_fields
、phrase
和 phrase_prefix
。以下是各模式的简要介绍:
- best_fields:默认模式,选择匹配度最高的字段。
- most_fields:计算每个字段的匹配度,然后将匹配度相加。
- cross_fields:将多个字段视为一个字段进行匹配,适用于分析文本被分散到多个字段的情况。
- phrase:短语匹配,确保词项顺序与查询相同。
- phrase_prefix:短语前缀匹配,允许词项的部分匹配。
我们先导入一些示例数据到一个索引 documents
中:
POST /documents/_bulk
{ "index": { "_id": 1 } }
{ "title": "Easysearch Guide", "content": "This is an introductory guide to Easysearch ." }
{ "index": { "_id": 2 } }
{ "title": "Advanced Easysearch ", "content": "This guide covers advanced topics in Easysearch ." }
{ "index": { "_id": 3 } }
{ "title": "Easysearch in Action", "content": "Practical guide to Easysearch usage." }
{ "index": { "_id": 4 } }
{ "title": "Learning Easysearch ", "content": "Beginner's guide to learning Easysearch ." }
我们将使用 multi_match
查询在 title
和 content
字段中同时搜索关键词。
1.基本 multi_match 查询:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "guide",
"fields": ["title", "content"]
}
}
}
2.指定匹配模式为 best_fields:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "guide",
"fields": ["title", "content"],
"type": "best_fields"
}
}
}
3.指定匹配模式为 most_fields:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "guide",
"fields": ["title", "content"],
"type": "most_fields"
}
}
}
4.使用 cross_fields 模式:
POST /documents/_search
{
"query": {
"multi_match": {
"query": "Easysearch guide",
"fields": ["title", "content"],
"type": "cross_fields"
}
}
}
5.短语匹配 (phrase):
POST /documents/_search
{
"query": {
"multi_match": {
"query": "introductory guide",
"fields": ["title", "content"],
"type": "phrase"
}
}
}
6.短语前缀匹配 (phrase_prefix):
POST /documents/_search
{
"query": {
"multi_match": {
"query": "introductory gui",
"fields": ["title", "content"],
"type": "phrase_prefix"
}
}
}
- query:要搜索的关键词或短语。
- fields:要搜索的字段列表,可以包含一个或多个字段。
- type:指定匹配模式,默认为 best_fields。
使用 multi_match
查询,您可以在多个字段上同时执行搜索,获得更精确和全面的结果。通过指定不同的匹配模式,您可以调整查询行为以满足特定的搜索需求。无论是基本关键词匹配、短语匹配还是跨字段匹配,multi_match
查询都提供了强大的功能来处理复杂的搜索场景。
除此之外,还可以使用 boost 参数用于调整特定字段的权重,从而影响搜索结果的相关性评分。multi_match
查询支持为不同字段设置不同的 boost 值,以便在搜索结果中优先显示某些字段的匹配项。
布尔查询
布尔查询是 Easysearch 中非常强大且灵活的一种查询方式,它允许用户通过组合多个查询条件来实现复杂的搜索需求。布尔查询使用 bool
查询类型,可以包含以下几种子句:must
、filter
、must_not
和 should
。每种子句都有其特定的用途和语义。
1.must:
- 包含在
must
数组中的查询条件必须匹配,类似于逻辑上的 AND 操作。 - 如果有多个条件,所有条件都必须满足,文档才会被包含在结果集中。
2.filter:
- 包含在
filter
数组中的查询条件必须匹配,但它不会影响评分。 filter
子句通常用于对性能要求较高的过滤操作,因为它不计算相关性评分。
3.must_not:
- 包含在
must_not
数组中的查询条件必须不匹配,类似于逻辑上的 NOT 操作。 - 如果有任何一个条件匹配,文档就会被排除在结果集之外。
4.should:
- 包含在
should
数组中的查询条件至少匹配一个。 - 如果布尔查询中没有
must
子句,则至少要匹配一个should
子句。 should
子句在计算相关性评分时也有影响。
5.minimum_should_match:
- 指定
should
子句中至少需要满足的条件数量。
首先,我们需要创建一个名为 books
的索引,并定义它的映射(mappings)。映射用于指定每个字段的数据类型。在这个例子中,类别
和书名
字段都被定义为 keyword
类型,这是因为我们需要进行精确匹配查询。
PUT /books
{
"mappings": {
"properties": {
"类别": { "type": "keyword" },
"书名": { "type": "keyword" }
}
}
}
接下来,我们使用批量操作(bulk API)将一些示例数据导入到 books
索引中。这些数据包括不同类别的书籍。
POST /books/_bulk
{ "index": { "_id": 1 } }
{ "类别": "文学", "书名": "我的阿勒泰" }
{ "index": { "_id": 2 } }
{ "类别": "文学", "书名": "平凡的世界" }
{ "index": { "_id": 3 } }
{ "类别": "科学", "书名": "时间简史" }
{ "index": { "_id": 4 } }
{ "类别": "文学", "书名": "百年孤独" }
{ "index": { "_id": 5 } }
{ "类别": "文学", "书名": "红楼梦" }
现在,我们使用布尔查询来搜索类别
为“文学”并且书名
为“我的阿勒泰”的文档。这里使用的是 must
子句,表示查询结果必须满足所有条件。
POST /books/_search
{
"query": {
"bool": {
"must": [
{ "term": { "类别": "文学" } },
{ "term": { "书名": "我的阿勒泰" } }
]
}
}
}
我们还可以使用 filter
子句来执行相同的查询。filter
子句用于过滤文档,且不会影响文档的相关性评分。这在不需要计算相关性评分时可以提高查询性能。
POST /books/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "类别": "文学" } },
{ "term": { "书名": "我的阿勒泰" } }
]
}
}
}
当我们执行上述查询时,期望返回的结果是 books
索引中类别为“文学”且书名为“我的阿勒泰”的文档。无论是使用 must
还是 filter
子句,结果应该都是:
{
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"hits": [
{
"_index": "books",
"_id": "1",
"_source": {
"类别": "文学",
"书名": "我的阿勒泰"
}
}
]
}
}
POST /_search
{
"query": {
"bool": {
"must": [
{ "term": { "user.id": "kimchy" } }
],
"filter": [
{ "term": { "tags": "production" } }
],
"must_not": [
{
"range": {
"age": { "gte": 10, "lte": 20 }
}
}
],
"should": [
{ "term": { "tags": "env1" } },
{ "term": { "tags": "deployed" } }
],
"minimum_should_match": 1,
"boost": 1.0
}
}
}
must
子句:必须匹配的条件,文档必须包含user.id
为kimchy
。filter
子句:过滤条件,文档必须包含tags
为production
,但不会影响评分。must_not
子句:不匹配的条件,文档的age
字段不能在 10 到 20 之间。should
子句:可选匹配条件,至少需要匹配一个should
子句中的条件。这里要求tags
字段匹配env1
或deployed
。minimum_should_match
:至少需要匹配一个 should 子句中的条件。boost
:提升查询的整体评分。
为了展示这个 DSL ,我们需要创建一个索引并导入一些数据。假设我们要在 Easysearch 中创建一个索引 users
,并插入一些测试数据。
创建索引
PUT /users
{
"mappings": {
"properties": {
"user.id": { "type": "keyword" },
"tags": { "type": "keyword" },
"age": { "type": "integer" }
}
}
}
批量导入数据
POST /users/_bulk
{ "index": { "_id": 1 } }
{ "user.id": "kimchy", "tags": ["production", "env1"], "age": 25 }
{ "index": { "_id": 2 } }
{ "user.id": "kimchy", "tags": ["production"], "age": 15 }
{ "index": { "_id": 3 } }
{ "user.id": "kimchy", "tags": ["deployed"], "age": 30 }
{ "index": { "_id": 4 } }
{ "user.id": "kimchy", "tags": ["test"], "age": 35 }
{ "index": { "_id": 5 } }
{ "user.id": "other", "tags": ["production"], "age": 25 }
接下来执行布尔查询:
POST /users/_search
{
"query": {
"bool": {
"must": [
{ "term": { "user.id": "kimchy" } }
],
"filter": [
{ "term": { "tags": "production" } }
],
"must_not": [
{
"range": {
"age": { "gte": 10, "lte": 20 }
}
}
],
"should": [
{ "term": { "tags": "env1" } },
{ "term": { "tags": "deployed" } }
],
"minimum_should_match": 1,
"boost": 1.0
}
}
}
根据以上查询,预期返回的结果应该符合以下条件:
user.id
必须是kimchy
(由must
子句决定)。tags
必须包含production
(由filter
子句决定)。age
字段不在 10 到 20 之间(由must_not
子句决定)。tags
字段中至少包含env1
或deployed
中的一个(由should
子句和minimum_should_match
参数决定)。
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.3769134,
"hits": [
{
"_index": "users",
"_type": "_doc",
"_id": "1",
"_score": 1.3769134,
"_source": {
"user.id": "kimchy",
"tags": ["production", "env1"],
"age": 25
}
}
]
}
}
SQL 搜索
Easysearch 直接支持 SQL 查询,无需额外安装插件,同时兼容 Elasticsearch 的 SQL 调用方式,还可以直接编写原生 SQL 查询。
以下是一些测试 SQL 语句的示例:
SELECT * FROM my_index;
SELECT * FROM my_index LIMIT 2;
SELECT * FROM my_index ORDER BY name;
SELECT name AS full_name, age FROM my_index WHERE age > 25;
SELECT name AS full_name, age FROM my_index WHERE age = 25;
SELECT * FROM my_index WHERE age IS NULL;
SELECT DISTINCT age FROM my_index;
SELECT MIN(age), MAX(age), AVG(age) FROM my_index;
SELECT age, COUNT(*) AS CNT FROM my_index GROUP BY age;
使用 Easysearch 执行 SQL 查询
Easysearch 提供了对直接使用 SQL 查询的支持。以下是如何在 Easysearch 中通过 POST 请求使用 _sql
端点进行查询的示例:
执行 SQL 查询非常简单,只需通过 POST 请求发送 SQL 查询即可。以下是一个示例:
POST /_sql
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age > 25"
}
你也可以规定返回 JSON 格式:
POST /_sql?format=json
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age > 25"
}
和 Elasticsearch 一样,Easysearch 允许你通过 POST 请求直接在集群上运行 SQL 查询,并返回查询结果。以下是一些常见的 SQL 查询示例及其对应的 POST 请求:
1.查询所有文档:
POST /_sql
{
"query": "SELECT * FROM my_index"
}
2.限制返回文档数:
POST /_sql
{
"query": "SELECT * FROM my_index LIMIT 2"
}
3.按字段排序:
POST /_sql
{
"query": "SELECT * FROM my_index ORDER BY name"
}
4.筛选条件查询:
POST /_sql
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age > 25"
}
5.精确值查询:
POST /_sql
{
"query": "SELECT name AS full_name, age FROM my_index WHERE age = 25"
}
6.查询空值:
POST /_sql
{
"query": "SELECT * FROM my_index WHERE age IS NULL"
}
7.查询唯一值:
POST /_sql
{
"query": "SELECT DISTINCT age FROM my_index"
}
8.聚合函数查询:
POST /_sql
{
"query": "SELECT MIN(age), MAX(age), AVG(age) FROM my_index"
}
9.分组统计:
POST /_sql
{
"query": "SELECT age, COUNT(*) AS CNT FROM my_index GROUP BY age"
}
多表操作的 SQL 语句
以下是多表操作的 SQL 语句及其解释:
1.子查询:
SELECT * FROM `table1` t1 WHERE t1.id IN (SELECT id FROM `table2`)
这个查询从 table1
中选择所有字段的记录,其中这些记录的 id
在 table2
表中也存在。
2.内连接:
SELECT * FROM `table1` t1 JOIN `table2` t2 ON t1.id = t2.id
这个查询进行内连接,从 table1
和 table2
中选择所有字段的记录,前提是 table1
和 table2
中 id
相等。
3.左连接:
SELECT * FROM `table1` t1 LEFT JOIN `table2` t2 ON t1.id = t2.id
这个查询进行左连接,从 table1
和 table2
中选择所有字段的记录,即使 table2
中没有匹配的记录,也会返回 table1
中的所有记录,未匹配到的部分会用 NULL 填充。
4.右连接:
SELECT * FROM `table1` t1 RIGHT JOIN `table2` t2 ON t1.id = t2.id
这个查询进行右连接,从 table1
和 table2
中选择所有字段的记录,即使 table1
中没有匹配的记录,也会返回 table2
中的所有记录,未匹配到的部分会用 NULL 填充。
假设我们有两个索引 table1
和 table2
,对应于 SQL 中的两个表。
创建索引 table1
:
PUT /`table1`
{
"mappings": {
"properties": {
"id": { "type": "integer" },
"name": { "type": "text" }
}
}
}
创建索引 table2
:
PUT /`table2`
{
"mappings": {
"properties": {
"id": { "type": "integer" },
"value": { "type": "text" }
}
}
}
导入数据到 table1
:
POST /`table1`/_bulk
{ "index": { "_id": 1 } }
{ "id": 1, "name": "Alice" }
{ "index": { "_id": 2 } }
{ "id": 2, "name": "Bob" }
{ "index": { "_id": 3 } }
{ "id": 3, "name": "Charlie" }
{ "index": { "_id": 4 } }
{ "id": 4, "name": "David" }
导入数据到 table2
:
POST /`table2`/_bulk
{ "index": { "_id": 1 } }
{ "id": 1, "value": "Value1" }
{ "index": { "_id": 2 } }
{ "id": 2, "value": "Value2" }
{ "index": { "_id": 5 } }
{ "id": 5, "value": "Value5" }
{ "index": { "_id": 6 } }
{ "id": 6, "value": "Value6" }
导入数据后,可以使用 SQL 来执行这些查询:
1.子查询:
POST /_sql
{
"query": "SELECT * FROM `table1` WHERE id IN (SELECT id FROM `table2`)"
}
2.内连接:
POST /_sql
{
"query": "SELECT * FROM `table1` t1 JOIN `table2` t2 ON t1.id = t2.id"
}
3.左连接:
POST /_sql
{
"query": "SELECT * FROM `table1` t1 LEFT JOIN `table2` t2 ON t1.id = t2.id"
}
4.右连接:
POST /_sql
{
"query": "SELECT * FROM `table1` t1 RIGHT JOIN `table2` t2 ON t1.id = t2.id"
}
效果如下:
SQL 全文检索
match
和 match_phrase
是 Easysearch 中用于全文搜索的查询类型,它们在处理文本匹配方面有不同的用途:
1.match
查询:
match
查询用于对文档进行全文搜索。- 它将搜索关键词进行分词,并对这些分词后的词项进行搜索。
- 适用于查询单个或多个字段,可以进行布尔操作(如 “AND”, “OR”)。
- 例如,搜索 “Easysearch is powerful” 会被分词为 "Easysearch ", “is”, “powerful” 三个词,然后对这三个词进行搜索,文档中包含这些词的都会被认为是匹配的。
{
"query": {
"match": {
"content": "Easysearch is powerful"
}
}
}
2.match_phrase
查询:
match_phrase
查询用于短语搜索。- 它要求搜索的短语必须在文档中出现且词的顺序相同,词之间的间隔也必须与查询中的短语相同。
- 适用于需要精确匹配短语的场景。
- 例如,搜索 “Easysearch is powerful” 时,只有包含这个确切短语的文档才会被认为是匹配的。
{
"query": {
"match_phrase": {
"content": "Easysearch is powerful"
}
}
}
总结来说,match
更灵活,用于一般的关键词搜索,而 match_phrase
则用于需要精确匹配短语的搜索。
SQL 全文检索示例
我们先造一些数据,然后使用 SQL 来进行全文检索。
批量导入数据:
POST /table3/_bulk
{ "index": { "_id": 1 } }
{ "id": 1, "test": "The quick brown fox jumps over the lazy dog" }
{ "index": { "_id": 2 } }
{ "id": 2, "test": "Foxes are wild animals" }
{ "index": { "_id": 3 } }
{ "id": 3, "test": "Jump high to catch the ball" }
{ "index": { "_id": 4 } }
{ "id": 4, "test": "Some animals can jump very high" }
{ "index": { "_id": 5 } }
{ "id": 5, "test": "The lazy dog sleeps all day" }
{ "index": { "_id": 6 } }
{ "id": 6, "test": "The foxes jump all day" }
执行全文检索的 SQL 查询:
SELECT * FROM table3;
SELECT * FROM table3 WHERE match(test, 'jump');
SELECT * FROM table3 WHERE match_phrase(test, 'foxes jump');
总结
随着数据量的不断增加,高效的数据搜索和分析变得尤为重要。Elasticsearch 以其强大的全文搜索能力和灵活的数据处理能力成为行业标准。Easysearch 作为 Elasticsearch 的优化版本,不仅继承了其强大的功能,还在性能和安全性上做了进一步的提升,为企业提供了一个高效、稳定且易于迁移的搜索引擎解决方案。通过深入了解这些技术和实践其应用,开发者和企业能够更好地利用这些工具来应对现代数据挑战,推动业务的持续发展和创新。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://infinilabs.cn/blog/2024/mastering-easysearch-syntax/
Easysearch 数据可视化和管理平台:INFINI Console 使用介绍
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2847 次浏览 • 2024-07-10 16:26
上次在《INFINI Easysearch 尝鲜 Hands on》中,我们部署了两个节点的 Easysearch,并设置了 Console 进行集群监控。今天,我们将介绍 INFINI Console 的使用。
Dashboard
INFINI Console 是一个功能强大的数据管理和分析平台,其仪表盘页面提供了直观简洁的界面,使用户能够快速了解系统状态并进行管理操作。本文将详细介绍仪表盘页面的各项功能。
仪表盘顶部显示系统的实时告警、通知和待办事项的数量,当前数据显示:
- 告警:0 条
- 通知:0 条
- 待办:0 条
在仪表盘的中心区域,用户可以看到几项关键的系统概览信息:
- 集群数量:当前有 3 个集群正在运行。
- 节点数量:系统中有 16 个节点。
- 主机数量:共有 3 台主机。
- 已用存储:系统已使用存储空间为 2.0GB。
仪表盘页面还提供了几个常用操作的快速入口,方便用户迅速访问常用功能:
- 集群注册:用户可以通过此入口快速注册新的集群。
- 数据探索:用户可以访问数据探索工具,对系统中的数据进行分析和查询。
- 告警管理:提供对告警信息的管理功能,用户可以查看和处理告警。
- 安全管理:安全管理入口帮助用户维护系统的安全设置和策略。
仪表盘右侧显示了集群的动态信息,包括最近的操作日志。例如:
- 2024-07-03 22:43:43,index medcl 在 cluster infiniLabs 中的状态更新。
- 2024-07-03 22:06:43,index medcl 在 cluster infiniLabs 中被创建。
集群管理页面
集群管理页面主要分为几个部分:顶部的功能选项卡、中部的集群列表、以及右侧的筛选和排序选项。
页面顶部的功能选项卡包括以下几项:
- Clusters (集群):显示当前系统中的所有集群。
- Nodes (节点):显示集群中的节点详细信息。
- Indices (索引):显示集群中的索引信息。
- Hosts (主机):显示系统中的主机信息。
集群列表展示了每个集群的详细信息,包括:
- 集群名称:每个集群的名称,如 “infinilabs”、“mycluster”、“INFINI_SYSTEM (JeanGrey)”。
- 集群健康状态:以颜色条的形式显示最近 14 天的集群健康状态(绿色表示健康,黄色表示有警告)。
- 节点数量:集群中包含的节点数量。
- 索引数量:集群中的索引数量。
- 分片数量:集群中的分片数量。
- 文档数量:集群中存储的文档数量。
- 磁盘使用率:集群的磁盘使用情况。
- JVM 堆内存使用率:集群的 JVM 堆内存使用情况。
- 索引速率:当前集群的索引速率(每秒索引数)。
- 搜索速率:当前集群的搜索速率(每秒搜索数)。
页面右侧提供了丰富的筛选和排序选项,可以根据以下条件筛选和排序集群:
- 健康状态 (Health Status):根据集群的健康状态筛选,如绿色(健康)和黄色(警告)。
- 分布 (Distribution):根据集群的分布类型筛选,如 “easysearch” 和 “elasticsearch”。
- 版本 (Version):根据集群使用的软件版本筛选,如 Easysearch 1.8.2 和 Elasticsearch 7.10.2。
- 区域 (Region):根据集群所在的区域筛选,如 “china” 和 “default”。
- 标签 (Tags):根据自定义标签进行筛选。
接下来分别介绍节点、索引和主机层面的信息,这些监控指标与集群层面大同小异。
节点监控
索引监控
主机监控
包括了常规的 CPU、内存、磁盘、网络的监控。
监控指标页面
监控报表页面提供了对集群运行状况的详细监控和分析功能。用户可以选择最近 15 分钟、1 小时、24 小时等不同时间范围查看数据,并手动点击刷新按钮更新数据,以获取最新的监控信息。
概览信息
显示当前集群的基本状态,包括:
- 集群名称:如 “infinilabs”。
- 在线时长:如 “3 天”。
- 集群版本:如 “1.8.2”。
- 健康状态:如 “green”。
- 节点数:如 “2”。
- 索引数:如 “38”。
- 主/总分片:如 “38/76”。
- 未分配分片:如 “0”。
- 文档数:如 “656,803”。
- 存储空间:如 “1007.2MB/385.4GB”。
- JVM 内存:如 “1023.0MB/2.0GB”。
监控报表页面还提供了多个性能指标的图表,包括:
索引吞吐 (doc/s)
- Total Indexing:总索引吞吐量。
- Primary Indexing:主分片的索引吞吐量。
查询吞吐 (query/s)
- Total Query:总查询吞吐量。
索引延迟 (ms)
- Indexing Latency:索引延迟时间。
- Delete Latency:删除操作的延迟时间。
查询延迟 (ms)
- Query Latency:查询延迟时间。
- Fetch Latency:获取操作的延迟时间。
- Scroll Latency:滚动操作的延迟时间。
点击“Advance”可以查看更多监控指标:
节点级别性能监控
包括 CPU、负载、JVM 内存、剩余使用空间及磁盘空间、集群启动时间和索引读写情况。
索引级别监控
包括集群内索引的数量、状态、主分片和副本分片数量、文档条数和占用空间。
集群动态页面
提供集群中各类事件和活动的详细记录和监控功能。
别名管理
别名管理页面提供了对索引别名的管理功能,使用户可以方便地管理和配置 Elasticsearch/EasySearch 的索引别名。
创建别名
可以通过 DSL 创建别名。例如,创建一个名为 my_index_alias 的别名指向 my_index
:
POST /_aliases
{
"actions": [
{
"add": {
"index": "my_index",
"alias": "my_index_alias"
}
}
]
}
删除别名
删除一个别名同样可以通过 REST API 实现:
POST /_aliases
{
"actions": [
{
"remove": {
"index": "my_index",
"alias": "my_index_alias"
}
}
]
}
索引轮换
索引轮换是一种常用的索引管理策略,特别适用于日志和时间序列数据的场景。通过索引轮换,用户可以在索引达到一定条件(如大小或文档数量)时,创建一个新的索引来继续存储数据,而旧的索引可以继续用于查询。
- 设置写别名:创建一个指向当前写入索引的别名,例如 current_write_index。
- 定义索引轮换条件:可以基于索引的大小、文档数量或时间来定义轮换条件。
- 索引并更新写别名指向这个新索引。
创建初始索引并设置写别名:
PUT /my_index-000001
{
"aliases": {
"current_write_index": {}
}
}
使用 /_rollover API 定义轮换条件并执行轮换:
POST /current_write_index/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 1000000
},
"settings": {
"number_of_shards": 1
},
"aliases": {
"current_write_index": {}
}
}
通过这种方式,查询操作可以透明地访问所有历史数据,而写操作总是指向最新的索引。
在 INFINI Console 中提供了可视化创建索引及别名的方式。页面右上角提供了新建按钮,用户可以通过点击该按钮创建新的索引别名,填写别名名称、关联索引、索引路由、搜索路由和过滤查询等配置。
平台监控
展示了多个关键指标的监控图表,包括:
- 健康状态 (Health):显示系统当前的健康状态。如果没有数据,则显示“暂无数据”。
- 引擎分布 (Engines):展示系统中不同搜索引擎的分布情况,例如 EasySearch 和 Elasticsearch 的比例。图表显示当前 EasySearch 占 67%,Elasticsearch 占 33%。
- 提供商 (Providers):显示系统中使用的云服务提供商信息。在示例中,所有资源都托管在 AWS 上。
- JDK 版本 (JDK):显示系统中使用的 JDK 版本信息。在示例中,所有节点都使用 JDK 版本 11.0.20。
- 磁盘使用情况 (Disk Utilization) - Top 10:显示磁盘使用率最高的前 10 个节点。在示例中,easysearch-node1 和 easysearch-node2 的磁盘使用率均为 4%。
- JVM 使用情况 (JVM Utilization) - Top 10:展示 JVM 使用率最高的前 10 个节点。在示例中,infinilabs 集群的 easysearch-node1 和 easysearch-node2 节点的 JVM 使用情况有详细的时间序列数据,显示了不同时间点的使用率变化。
我们还能够看到更多指标:
数据探索
在数据探索里,可以根据时间、字段等条件对索引或者视图下的数据进行搜索查询和分析,类似 Kibana 的 Discover。
这里可以看到集群的警报,目前集群运行良好,没有任何警报。
内部会预设一些警报规则,如下:
点进去一个请求,比如磁盘的警告,可以针对不同的使用量设置不同的警告级别和通知。
这里针对警报设置警报,可以看到现在支持很多平台,Discord、飞书、邮件、微信、Slack 以及钉钉。
点击进去可以查看,对于社交软件而言,其实是使用 Webhook 进行通知,除此之外也支持配置邮件服务器和自定义的 Webhook 进行通知。
开发工具
Console 的开发工具相当于 Kibana DevTool 的升级版,使用上基本没有大的区别,除了支持 DSL 之外,还支持多集群 Tab 切换、常用命令快速 Load、SQL 查询等。
集群连接凭证管理
可以看到连接这三个集群的凭证管理,目前都是有效的。
后台用户授权
可以添加用户以及修改 Console 管理界面的密码。目前设置了 admin 账号。
审计日志
追踪对集群的操作,捕获查看集群监控信息以及集群索引的操作。
结论
INFINI Console 的仪表盘页面集成了系统的关键信息和快捷操作入口,使用户可以高效地管理和监控系统。通过详细的概览信息、实时的告警通知、快速的功能入口和动态日志,用户能够对系统的运行状态一目了然,并快速响应各种管理需求。这个设计不仅提升了用户的工作效率,还确保了系统的安全和稳定运行。
INFINI Console 的集群管理页面提供了对系统集群的全面监控和管理功能。通过详细的集群信息展示、便捷的功能选项卡切换以及丰富的筛选和排序功能,用户可以高效地管理和监控系统中的集群状态。这不仅提升了运维效率,还确保了系统的稳定运行和高效管理。
INFINI Console 的节点管理页面提供了对集群节点的全面监控和管理功能。通过详细的节点信息展示、便捷的功能选项卡切换以及丰富的筛选和搜索功能,用户可以高效地管理和监控系统中的节点状态,从而提升运维效率,确保系统的稳定运行和高效管理。
INFINI Console 的监控报表页面提供了对集群运行状况的全面监控和分析功能。通过详细的概览信息和多个性能指标图表,用户可以高效地监控和管理集群的运行状态。这不仅提升了系统运维效率,还确保了集群的稳定运行和高效管理。
通过这些功能,INFINI Console 为用户提供了全面的系统管理工具,帮助他们高效地应对各种运维挑战,确保系统的高效、安全、稳定运行。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://blog.csdn.net/weixin_38781498/article/details/140077785
INFINI Easysearch 尝鲜 Hands on
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 2611 次浏览 • 2024-07-10 14:43
INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个自主可控的轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。
Easysearch 支持原生 Elasticsearch 的 DSL 查询语法,确保原业务代码无需调整即可无缝迁移。同时,极限科技还支持 SQL 查询,为熟悉 SQL 的开发人员提供更加便捷的数据分析方式。此外,Easysearch 兼容 Elasticsearch 的 SDK 和现有索引存储格式,支持冷热架构和索引生命周期管理,确保用户能够轻松实现数据的无缝衔接。
安装
安装脚本
无论是 Linux 还是 Mac 都是这个一键脚本
curl -sSL http://get.infini.cloud | bash -s -- -p easysearch
同时也提供了二进制的安装包:
如果不想整理 JAVA 环境问题,还可以使用这个 https://release.infinilabs.com/easysearch/stable/bundle/
docker 部署
官方提供了 Docker Compose 样例,包括三个服务:
- easysearch-node1
- easysearch-node2
- console
以下是详细说明:
版本控制:
- version: '3' 表示使用 Docker Compose 文件的第 3 版格式。
服务定义:
-
easysearch-node1 和 easysearch-node2:
- 这两个服务使用相同的 Docker 镜像 infinilabs/easysearch:latest 来组成双节点的集群。
- 容器运行时使用用户和组 ID 602:602。
- 设置了 ES_JAVA_OPTS 环境变量以配置 Java 虚拟机的内存。
- ulimits 选项配置了内存锁定和文件描述符的限制,以提升性能。
- 容器内的配置、数据和日志目录通过卷映射到主机目录中,以便于数据持久化。
- 服务暴露特定端口,使外部能够访问容器中的服务。
- 两个节点均加入名为 esnet 的自定义网络中。
-
console:
- 该服务使用镜像 infinilabs/console:1.26.0-1552(该镜像没有 latest,需要手动把 latest 更改位特定的版本号)。
- 同样通过卷将数据和日志目录映射到主机。
- 暴露 9000 端口用于 Web 界面访问。
- 使用 links 功能链接到 easysearch-node1 和 easysearch-node2,简化容器之间的通信。
- 设置了时区环境变量 TZ 为 Asia/Shanghai。
网络配置:
- esnet 网络使用 bridge 驱动,提供一个隔离的网络环境,配置了特定的子网 172.24.0.0/16,以确保服务之间的网络通信。
version: '3'
services:
easysearch-node1:
user: "602:602"
image: infinilabs/easysearch:latest
container_name: easysearch-node1
hostname: easysearch-node1
environment:
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- $PWD/ezs1/config:/app/easysearch/config
- $PWD/ezs1/data:/app/easysearch/data
- $PWD/ezs1/logs:/app/easysearch/logs
ports:
- 9201:9200
- 9301:9300
networks:
- esnet
easysearch-node2:
user: "602:602"
image: infinilabs/easysearch:latest
container_name: easysearch-node2
hostname: easysearch-node2
environment:
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- $PWD/ezs2/config:/app/easysearch/config
- $PWD/ezs2/data:/app/easysearch/data
- $PWD/ezs2/logs:/app/easysearch/logs
ports:
- 9202:9200
- 9302:9300
networks:
- esnet
console:
image: infinilabs/console:1.26.0-1552
container_name: console
hostname: console
volumes:
- $PWD/console/data:/data
- $PWD/console/log:/log
networks:
- esnet
ports:
- 9000:9000
links:
- easysearch-node1:es1
- easysearch-node2:es2
environment:
- TZ=Asia/Shanghai
networks:
esnet:
driver: bridge
ipam:
config:
- subnet: 172.24.0.0/16
尽管在这里官方提供了详细的命令,完全可以使用这个 docker-compose up 来进行替代。其他的脚本解释如下:
init.sh
#!/bin/bash
# 获取当前脚本所在目录的绝对路径
CUR_DIR=$(cd $(dirname $0); pwd)
# 创建必要的目录结构
mkdir -p $CUR_DIR/console/{data,log}
mkdir -p $CUR_DIR/{ezs1,ezs2}/{data,logs}
# 设置目录的拥有者和权限
chown -R 1000:1000 $CUR_DIR/console
chown -R 602:602 $CUR_DIR/{ezs1,ezs2}
chmod -R 0600 $CUR_DIR/{ezs1,ezs2}/config
# 设置 config 目录的子目录权限
find $CUR_DIR/{ezs1,ezs2}/config -type d -print0 | xargs -0 chmod 750
reset.sh
#!/bin/bash
# 获取当前脚本所在目录的绝对路径
CUR_DIR=$(cd $(dirname $0); pwd)
# 定义确认函数
function confirm() {
display_str=$1
default_ans=$2
if [[ $default_ans == 'y/N' ]]; then
must_match='[yY]'
else
must_match='[nN]'
fi
read -p"${display_str} [${default_ans}]:" ans
[[ $ans == $must_match ]]
}
# 提示用户确认删除所有数据
confirm "RISK WARN: Delete all data!!!" 'y/N' && echo || exit
# 删除 console、ezs1 和 ezs2 的数据和日志文件
rm -rvf $CUR_DIR/console/{data,log}/*
rm -rvf $CUR_DIR/{ezs1,ezs2}/{data,logs}/*
start.sh
#!/bin/bash
# 使用 Docker Compose 启动 ezs2 项目中的服务
docker-compose -p ezs2 up
stop.sh
#!/bin/bash
# 使用 Docker Compose 关闭并移除 ezs2 项目中的所有服务
docker-compose -p ezs2 down
在我的电脑中,可以看到成功启动的容器。
https://infinilabs.cn/docs/latest/easysearch/getting-started/install/docker-compose/
Console 连接
设置集群连接参数,比如域名端口,用户名密码。
初始化,这里会新建索引,写一些 sample 数据。
设置后台管理的密码,后期使用这个登录控制台。
检查配置,完成集群关联。
这个是后台管理界面,除了用户名密码之外,也支持单点登录:
跨引擎、跨版本、跨集群 独一份!
使用自带的面板进行查看节点数量:
同时也支持 REST 风格的 API 来进行查询。
接下来使用 Console 连接 Amazon 的 OpenSearch:
同样是输入集群的 URL,用户名和密码。
然后可以拿到集群的信息,比如地址,版本号,集群状态,节点数量。
最后看到连接成功的信息。
我们可以在集群管理中看到 Easysearch 的集群和我们刚刚添加的 OpenSearch 集群。
是否开源?目前还没有开放源代码。
关于 Easysearch 有奖征文活动
无论你是 Easysearch 的老用户,还是第一次听说这个名字,只要你对 INFINI Labs 旗下的 Easysearch 产品感兴趣,或者是希望了解 Easysearch,都可以参加这次活动。
详情查看:Easysearch 征文活动
作者:韩旭,亚马逊云技术支持,亚马逊云科技技领云博主,目前专注于云计算开发和大数据领域。
原文:https://blog.csdn.net/weixin_38781498/article/details/140077785