我刚打酱油去了,不好意思
es

es

极限网关助力好未来 Elasticsearch 容器化升级

ElasticsearchINFINI Labs 小助手 发表了文章 • 0 个评论 • 2118 次浏览 • 2024-06-12 15:01 • 来自相关话题

极限网关在好未来的最佳实践案例,轻松扛住日增百 TB 数据的流量,助力 ES 从物理机到云原生架构的改造,实现了流控、请求分析、安全管理、无缝迁移等场景。一次完美的客户体验~

背景

物理机架构时代

2022 年,好未来整个日志 Elasticsearch 拥有数十套服务集群,几百台物理机。这么多台机器耗费成本非常高,而且还要花费很大精力去维护。在人力资源有限情况下,存在非常多的弊端,运行成本高,不仅是机器折旧还有机柜等费用。

流量特征

这是来自某个业务线,如下图 1,真实流量,潮汐性非常明显。好未来有很多条业务线,几乎跟这个趋势都一致的,除了个别业务有“续报”、“开课”等活动特殊情况。潮汐性带来的问题就是高峰期 CPU、内存资源是可以消耗很高;低峰期资源使用量非常低,由于是物理架构,这些资源无法给其他业务线共享。

图1

图1

降本增效-容器化改造原动力

日志服务对成本的空前的压力促使我们推进 Elasticsearch 进行架构改造;如何改造,改造成什么样子,这两个问题一直是推进改造原动力。业界能够同时对水平扩展和垂直扩展就是 K8S,我们开始对 Elasticsearch 改造成能在 K8S 上运行进行探索,从而提升 CPU、内存利用率。

物理机时代,没办法把资源动态的扩缩,动态调配,资源隔离,单靠人力操作调度成本太高,几乎无法完成;集群对内存资源需求要比 CPU 资源大很多,由于机器型号配置是固定的,无法“定制”,这也会导致成本居高不下。所以,无论从那个方面来讲,容器化优势非常明显,既能够优化成本,也能够降低运维复杂度。

ES 容器化改造

进行架构升级重点难点- API 服务

改造过程,我们遇到了很多问题,比如容器 ES 版本和物理机 ES 版本不一致,如何让 ES API 能够兼容不同的 ES 版本,由于版本的不兼容,导致无法直接使用原有的 tribenode 进行服务,怎么提供一个高可用的 Elasticsearch API 服务。我们考虑到多个方面,比如使用官方推荐的 proxy 模式、第三方服务等进行选择,经过多方面对比,选择了极限网关 进行 tribenode 替换。

原始 ES API 服务痛点

  • API 访问没有流量控制
  • 可观测性差,而且稳定性一般
  • 版本兼容性差

物理机时代 API 架构

在物理机时代 ES 集群,API 架构如图 2,可以明显看到 tribe node 对所有 ES 集群的“侵入性”是非常大的,这就带来了很多问题,比较严重的就是单个集群对 ES tribenode 的影响和版本升级带来的不兼容问题。

图2

图2

混合时代 API 架构

通过图 3,我们可以看到,极限网关对于版本兼容性很好,能够适配不同的版本。因此,最终选择极限网关作为下一代 ES API 服务方。

图3

图3

里程碑:全部 ES 集群容器化

在 2023 年 3 月份,通过 Elastic 官方 ECK 模式,完成全部日志 ES 集群容器化改造,拥有数百节点,1PB+ 数据存储,每日新增数据 100T 左右。紧接着,除了日志服务外,同时支持了好未来多条业务线。

图4

图4

极限网关实践

下面主要讲述了,为什么选择极限网关,以及极限网关在好未来落地、应用这些内容。

为什么选择极限网关?

学习成本低

我们可以从文档中看到极限网关,其架构简洁,语法简单,直观易懂。学习成本比较低,上手非常快,对新手友好。

性能强悍

经过压测,发现极限网关速度非常快,且针对 Elasticsearch 做了非常细致的优化,能成倍提升写入和查询的速度。

安全性高

支持多种认证方式,最简单的账号密码认证,可以给自定义多个账户密码,大大简化了 Elasticsearch 的安全设置,同时,还可以支持 LDAP 安全验证。

跨版本支持

我们容器化改造过程需要兼容不同版本的 Elasticsrearch,极限网关针对不同的 Elasticsearch 版本做了兼容和针对性处理,能够让业务代码无缝的进行适配,后端 Elasticsearch 集群版本升级能够做到无缝过渡,降低版本升级和数据迁移的复杂度,非常匹配我们的业务场景。

灵活可扩展

可灵活对每个请求进行干预和路由,支持路由的智能学习,内置丰富的过滤器,通过配置动态修改每个请求的处理逻辑,也支持通过插件来进行扩展,满足我们对流量的控制,尤其是限流、用户、IP 等这些功能非常实用。

启用安全策略-为 API 服务保驾护航

痛点

在升级之前使用 tribe 作为 API 服务提供后端,几乎相当于裸奔,没有任何认证策略;另外,tribe 本身的稳定性也有问题,官方在新版本逐渐废弃这种 CCS(跨集群搜索),期间出现多次服务崩溃。

极限网关解决问题

极限网关通过,“basic_auth” 插件,提供最基本的安全校验,使用起来非常方便;同时,极限网关提供 LDAP 插件,可以接入公共的 LDAP 服务,对所有的访问用户进行校验,安全策略对所有的用户生效,不用担心因为 IP 问题泄漏数据等。

强大的过滤功能

在使用 ES 集群过程中,许多场景,需要对请求进行控制、限制等操作。在这方便,感受到了极限网关强大的产品力。比如下面的两个场景

对异常流量进行限流

  • 支持对 IP 限流
  • 支持对 hostname 限流
  • 支持 header 限流

对异常用户进行封禁

当 Elasticsearch 是通过 Basic Auth 或者 LDAP 方式来进行身份认证的时候,request_user_filter 过滤器可用来按请求的用户名信息来进行过滤。操作起来也非常简单,只需要 request_user_filter 这一个过滤器。

- request_user_filter:
    include:
        - "elastic"
    exclude:
        - "Ryan"

总结来讲,主要有这些方面的功能:

图5

图5

优秀的可观测性

痛点

改造前经常为看不到直观的数据指标感到头疼,查看指标需要多个地方同时打开,去筛选,查找,非常繁琐,付出的成本非常大。为此,大家都再考虑如何优化这种情况,无奈优先级比较低,一直没有真正的投入时间去优化这块。

完美解决

使用了极限网关,通过收集请求日志,非常清晰的收集到想要的数据,具体如下:

  • 总体方面:
    • 流量曲线
    • 状态码占比
    • 缓存统计
    • 每台网关请求流量
  • 细节方面:
    • 打印每次请求语句
    • 可以查看请求到具体 ES 节点流量
    • 可以查看过滤器的列表

通过下图,我们可以从管理视角直观的看到各种信息,这对于管理员来讲,省时省力,方便快捷。

图6

图6

意外收获:无缝迁移业务 Elasticsearch 上云

由于前期日志业务上云,受到非常好的反馈,多个业务线期望能够上云上服务,达到降本增效的目的。

支持双写

数据可以通过极限网关同时写入两个 ES 集群,能够保障数据完全一致,安全可靠。

无缝切换

切换很丝滑,影响非常小,能够让外界几乎感受不到服务波动。

图7

图7

通过使用极限网关,自建 ES 集群可以无缝的迁移上云,在整个迁移的过程中,两套集群通过网关进行了解耦,在迁移的过程中还能实现版本的无缝升级,极大降低了迁移成本,提高迁移效率,多次验证服务稳定可靠。

极限网关流量概览

这是其中一套极限网关的流量统计。用这部分数据进行巡检,一目了然,做到全局的掌控,提高感知力度。

图8

图8

极限网关使用总结

极限网关提供一系列高性能和高可靠性的网关服务。使用这样的服务给我们带来以下好处:

  1. 可观测性好:极限网关可以动态的对 Elasticsearch 运行过程中请求进行拦截和分析,通过指标和日志来了解集群运行状态,这些指标可以用于提升性能和业务优化。
  2. 增强安全性:包含先进的安全机制,如 basicauth、LDAP 等支持,保护用户数据不受未授权访问和各种网络威胁的侵害。
  3. 高稳定性:通过冗余设计和故障转移机制,极限网关能够确保网络服务的高可用性,即使在某些组件发生故障时也能保持服务不中断,单版本最长服务超过 15 个月。
  4. 易于管理:通过提供 INFINI Console 简洁直观的管理界面,让用户能够轻松配置和监控网络状态,提升管理效率。
  5. 客户支持:良好的客户服务支持可以帮助用户快速解决使用过程中遇到的问题,提供专业的技术指导。

综上所述,极限网关为用户提供了一个高速、安全、稳定且易于管理的 ES 网关,适合对网络性能有较高要求的个人和企业用户。

未来规划

第一阶段,完成了日志 ES 集群,所有集群的容器化改造,合并,成功的把成本降低了 60%以上。这期间积累了丰富容器化经验,为业务 ES 集群上容器做了良好的铺垫;成本优势和运维优势吸引越来越多的业务接入到容器化 ES 集群。

提升 ES 集群效能--新技术应用&&版本升级

  • 极限科技官方推荐的 Easysearch 在压缩率,查询速度等等方面有很多的优势,通过长时间的测试稳定性,新特性,对比云原生的 ES 集群,根据测试结果,给“客户”提供多种选择,这也是工作重点之一。
  • 我们当前使用的 ES 版本是 6.8,已经远远落后于官方版本,今年我们计划在选择合适的集群升级 ES 版本,拥抱更多官方提供的特性。

混合(多)云架构支持

随着越来越多的 ES 集群在机房的 K8S 集群部署,这里资源出现了紧张局面。 我们尝试在云上部署自建 ES 集群,弥补机房资源有限,无法大规模扩容,同时能够支持多活场景,满足更多客户的不同需求。混合云主要实现以下几种能力:

1、扩缩容:满足不同业务灵活适配

混合(多)云部署,可以让负载内部私有云 ES,同时部署到公有云,提升扩展 IT 基础设施不仅局限于 CPU、内存,还有存储。比如某一个业务要做活动,预估流量“大爆发”,需要提前准备大规模资源,在机房内根本来不及采购扩容支持,然而在公有云上就能很方便扩容、缩容。在云上搭建 ES 集群,设置满足需求的数量、容量、配置,配合极限网关路由策略,精准的把控流量流向。

图9

图9

2、灾备:紧急情况快速部署,恢复 ES 集群读写

当机房级别大规模故障,部分业务实现了多活,单一的机房故障不会影响其服务能力,而此时比如日志查看等仍有需求,为了满足这部分“客户”需求,可以在云上 K8S 集群,快速搭建 ES 集群,恢复日志读写功能。

图10

图10

参考文档:

作者:张华勋,前新浪 CDN 研发,工作主要涉及 Mysql、MongoDB、Redis、Elasticsearch、流量调度等组件和系统,以及运维自动化、平台化等工作。现就职于好未来。

关于好未来

好未来(NYSE:TAL)是一家以内容能力与科技能力为基础,以科教、科创、科普为战略方向,助力人的终身成长,并持续探索创新的科技公司。 好未来的前身学而思成立于 2003 年,2010 年在美国纽交所正式挂牌交易。好未来以“爱与科技助力终身成长”为使命,致力成为持续创新的组织。更多参见:https://www.100tal.com/

关于极限科技(INFINI Labs)

INFINI Labs

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。

极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。

官网:https://www.infinilabs.cn

联系我们

换掉ES? Redis官方搜索引擎,效率大幅提升

默认分类Fred2000 发表了文章 • 2 个评论 • 2875 次浏览 • 2024-05-30 10:08 • 来自相关话题

RediSearch是一个Redis模块,为Redis提供查询、二次索引和全文搜索。要使用RediSearch,首先要在Redis数据上声明索引。然后可以使用重新搜索查询语言来查询该数据。

RedSearch使用压缩的反向索引进行快速索引,占用内存少。RedSearch索引通过提供精确的短语匹配、模糊搜索和数字过滤等功能增强了

实现特性

  • 基于文档的多个字段全文索引
  • 高性能增量索引
  • 文档排序(由用户在索引时手动提供)
  • 在子查询之间使用 AND 或 NOT 操作符的复杂布尔查询
  • 可选的查询子句
  • 基于前缀的搜索
  • 支持字段权重设置
  • 自动完成建议(带有模糊前缀建议)
  • 精确的短语搜索
  • 在许多语言中基于词干分析的查询扩展
  • 支持用于查询扩展和评分的自定义函数
  • 将搜索限制到特定的文档字段
  • 数字过滤器和范围
  • 使用 Redis 自己的地理命令进行地理过滤
  • Unicode 支持(需要 UTF-8 字符集)
  • 检索完整的文档内容或只是ID 的检索
  • 支持文档删除和更新与索引垃圾收集
  • 支持部分更新和条件文档更新

对比 Elasticsearch

如下图所示,RediSearch 构建索引的时间为 221 秒,而 Elasticsearch 为 349 秒,快了 58%。

索引构建测试

我们模拟了一个多租户电子商务应用程序,其中每个租户代表一个产品类别并维护自己的索引。对于此基准测试,我们构建了 50K 个索引(或产品),每个索引最多存储 500 个文档(或项目),总共 2500 万个文档。

RediSearch 仅用了 201 秒就构建了索引,平均每秒运行 125K 个索引。然而,Elasticsearch 在 921 个索引后崩溃了,显然它不是为应对这种负载而设计的。

查询性能测试

一旦数据集被索引,我们就使用在专用负载生成器服务器上运行的 32 个客户端启动两个单词的搜索查询。如下图所示,RediSearch 吞吐量达到了 12.5K 操作/秒,而 Elasticsearch 为 3.1K 操作/秒,速度提高了 4 倍。

此外,RediSearch 延迟稍好一些,平均为 8 毫秒,而 Elasticsearch 为 10 毫秒。

安装

安装目前分为源码和docker安装两种方式。

源码安装

git clone https://github.com/RediSearch/RediSearch.git
cd RediSearch # 进入模块目录
make setup
make install

docker安装

note: RediSearch的安装比较复杂原包无法进行编译操作所以我们使用docker安装
docker run -p 6379:6379 redislabs/redisearch:latest

判断是否安装成功

127.0.0.1:0>module list
1) 1) "name"
   2) "ReJSON"
   3) "ver"
   4) "20007"

2) 1) "name"
   2) "search"
   3) "ver"
   4) "20209"

返回数组存在“ft”或 “search”(不同版本),表明 RediSearch 模块已经成功加载。

命令行操作

1、创建

1.1 创建索引

创建索引不妨想象成创建表结构,表一般基本属性有表名、字段和字段类别等,所以我们可以考虑将索引名代表表名,字段代表字段,属性即表示属性。

xxx.xxx.xxx.xxx:0>ft.create "student" schema "name" text weight 5.0 "sex" text "desc" text "class" tag
"OK"

student 表示索引名,name、sex、desc表示字段,text表示类型(这样表示只是为了便于理解)

“weight”为权重,默认值为 1.0

type student
"none"

我们创建的索引redis是不认识的,这证明使用的是插件。

1.2 创建文档

创建文档上下文的过程不妨想想成向表中插入数据,这里请注意字段名可以使用双引号但切记一定要用英文,这里之所以着重提出是因为有些编译器中文双引号和英文双引号用肉眼实在难以辨认否则会出现 “Fields must be specified in FIELD VALUE pairs”(其实是将“ 当作内容处理了以至于缺少了字段)

ft.add student 001 1.0 language "chinese" fields name "张三" sex "男" desc "这是一个学生" class "一班"
"OK"

其中001为文档ID,"1.0"为评分缺少此值会报"Could not parse document score"异常,language 指明使用的语言默认是英文编码 如果没有此标记存储是没有问题的但不可以通过中文字符查询

1.3 查询

1.3.1 基本查询

1.3.1.1 全量查询

xxx.xxx.xxx.xxx:0>FT.SEARCH student * SORTBY sex desc RETURN 3 name sex desc
1) "2"
2) "001"
3) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

4) "002"
5) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

1.3.1.2 匹配查询

xxx.xxx.xxx.xxx:0>ft.search student "张三" limit 0 10 RETURN 3 name sex desc
1) "2"
2) "001"
3) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

4) "002"
5) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

limit 与mysql相识主要用于分页,此处是全量匹配,如果没有设置language “chinese” 此处查询为0,

1.3.2 模糊匹配

1.3.2.1 后置匹配

ft.search student "李*"  SORTBY sex desc RETURN 3 name sex desc
1) "1"
2) "003"
3) 1) "name"
   2) "李四"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

1.3.2.2 模糊搜索

xxx.xxx.xxx.xxx:0>FT.SEARCH beers "%%张店%%"
1) "1"
2) "beer:1"
3) 1) "name"
  2) "集团本部已发布【文明就餐公约】,2号楼办公人员午餐的就餐时间是11:45~13:00,现经行政服务部进行抽查,发现我们部门有员工违规就餐现象。请大家务必遵守,相互转告,对于外地回到集团办公的同事,亦请遵守,谢谢!"
   3) "org"
   4) "山东省淄博市张店区"
   5) "school"
   6) "山东理工大学"

别高兴太早全量模糊匹配是由很大限制的,他基于Levenshtein距离(LD)进行模糊匹配。术语的模糊匹配是通过在术语周围加“%”来实现的,模糊匹配的最大LD为3,确切的说这只是一种相识度查询,并非一般意义上的模糊搜索,但是如果仔细观察会发现通过精确匹配时不仅能够将完整value值查询出来而且还查询出其他处于文档某个位置的key请看官方提供的一个例子:

FT.CREATE idx SCHEMA txt TEXT
FT.ADD idx docCn 1.0 LANGUAGE chinese FIELDS txt

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。

由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

FT.CREATE idx SCHEMA txt TEXT
FT.ADD idx docCn 1.0 LANGUAGE chinese FIELDS txt "Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。[8]"
FT.SEARCH idx "数据" LANGUAGE chinese HIGHLIGHT SUMMARIZE
# Outputs:
# <b>数据</b>?... <b>数据</b>进行写操作。由于完全实现了发布... <b>数据</b>冗余很有帮助。[8...

之所以会出现这样的效果是因为redisearch对文本进行了分词,其使用的工具是friso相比es的ik还是弱一些前者主要是对中文分词,体积小可移植性强。

从而我们可以结合后后置匹配算法

xxx.xxx.xxx.xxx:0>FT.SEARCH idx "数*" LANGUAGE chinese HIGHLIGHT
1) "1"
2) "docCn"
3) 1) "txt"
  2) "Redis支持主从同步。<b>数据</b>可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对<b>数据</b>进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和<b>数据</b>冗余很有帮助。[8]"

或者结合Levenshtein算法这样基本上能够满足业务查询需求

xxx.xxx.xxx.xxx:0>FT.SEARCH idx "%%单的树%%" LANGUAGE chinese HIGHLIGHT
1) "1"
2) "docCn"
3) 1) "txt"
  2) "Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层<b>树</b>复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步<b>树</b>时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。[8]"

1.3.2.3 字段查询

通过字段查询也可以实现模糊搜索,直接给例子,后面跟着官网上给的sql 和 redisearch的对照表

ft.search student *
1) "2"
2) "doudou"
3) 1) "name"
   2) "豆豆"
   3) "jtzz"
   4) "“检索”是很多产品中"
   5) "phone"
   6) "18563717107"

4) "ttao"
5) 1) "name"
   2) "姚元涛"
   3) "jtzz"
   4) "一个生病的人只"
   5) "phone"
   6) "18563717107"

ft.search student '@phone:185* @name:豆豆'
1) "1"
2) "doudou"
3) 1) "name"
   2) "豆豆"
   3) "jtzz"
   4) "“检索”是很多产品中"
   5) "phone"
   6) "18563717107"

1.4 删除

1.4.1 删除文档

xxx.xxx.xxx.xxx:0>ft.del student 002
"1"

1.4.3 删除索引

xxx.xxx.xxx.xxx:0>ft.drop student
"OK"

1.5 查看

1.5.1 查看所有索引

xxx.xxx.xxx.xxx:0>FT._LIST
1) "student1"
2) "ttao"
3) "idx"
4) "student"
5) "myidx"
6) "123"
7) "myIndex"
8) "testung"
9) "student2"

1.5.2 查看索引文档中的数据

1.5.2.1 获取单条数据

xxx.xxx.xxx.xxx:0>ft.get student 001
1) "name"
2) "张三"
3) "sex"
4) "男"
5) "desc"
6) "这是一个学生"
7) "class"
8) "一班"

1.5.2.2 获取多条数据

xxx.xxx.xxx.xxx:0>ft.mget student 001 002
1) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"
   7) "class"
   8) "一班"

2) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"
   7) "class"
   8) "一班"

1.6 索引别名操作

1.6.1 添加别名

123.232.112.84:0>FT.ALIASADD xs student
"OK"

给索引student起个xs的别名,一个索引可以起多个别名

1.6.2 修改别名

1.6.3 删除别名

123.232.112.84:0>FT.ALIASDEL xs 
"OK"

作者:架构师公众号

来源:https://mp.weixin.qq.com/s/TmCXx3rLjLPggvOFjGqS9w

版权申明:内容来源网络,仅供学习研究,版权归原创者所有。如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

记某客户的一次 Elasticsearch 无缝数据迁移

Elasticsearchyangmf2040 发表了文章 • 0 个评论 • 3757 次浏览 • 2024-04-02 14:16 • 来自相关话题

背景

客户需要将 Elasticsearch 集群无缝迁移到移动云,迁移过程要保证业务的最小停机时间。

实现方式

通过采用成熟的 INFINI 网关来进行数据的双写,在集群的切换恢复过程中来记录数据变更,待全量数据恢复之后再追平后面增量数据,追平增量之后,进行校验确保数据一致再进行流量的切换。

总体流程

总体迁移流程如下:

  1. 客户业务代码,切流量,双写。(新增的变更都会记录在网关本地,但是暂停消费到移动云)
  2. 暂停网关移动云这边的增量数据消费。
  3. 迁移 11 月的数据,快照,快照上传到 S3;
  4. 下载 S3 的文件到移动云。
  5. 恢复快照到移动云的 11 月份的索引。
  6. 开启网关移动云这边的增量消费。
  7. 等待增量追平(接近追平)。
  8. 按照时间条件(如:时间 A,当前时间往前 30 分钟),验证文档数据量,Hash 校验等等。
  9. 停业务的写入,网关,腾讯云的写入(10 分钟)。
  10. 等待剩余的增量追完。
  11. 对时间 A 之后的,增量进行校验。
  12. 切换所有流量到移动云,业务端直接访问移动云 ES。

总体的迁移时间:

  1. 11 月备份时间(30 分钟)19 号开始
  2. 备份下载到移动云的时间(2-3 天)
  3. 备份恢复到移动云集群的时间(30 分钟)
  4. 11 月份增量备份(20 分钟)(双写开始)(21 号)
  5. 11 月份增量下载到移动云(6 小时)
  6. 11 月份增量恢复时间(20 分钟)
  7. 追增量数据(8 个小时产生的数据,需要 1 个小时)
  8. 校验比对(存量 1 个小时)
  9. 流量暂停,增量的校验(10 分钟)
  10. 切换(1 分钟)

总体流程如下示意图:

ES 集群信息

  1. ES 版本 7.10.1
  2. 2个热节点 3个温节点  总数 1.9 TB
  3. 索引   1041, 分片2085
  4. 无自定义插件
  5. 有 update_bu_query 使用
  6. 有 delete_by_query 使用
  7. 吞吐量没有测试过,当前日增文档数 1 千多万,目标日增加上亿  

    迁移操作手册(参考)

    环境

  • 自建 ES 5.4.2
  • 自建 ES 5.6.8
  • 自建 ES 7.5.0
  • 极限网关服务器 1
  • 极限网关服务器 2
  • 云端负载均衡 1 (监听 9200 端口,指向极限网关服务器 1/2 的 8000 端口)
  • 云端负载均衡 2 (监听 9200 端口,指向极限网关服务器 1/2 的 8001 端口)

    场景描述

    若干个自建 Elasticsearch 集群需要平滑迁移到移动云,业务不停写、不做代码改动。

    数据架构

    通过将应用端流量走网关的方式,请求同步转发给自建 ES,网关记录所有的写入请求,并确保顺序在云端 ES 上重放请求,两侧集群的各种故障都妥善进行了处理,从而实现透明的集群双写,实现安全无缝的数据迁移。 业务端如果已经部署在云上,可以使用云上的 SLB 服务来访问网关,确保后端网关的高可用,如果业务端和极限网关还在企业内网,可以使用极限网关自带的 4 层浮动 IP 来确保网关的高可用

数据描述

以数据从自建集群 5.4.2 迁移到云上的 5.6.16 为例进行说明,执行步骤依次说明。

执行步骤

部署 INFINI Gateway

为了保证数据的无缝透明迁移,通过 INFINI Gateway 来进行双写。

  1. 系统调优

    参考此文档

  2. 下载程序
    
    [root@iZbp1gxkifg8uetb33pvcoZ ~]# mkdir /opt/gateway
    [root@iZbp1gxkifg8uetb33pvcoZ ~]# cd /opt/gateway/
    [root@iZbp1gxkifg8uetb33pvcoZ gateway]# wget http://release.infinilabs.com/gateway/snapshot/gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz
    --2022-05-19 10:16:25--  http://release.infinilabs.com/gateway/snapshot/gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz
    正在解析主机 release.infinilabs.com (release.infinilabs.com)... 120.79.205.193
    正在连接 release.infinilabs.com (release.infinilabs.com)|120.79.205.193|:80... 已连接。
    已发出 HTTP 请求,正在等待回应... 200 OK
    长度:7430568 (7.1M) [application/octet-stream]
    正在保存至: “gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz”

100%[==============================================================================================================================================>] 7,430,568 22.8MB/s 用时 0.3s

2022-05-19 10:16:25 (22.8 MB/s) - 已保存 “gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz” [7430568/7430568])

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# tar vxzf gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz gateway-linux-amd64 gateway.yml sample-configs/ sample-configs/elasticsearch-with-ldap.yml sample-configs/indices-replace.yml sample-configs/record_and_play.yml sample-configs/cross-cluster-search.yml sample-configs/kibana-proxy.yml sample-configs/elasticsearch-proxy.yml sample-configs/v8-bulk-indexing-compatibility.yml sample-configs/use_old_style_search_response.yml sample-configs/context-update.yml sample-configs/elasticsearch-route-by-index.yml sample-configs/hello_world.yml sample-configs/entry-with-tls.yml sample-configs/javascript.yml sample-configs/log4j-request-filter.yml sample-configs/request-filter.yml sample-configs/condition.yml sample-configs/cross-cluster-replication.yml sample-configs/secured-elasticsearch-proxy.yml sample-configs/fast-bulk-indexing.yml sample-configs/es_migration.yml sample-configs/index-docs-diff.yml sample-configs/rate-limiter.yml sample-configs/async-bulk-indexing.yml sample-configs/elasticssearch-request-logging.yml sample-configs/router_rules.yml sample-configs/auth.yml sample-configs/index-backup.yml


3. 修改配置

将网关提供的示例配置拷贝,并根据实际集群的信息进行相应的修改,如下:

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# cp sample-configs/cross-cluster-replication.yml 5.4.2TO5.6.16.yml

首先修改集群的身份信息,如下:
![](https://www.infinilabs.com/img/blog/2024/seamless-data-migration/3.png)

然后修改集群的注册信息,如下:
![](https://www.infinilabs.com/img/blog/2024/seamless-data-migration/4.png)

根据需要修改网关监听的端口,以及是否开启 TLS (如果应用客户端通过 http 协议访问 ES,请将entry.tls.enabled 值改为 false),如下:
![](https://www.infinilabs.com/img/blog/2024/seamless-data-migration/5.png)
不同的集群可以使用不同的配置,分别监听不同的端口,用于业务的分开访问。

4. 启动网关

启动网关并指定刚刚创建的配置,如下:

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# ./gateway-linux-amd64 -config 5.4.2TO5.6.16.yml


/ \ /\ / \/\/ / /\ \ \/\ /_/\ / /\///\ / /\/\ \ \/ \/ //\_ / / /\/ \/ / // \ /\ / \/ \ ___/\/ \/\/ \/ \/ \/_/ _/_/

[GATEWAY] A light-weight, powerful and high-performance elasticsearch gateway. [GATEWAY] 1.6.0_SNAPSHOT, 2022-05-18 11:09:54, 2023-12-31 10:10:10, 73408e82a0f96352075f4c7d2974fd274eeafe11 [05-19 13:35:43] [INF] [app.go:174] initializing gateway. [05-19 13:35:43] [INF] [app.go:175] using config: /opt/gateway/5.4.2TO5.6.16.yml. [05-19 13:35:43] [INF] [instance.go:72] workspace: /opt/gateway/data1/gateway/nodes/ca2tc22j7ad0gneois80 [05-19 13:35:43] [INF] [app.go:283] gateway is up and running now. [05-19 13:35:50] [INF] [actions.go:358] elasticsearch [primary] is available [05-19 13:35:50] [INF] [api.go:262] api listen at: http://0.0.0.0:2900 [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [primary] hosts: [] => [192.168.0.19:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [backup] hosts: [] => [es-cn-tl32p9fkk0006m56k.elasticsearch.aliyuncs.com:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [primary] hosts: [] => [192.168.0.19:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [backup] hosts: [] => [es-cn-tl32p9fkk0006m56k.elasticsearch.aliyuncs.com:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [primary] hosts: [] => [192.168.0.19:9200] [05-19 13:35:50] [INF] [entry.go:322] entry [my_es_entry/] listen at: https://0.0.0.0:8000 [05-19 13:35:50] [INF] [module.go:116] all modules are started


5. 后台运行

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# nohup ./gateway-linux-amd64 -config 5.4.2TO5.6.16.yml &


6. 应用授权

curl -XPOST http://localhost:2900/_license/apply -d' { "license": "XXXXXXXXXXXXXXXXXXXXXXXXX" }'

#### 部署 INFINI Console
为了方便在多个集群之间快速切换,使用 INFINI [Console](https://infinilabs.cn/products/console/) 来进行管理。

1. 下载安装

[root@iZbp1gxkifg8uetb33pvcpZ console]# wget http://release.infinilabs.com/console/snapshot/console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz --2022-05-19 10:57:24-- http://release.infinilabs.com/console/snapshot/console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz 正在解析主机 release.infinilabs.com (release.infinilabs.com)... 120.79.205.193 正在连接 release.infinilabs.com (release.infinilabs.com)|120.79.205.193|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度:13576234 (13M) [application/octet-stream] 正在保存至: “console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz”

100%[==============================================================================================================================================>] 13,576,234 33.2MB/s 用时 0.4s

2022-05-19 10:57:25 (33.2 MB/s) - 已保存 “console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz” [13576234/13576234])

[root@iZbp1gxkifg8uetb33pvcpZ console]# tar vxzf console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz console-linux-amd64 console.yml


2. 修改配置

[root@iZbp1gxkifg8uetb33pvcpZ console]# cat console.yml

for the system cluster, please use Elasticsearch v7.3+

elasticsearch:

  1. 启动服务

    [root@iZbp1gxkifg8uetb33pvcpZ console]# ./console-linux-amd64 -service install
    Success
    [root@iZbp1gxkifg8uetb33pvcpZ console]# ./console-linux-amd64 -service start
    Success
  2. 访问后台

访问该主机的 9000 端口,即可打开 Console 后台,http://x.x.x.x:9000/ 打开菜单 [System][Cluster] ,注册当前需要管理的 Elasticsearch 集群和网关地址,用来快速管理,如下:

测试 INFINI Gateway

为了验证网关是否正常工作,我们通过 INFINI Console 来快速验证一下。 首先通过走网关的接口来创建一个索引,并写入一个文档,如下: 查看 5.4.2 集群的数据情况,如下: 查看集群 5.6.16 的数据情况,如下: 说明网关配置都正常,验证结束。

调整网关的消费策略

因为我们需要在全量数据迁移之后,才能进行增量数据的追加,在全量数据迁移完成之前,我们应该暂停增量数据的消费。修改网关配置里面 Pipeline consume-queue_backup-to-backupconsume-queue_primary-failure-to-backup的参数 auto_startfalse,表示不自动启动该任务,具体配置方法如下: 修改完配置之后,需要重新启动网关。 为了方便管理,可以使用 INFINI Console 来注册和管理网关,如下: 待全量迁移完成之后,可以通过后台的 Task 管理来进行后续的任务启动、停止,如下:

切换流量

接下来,将业务正常写的流量切换到网关,也就是需要把之前指向 ES 5.4.2 的地址指向网关的地址,如果 5.4.2 集群开启了身份验证,业务端代码同样需要传递身份信息,和 5.4.2 之前的用法保持不变。 切换流量到网关之后,用户的请求还是以同步的方式正常访问自建集群,网关记录到的请求会按顺序记录到 MQ 里面,但是消费是暂停状态。 如果业务端代码使用的 ES 的 SDK 支持 Sniff,并且业务代码开启了 Sniff,那么应该关闭 Sniff,避免业务端通过 Sniff 直接链接到后端的 ES 节点,所有的流量现在应该都只通过网关来进行访问。

全量数据迁移

在流量迁移到网关之后,我们开始对自建 Elasticsearch 集群的数据进行全量迁移到云端 Elasticsearch 集群。 全量迁移已有的数据的方式有很多种:

  • 通过快照的方式进行恢复
  • 使用工具来导出导入,如: ESM

如果索引数量很多的话,可以按照索引依次进行导入,同时需要注意将 Mapping 和 Setting 提前导入。 以现在 5.4 集群的索引来为例,目前的待迁移索引为 demo_5_4_2,只有4 个文档: 我们使用网关自带的迁移功能来进行数据迁移,拷贝自带的样例文件,如下:

[root@iZbp1gxkifg8uetb33pvcpZ gateway]# cp sample-configs/es_migration.yml  5.4TO5.6.yml

修改其中代表集群和索引的相关配置,可以根据需要配置是否需要重命名索引和统一 Type( 用于跨版本统一 Type),如下图红框位置: 创建好模板和索引,如果目标集群不允许动态创建文档,需要提前创建好索引,如下图: 然后就可以开始数据的迁移了,执行网关程序并指定刚刚定义的配置,如下: 执行完成后,可以确认下数据的情况,如下图: 全量数据至此导入完成。

增量数据迁移

在全量导入的过程中,可能存在数据的增量修改,不过这部分请求都已经完整记录下来了,我们只需要开启网关的消费任务即可将挤压的请求应用到云端的 Elasticsearch 集群。 示例操作如下: 如果从 5.6 的集群来看的话,这部分的修改还没同步过来,如下: 这部分增量的数据变更,在网关层面都进行了完整记录,我们只需要开启网关的增量消费任务,如下: 通过观察队列是否消费完成来判断增量数据是否做完,如下: 现在我们再看一下 5.6 集群的数据情况,如下: 数据的增量更新就过来了。

执行数据比对

由于集群内部的数据可能比较多,我们需要进行一个完整的比对才能确保数据的完整性,可以通过网关自带的数据比对工具来进行,将样例自带的文件拷贝一份,如下:

[root@iZbp1gxkifg8uetb33pvcpZ gateway]# cp sample-configs/index-docs-diff.yml  5.4DIFF5.6.yml

修改需要比对的集群和索引信息,可以加上过滤条件,如时间范围窗口来进行增量 Diff,如下图:

执行网关程序,并指定该配置文件,如下图: 如图,两个集群完全一致。

切换集群

如果验证完之后,两个集群的数据已经完全一致了,可以将程序切换到新集群,或者将网关的配置里面的主备进行互换,同步写 5.6 集群。 双集群在线运行一段时间,待业务完全验证之后,再安全下线旧集群,如遇到问题,也可以随时回切到老集群。

小结

通过使用极限网关,自建 ES 集群可以安全无缝的迁移到移动云 ES,在迁移的过程中,两套集群通过网关进行了解耦,两套集群的版本也可以不一样,在迁移的过程中还能实现版本的无缝升级。 如有任何问题,请随时联系我,期待与您交流!

Elasticsearch 国产化

Easysearchyangmf2040 发表了文章 • 0 个评论 • 1613 次浏览 • 2024-03-16 16:36 • 来自相关话题

背景

Elasticsearch 这些年来在搜索领域一直是领头羊。国内也有非常多的企业在使用 Elasticsearch 来做查询搜索、数据分析、安全分析等等。甚至一些很重要的行业、系统都在使用 Elasticsearch。在使用 Elasticsearch 的道路上狂飙的时候,我们也观察到了一些问题:

  1. Elasticsearch 不再是开源软件了。
  2. Elastic 公司退出了中国直销市场,不提供本土化支持了。
  3. 国家对信创、自主可控的战略化布局。
  4. 国际形势从合作共赢到自闭对垒。
  5. Elasticsearch 软件本身安全问题频发。
  6. Elasticsearch 软件在性能、稳定性和扩展性方面存在很大的提升空间。

基于以上这些问题,推出一个 Elasticsearch 国产化解决方案就很有必要了。我们的解决方案是推出一款名为 Easysearch 的软件,作为 Elasticsearch 国产化替代 。
出发点是在兼容原 Elasticsearch 软件的基础之上,完善更多的企业级功能,同时提高产品的性能、稳定性和扩展性。
下面我将从几个方面简单介绍下 Easysearch 软件。

兼容性

支持原生 Elasticsearch 的 DSL 查询语法,原业务代码无需调整。 支持 SQL ,方便熟悉 SQL 的开发人员上手分析数据。 兼容 Elasticsearch 的 SDK。 兼容现有索引存储格式。 支持冷热架构和索引生命周期,真正做到无缝衔接。

功能增强

提供企业级的安全管理,可对接 LDAP、AD 认证。 重构分布式架构,保持稳定的同时,能支持更大规模的数据。 在不降低性能的同时,实现更高压缩比的数据压缩,直接节省磁盘 40% 以上。 支持 KNN、异步搜索、数据脱敏、可搜索快照、审计等企业级功能。

容灾

支持基于 CDC 的集群复制技术,实现同版本间的容灾。
支持基于请求双写的复制技术,实现跨版本容灾。

信创

全面适配国产 CPU、操作系统,并获得厂家认证。

迁移方案

支持原索引存储格式,可通过快照备份直接恢复到 Easysearch 集群。
提供迁移工具,直接可视化操作迁移数据。

简单的介绍就到这里了,更多信息请访问:https://www.infinilabs.com/products/easysearch

最后

如有需要请联系我,让我们一起位祖国的信创事业添砖加瓦。

如何防止 Elasticsearch 服务 OOM?

Easysearchyangmf2040 发表了文章 • 0 个评论 • 2151 次浏览 • 2024-02-26 10:12 • 来自相关话题

Elasticsearch(简称:ES) 和传统关系型数据库有很多区别, 比如传统数据中普遍都有一个叫“最大连接数”的设置。目的是使数据库系统工作在可控的负载下,避免出现负载过高,资源耗尽,谁也无法登录的局面。

那 ES 在这方面有类似参数吗?答案是没有,这也是为何 ES 会被流量打爆的原因之一。

针对大并发访问 ES 服务,造成 ES 节点 OOM,服务中断的情况,极限科技旗下的 INFINI Gateway 产品(以下简称 “极限网关”)可从两个方面入手,保障 ES 服务的可用性。

  1. 限制最大并发访问连接数。
  2. 限制非重要索引的请求速度,保障重要业务索引的访问速度。

下面我们来详细聊聊。

架构图

所有访问 ES 的请求都发给网关,可部署多个网关。

限制最大连接数

在网关配置文件中,默认有最大并发连接数限制,默认最大 10000。

entry:
  - name: my_es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: $[[env.GW_BINDING]]
      # See `gateway.disable_reuse_port_by_default` for more information.
      reuse_port: true

使用压测程序测试,看看到达10000个连接后,能否限制新的连接。 超过的连接请求,被丢弃。更多信息参考官方文档

限制索引写入速度

我们先看看不做限制的时候,测试环境的写入速度,在 9w - 15w docs/s 之间波动。虽然峰值很高,但不稳定。 接下来,我们通过网关把写入速度控制在最大 1w docs/s 。 对网关的配置文件 gateway.yml ,做以下修改。

env: # env 下添加
    THROTTLE_BULK_INDEXING_MAX_BYTES: 40485760 #40MB/s
    THROTTLE_BULK_INDEXING_MAX_REQUESTS: 10000 #10k docs/s
    THROTTLE_BULK_INDEXING_ACTION: retry #retry,drop
    THROTTLE_BULK_INDEXING_MAX_RETRY_TIMES: 10 #1000
    THROTTLE_BULK_INDEXING_RETRY_DELAY_IN_MS: 100 #10

router: # route 部分修改 flow
  - name: my_router
    default_flow: default_flow
    tracing_flow: logging_flow
    rules:
      - method:
          - "*"
        pattern:
          - "/_bulk"
          - "/{any_index}/_bulk"
        flow:
          - write_flow

flow: #flow 部分增加下面两段    
  - name: write_flow
    filter:
      - flow:
          flows:
            - bulking_indexing_limit
      - elasticsearch:
          elasticsearch: prod
          max_connection_per_node: 1000
  - name: bulking_indexing_limit
    filter:
      - bulk_request_throttle:
          indices:
            "test-index":
              max_bytes: $[[env.THROTTLE_BULK_INDEXING_MAX_BYTES]]
              max_requests: $[[env.THROTTLE_BULK_INDEXING_MAX_REQUESTS]]
              action: $[[env.THROTTLE_BULK_INDEXING_ACTION]]
              retry_delay_in_ms: $[[env.THROTTLE_BULK_INDEXING_RETRY_DELAY_IN_MS]]
              max_retry_times: $[[env.THROTTLE_BULK_INDEXING_MAX_RETRY_TIMES]]
              message: "bulk writing too fast" #触发限流告警message自定义
              log_warn_message: true

再次压测,test-index 索引写入速度被限制在了 1w docs/s 。

限制多个索引写入速度

上面的配置是针对 test-index 索引的写入速度控制。如果想添加其他的索引,新增一段配置即可。 比如,我允许 abc 索引写入达到 2w docs/s,test-index 索引最多不超过 1w docs/s ,可配置如下。

  - name: bulking_indexing_limit
    filter:
      - bulk_request_throttle:
          indices:
            "abc":
              max_requests: 20000
              action: drop
              message: "abc doc写入超阈值" #触发限流告警message自定义
              log_warn_message: true
            "test-index":
              max_bytes: $[[env.THROTTLE_BULK_INDEXING_MAX_BYTES]]
              max_requests: $[[env.THROTTLE_BULK_INDEXING_MAX_REQUESTS]]
              action: $[[env.THROTTLE_BULK_INDEXING_ACTION]]
              retry_delay_in_ms: $[[env.THROTTLE_BULK_INDEXING_RETRY_DELAY_IN_MS]]
              max_retry_times: $[[env.THROTTLE_BULK_INDEXING_MAX_RETRY_TIMES]]
              message: "bulk writing too fast" #触发限流告警message自定义
              log_warn_message: true

限速效果如下

限制读请求速度

我们先看看不做限制的时候,测试环境的读取速度,7w qps 。 接下来我们通过网关把读取速度控制在最大 1w qps 。 继续对网关的配置文件 gateway.yml 做以下修改。

  - name: default_flow
    filter:
      - request_path_limiter:
          message: "Hey, You just reached our request limit!"                                      rules:      
            - pattern: "/(?P<index_name>abc)/_search"                          
              max_qps: 10000
              group: index_name                                    
      - elasticsearch: 
          elasticsearch: prod                            
          max_connection_per_node: 1000

再次进行测试,读取速度被限制在了 1w qps 。

限制多个索引读取速度

上面的配置是针对 abc 索引的写入速度控制。如果想添加其他的索引,新增一段配置即可。 比如,我允许 abc 索引读取达到 1w qps,test-index 索引最多不超过 2w qps ,可配置如下。

  - name: default_flow
    filter:
      - request_path_limiter:
          message: "Hey, You just reached our request limit!"
          rules:
            - pattern: "/(?P<index_name>abc)/_search"
              max_qps: 10000
              group: index_name
            - pattern: "/(?P<index_name>test-index)/_search"
              max_qps: 20000
              group: index_name
      - elasticsearch:
          elasticsearch: prod
          max_connection_per_node: 1000

多个网关限速

限速是每个网关自身的控制,如果有多个网关,那么后端 ES 集群收到的请求数等于多个网关限速的总和。 本次介绍就到这里了。相信大家在使用 ES 的过程中也遇到过各种各样的问题。欢迎大家来我们这个平台分享自己的问题、解决方案等。如有任何问题,请随时联系我,期待与您交流!

用 Easysearch 帮助大型车企降本增效

Easysearchyangmf2040 发表了文章 • 0 个评论 • 4439 次浏览 • 2024-02-02 15:15 • 来自相关话题

最近某头部汽车集团需要针对当前 ES 集群进行优化,背景如下: ES 用于支撑包括核心营销系统、管理支持系统、财务类、IT 基础设施类、研发、自动驾驶等多个重要应用,合计超 50 余套集群,累计数据超 1.5PB 。 本文针对其中一个 ES 集群进行分享,该集群原本使用的是 ES 7.3.2 免费版,数据已经 130TB 了,14 个节点。写入数据时经常掉节点,写入性能也不稳定,当天的数据写不完。迫切需要新的解决方案。 分析业务场景后总结需求要点:主要是写,很少查。审计需求,数据需要长期保存。 这个需求比较普遍,处理起来也很简单:

  • 使用 Easysearch 软件,只需少量节点存储近两天的数据。
  • 索引设置开启 ZSTD 压缩功能,节省磁盘空间。
  • 每天索引数据写完后,第二天执行快照备份存放到 S3 存储。
  • 备份成功后,删除索引释放磁盘空间。
  • 需要搜索数据时,直接从快照搜索。

将近期的数据,存放到本地磁盘,保障写入速度。写入完毕的索引,在执行快照备份后,可删除索引,释放本地磁盘空间。

Easysearch 配置要点

path.repo: ["/S3-path"]
node.roles: ["data","search"]
node.search.cache.size: 500mb
  • path.repo : 指定 S3 存储路径,上传快照用。
  • node.roles : 只有 search 角色的节点,才能去搜索快照中的数据。
  • node.search.cache.size : 执行快照搜索时的,缓存大小。

更多信息请参考官方文档

旧数据迁移

通过 Console 将原 ES 集群的数据,迁移到新 Easysearch 集群。迁移时,复制 mapping 和 setting,并在 setting 中添加如下设置。

"codec": "ZSTD",
"source_reuse": true,

原索引数据量大,可拆分成多个小任务。 迁移完,索引存储空间一般节省 50% 左右。 原索引 279GB ,迁移完后 138GB。

搜索快照数据

挂载快照后,搜索快照里的索引和搜索本地的索引,语法完全一样。 如何判断一个索引是在快照还是本地磁盘呢?可以查看索引设置里的 settings.index.store.type 如果是 remote_snapshot ,说明是快照中的数据。如果是空值,则是集群本地的数据。
这次迁移,节省了 6 台主机资源。更重要的是,用上对象存储后,主机磁盘空间压力骤减。
这次介绍就到这里了,有问题联系我。

关于 Easysearch

Easysearch

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。

官网文档:https://infinilabs.com/docs/latest/easysearch

【搜索客社区日报】第1769期 (2024-01-05)

社区日报laoyang360 发表了文章 • 0 个评论 • 2922 次浏览 • 2024-01-05 15:41 • 来自相关话题

1、一个Elasticsearch 监控 vue 客户端(昨天还在更新) https://github.com/cars10/elasticvue 2、Elasticsearch 系统设计小抄 https://betterprogramming.pub/ ... 60463 https://towardsdatascience.com ... ebfff 3、CKibana——为了能够在原生kibana上直接使用ElasticSearch语法查询ClickHouse的服务 https://github.com/TongchengOpenSource/ckibana 4、从 Elasticsearch 7.17 迁移到 Elasticsearch 8.x:陷阱和经验教训 https://engineering.zalando.co ... .html 编辑:铭毅天下  更多资讯:http://news.searchkit.cn

开启安全功能 ES 集群就安全了吗?

Easysearchyangmf2040 发表了文章 • 0 个评论 • 3184 次浏览 • 2023-12-27 10:38 • 来自相关话题

背景

经常跟 ES 打交道的朋友都知道,现在主流的 ES 集群安全方案是:RBAC + TLS for Internal + HTTPS 。

作为终端用户一般只需要关心用户名和密码就行了。作为管理和运维 ES 的人员来说,可能希望 ES 能提供密码策略来强制密码强度和密码使用周期。遗憾的是 ES 对密码强度和密码使用周期没有任何强制要求。如果不注意,可能我们天天都在使用“弱密码”或从不修改的密码(直到无法登录)。而且 ES 对连续的认证失败,不会做任何处理,这让 ES 很容易遭受暴力破解的入侵。

那还有没有别的办法,进一步提高安全呢? 其实,网关可以来帮忙。

虽然网关无法强制提高密码复杂度,但可以提高 ES 集群被暴力破解的难度。

大家都知道,暴力破解--本质就是不停的“猜”你的密码。以现在的 CPU 算力,一秒钟“猜”个几千上万次不过是洒洒水,而且 CPU 监控都不带波动的,很难发现异常。从这里入手,一方面,网关可以延长认证失败的过程--延迟返回结果,让破解不再暴力。另一方面,网关可以记录认证失败的情况,做到实时监控,有条件的告警。一旦出现苗头,可以使用网关阻断该 IP 或用户发来的任何请求。

场景模拟

首先,用网关代理 ES 集群,并在 default_flow 中增加一段 response_status_filter 过滤器配置,对返回码是 401 的请求,跳转到 rate_limit_flow 进行降速,延迟 5 秒返回。

  - name: default_flow
    filter:
      - elasticsearch:
          elasticsearch: prod
          max_connection_per_node: 1000
      - response_status_filter:
          exclude:
            - 401
          action: redirect_flow
          flow: rate_limit_flow
  - name: rate_limit_flow
    filter:
      - sleep:
          sleep_in_million_seconds: 5000

其次,对于失败的认证,我们可以通过 Console 来做个看板实时分析,展示。

折线图、饼图图、柱状图等,多种展示方式,大家可充分发挥。

最后,可在 Console 的告警中心,配置对应的告警规则,实时监控该类事件,方便及时跟进处置。

效果测试

先带上正确的用户名密码测试,看看返回速度。

0.011 秒返回。再使用错误的密码测试。

整整 5 秒多后,才回返结果。如果要暴力破解,每 5 秒钟甚至更久才尝试一个密码,这还叫暴力吗?

看板示例

此处仅仅是抛砖引玉,欢迎大家发挥想象。

告警示例

建立告警规则,用户 1 分钟内超过 3 次登录失败,就产生告警。

可在告警中心查看详情,也可将告警推送至微信、钉钉、飞书、邮件等。

查看告警详情,是 es 用户触发了告警。

最后,剩下的工作就是对该账号的处置了。如果有需要可以考虑阻止该用户或 IP 的请求,对应的过滤器文档在这里,老规矩加到 default_flow 里就行了。

如果小伙伴有其他办法提升 ES 集群安全,欢迎和我们一起讨论、交流。我们的宗旨是:让搜索更简单!

给 ES 插上向量检索的翅膀 | DataFunSummit 2023 峰会演讲内容速达

Elasticsearchliaosy 发表了文章 • 0 个评论 • 1506 次浏览 • 2023-07-12 18:37 • 来自相关话题

近日,由 DataFun 主办的 DataFunSummit 2023 数据基础架构峰会 圆满落下帷幕,本次峰会邀请了腾讯、百度、字节、极限科技、Zilliz 等众多企业技术专家为大家带来分布式存储以及向量数据库的架构原理、性能优化与实践解析分享。

向量数据库架构与实践论坛 中,极限科技搜索引擎研发工程师张磊受邀出席做了《给 ES 插上向量检索的翅膀》的主题演讲。据介绍,本次演讲主要介绍了 Elasticsearch(ES)与向量技术的融合,展示其在不同行业中的应用场景和优势,同时也对 ES 与向量的技术细节进行详细讨论,并通过具体案例演示如何利用向量提升搜索能力。

讲师介绍

张磊,极限科技 Easysearch 引擎研发工程师,2013 年开始接触 Elasticsearch,10 余年搜索相关经验,之前主要做一些围绕 Elasticsearch 在日志检索和公安大数据相关业务的开发,对 Elasticsearch 和 Lucene 源码比较熟悉,目前专注于公司内部搜索产品的开发。

《给 ES 插上向量检索的翅膀》PPT 内容

更多 PPT 内容参见 https://elasticsearch.cn/slides/322

关于 Easysearch

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 衍生自基于开源协议 Apache 2.0 的 Elasticsearch 7.10 版本。Easysearch 的目标是提供一个轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。

官网文档:https://www.infinilabs.com/docs/latest/easysearch

下载地址:https://www.infinilabs.com/download

集群分片数非常多的情况下,是否会造成master节点频繁gc

Elasticsearchxiaohei 回复了问题 • 3 人关注 • 2 个回复 • 1990 次浏览 • 2023-07-07 16:23 • 来自相关话题

ES的正排索引(field data)转为doc values存储后如何做到disk上实时搜索的

Elasticsearchhapjin 回复了问题 • 4 人关注 • 2 个回复 • 6273 次浏览 • 2023-06-20 11:47 • 来自相关话题

es进程异常退出,es日志和系统日志都无相关信息,求助各位大大~

Elasticsearchlemontree666 回复了问题 • 3 人关注 • 2 个回复 • 7459 次浏览 • 2023-06-02 16:20 • 来自相关话题

关于es7中的节点失效探测(fault_detection)参数

回复

Elasticsearchshwtz 发起了问题 • 1 人关注 • 0 个回复 • 6241 次浏览 • 2023-01-17 14:56 • 来自相关话题

elasticsearch 自定义id引发的负载均衡问题

Elasticsearchamc 回复了问题 • 2 人关注 • 1 个回复 • 2284 次浏览 • 2022-12-12 15:04 • 来自相关话题

es的bulk操做,相同的id,可以保证写入数据的顺序性吗?

Elasticsearch陈水鱼 回复了问题 • 3 人关注 • 3 个回复 • 2397 次浏览 • 2022-11-11 11:10 • 来自相关话题

条新动态, 点击查看
medcl

medcl 回答了问题 • 2014-11-11 17:27 • 6 个回复 不感兴趣

ElasticSearch-Hadoop的目標是什麼呢??

赞同来自:

简单来说,Hadoop还是Hadoop,Elasticsearch还是Elasticsearch,而Elasticsearch-Hadoop在中间用来连接这两个系统,大量的原始数据可以存放在Hadoop里面,通过Elasticsearch—Hadoop可以调用... 显示全部 »
简单来说,Hadoop还是Hadoop,Elasticsearch还是Elasticsearch,而Elasticsearch-Hadoop在中间用来连接这两个系统,大量的原始数据可以存放在Hadoop里面,通过Elasticsearch—Hadoop可以调用Hadoop的Map-Reduce任务来创建elasticsearch的索引,数据进入elasticsearch之后,就可以使用elasticsearch的搜索特性来进行更加高级的分析,比如基于Kibana来作快速分析。

技术上来说elasticsearch-Hadoop实现了Hadoop的读写接口,翻译es的查询到Hadoop的map-reduce,job,这样可以通过es来直接查询Hadoop里面的数据。

HDFS之前可以作为elasticsearch的gateway,1.0之后也能当做snapshot的存储,用来做索引备份,方便恢复数据。
Rubricate

Rubricate 回答了问题 • 2014-11-24 17:22 • 9 个回复 不感兴趣

如何设置分配给elasticsearch的内存大小?

赞同来自:

在 ES_HOME/bin/elasticsearch 里面
在 ES_HOME/bin/elasticsearch 里面
keyword其实可以达到不分词的效果
keyword其实可以达到不分词的效果
Elk的处理能力没有公式可以得到,受很多因素影响,我给出的答案是基于我们的实践经验。我们经历过20G -> 100G -> 200G -> 500G -> 1T这样的过程,集群的data node从最初的4个扩容到现在的20个。目前每天... 显示全部 »
Elk的处理能力没有公式可以得到,受很多因素影响,我给出的答案是基于我们的实践经验。我们经历过20G -> 100G -> 200G -> 500G -> 1T这样的过程,集群的data node从最初的4个扩容到现在的20个。目前每天处理50亿条裸日志,产生的主索引1.5TB,业务繁忙期间,每秒处理8-10万条日志,历史数据保留10天。

如果每天200gb日志估计用redis问题不大,但以后量会大很多,推荐用Kafka,主要原因是redis是单线程,一个实例的处理能力受限于一个cpu内核,而多个实例做lb会很麻烦。kafka是集群方式运作,扩容简单得多。另外Kafka的队列是构造在磁盘上的,相比Reidis可以容忍更长的消费端故障时间。我们目前是2台服务器做kafka集群,上面所说的量撑住毫无压力。
medcl

medcl 回答了问题 • 2015-01-27 18:25 • 4 个回复 不感兴趣

关于elasticsearch的集群问题

赞同来自:

是的,会重新拷贝数据,你真的需要跨机房么?
是的,会重新拷贝数据,你真的需要跨机房么?
首先,你写入的时候要确定内存的使用量如何,不过一般写入内存的使用不会消耗太大。就算是bulk,也只是用一点内存缓冲而已。。。我不知道你的es的磁盘情况如何,es的写入数据是顺序存储,但是在es里面存在大量的索引,这些索引在维护和写入的时候,锁的情况还有随机IO... 显示全部 »
首先,你写入的时候要确定内存的使用量如何,不过一般写入内存的使用不会消耗太大。就算是bulk,也只是用一点内存缓冲而已。。。我不知道你的es的磁盘情况如何,es的写入数据是顺序存储,但是在es里面存在大量的索引,这些索引在维护和写入的时候,锁的情况还有随机IO的消耗都很明显,所以我觉得你的瓶颈更多可能是在磁盘。可以分享下磁盘的情况再讨论~
tonylxc

tonylxc 回答了问题 • 2015-03-15 17:20 • 5 个回复 不感兴趣

es被攻击了,怎么处理?

赞同来自:

1. 永远不要把Elasticsearch端口暴露给外网. Elasticsearch应当运行在private network中.
2. 禁用dynamic scripting.
3. Elasticsearch更新频繁, 务必跟上更新脚步至1.4.4
4. ... 显示全部 »
1. 永远不要把Elasticsearch端口暴露给外网. Elasticsearch应当运行在private network中.
2. 禁用dynamic scripting.
3. Elasticsearch更新频繁, 务必跟上更新脚步至1.4.4
4. Elasticsearch并不依赖于Shield插件. Shield插件只是一个extra sugar, 并且是商业收费.
如果你用的是search api的话 http://elasticsearch-py.readthedocs.io/en/master/api.html#elasticsearch.Elasticsearch.search
我猜你的size参数用的默认值10... 显示全部 »
如果你用的是search api的话 http://elasticsearch-py.readthedocs.io/en/master/api.html#elasticsearch.Elasticsearch.search
我猜你的size参数用的默认值10
size – Number of hits to return (default: 10)
kennywu76

kennywu76 回答了问题 • 2017-02-16 11:03 • 4 个回复 不感兴趣

es自定义分词插件问题

赞同来自:

你用的第三方库com.hankcs.hanlp.dictionary.CoreDictionary  CoreDictionary.java里有一个辞典加载失败时做一个System.exit(-1)的系统调用。  ES使用了 Java Security Man... 显示全部 »
你用的第三方库com.hankcs.hanlp.dictionary.CoreDictionary  CoreDictionary.java里有一个辞典加载失败时做一个System.exit(-1)的系统调用。  ES使用了 Java Security Manager来限制第三方库做不安全的系统调用,所以这个System.exit(-1)就被禁止了。 
 
解决方法一个是更改这个第三方库,在异常的时候不要掉用system.exit,或者为这个库加一个白名单(有安全隐患,不建议这么做)。 
 
参考:
https://www.elastic.co/guide/en/elasticsearch/reference/5.2/modules-scripting-security.html#java-security-manager
http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html
 
 
kennywu76

kennywu76 回答了问题 • 2017-09-11 13:44 • 3 个回复 不感兴趣

现在es能不能用G1来进行内存回收?

赞同来自:

之前版本,官方是有文档明确说明不要用G1。 因为根据Lucene的stress test,发现某些版本JAVA G1存在的Bug,会造成Lucene的段文件损坏。
 
在5.0以后,官方文档没有明确说是否可以使用G1,但是ES启动过程中有一个针对G1 GC的J... 显示全部 »
之前版本,官方是有文档明确说明不要用G1。 因为根据Lucene的stress test,发现某些版本JAVA G1存在的Bug,会造成Lucene的段文件损坏。
 
在5.0以后,官方文档没有明确说是否可以使用G1,但是ES启动过程中有一个针对G1 GC的JVM版本校验
https://www.elastic.co/guide/en/elasticsearch/reference/5.5/_g1gc_check.html
其隐含的意思是说,使用 JDK 8u40以上版本,启用G1应该是安全的。
 
不过,根据经验,在使用ES过程中遇到长时间GC问题时,通常需要调整的不是JVM,而是Query本身。特别是,频繁OLD GC过后, 释放不了Heap空间的情况下,用CMS还是G1不会有什么分别。
我觉得吧,你这个本质是一个语句调优的问题,结果你把大家带跑偏了,es 对于几百万数据的查询肯定是在 ms 级,所以你应该把你的查询语句还有数据模型讲一下,优化你的查询才是正道,不要想这些没用的。
我觉得吧,你这个本质是一个语句调优的问题,结果你把大家带跑偏了,es 对于几百万数据的查询肯定是在 ms 级,所以你应该把你的查询语句还有数据模型讲一下,优化你的查询才是正道,不要想这些没用的。
luohuanfeng

luohuanfeng 回答了问题 • 2018-03-15 11:40 • 6 个回复 不感兴趣

query_string查询多值字段问题请教

赞同来自:

能使用term查询么
能使用term查询么
kennywu76

kennywu76 回答了问题 • 2018-03-23 12:26 • 3 个回复 不感兴趣

使用elasticsearch 做排重存储使用的可行性

赞同来自:

功能上可行,主要还是需要测试一下性能。 因为op=create这种方式写入文档,遇到重复的id会抛异常,从而阻止写入。 所以当有大量重复文档的时候,catch大量的异常产生的性能损耗就不能够忽视。 
 
20w每秒的写入量不算小,自己剋模拟不同量级的id重复情... 显示全部 »
功能上可行,主要还是需要测试一下性能。 因为op=create这种方式写入文档,遇到重复的id会抛异常,从而阻止写入。 所以当有大量重复文档的时候,catch大量的异常产生的性能损耗就不能够忽视。 
 
20w每秒的写入量不算小,自己剋模拟不同量级的id重复情况,测试一下写入吞吐量,据此规划硬件资源。
kennywu76

kennywu76 回答了问题 • 2018-09-18 17:57 • 3 个回复 不感兴趣

es 集群索引 分片分配策略

赞同来自:

可以给不同数据中心的结点,在ES配置文件里配置不同的rack_id这个属性,然后集群设置里将rack_id设置为shard allocation awareness即可。 这样ES会保证,主分片和副本必须分布在rack_id不同的结点上。
 
参考: http... 显示全部 »
可以给不同数据中心的结点,在ES配置文件里配置不同的rack_id这个属性,然后集群设置里将rack_id设置为shard allocation awareness即可。 这样ES会保证,主分片和副本必须分布在rack_id不同的结点上。
 
参考: https://www.elastic.co/guide/en/elasticsearch/reference/6.4/allocation-awareness.html
 
 
 
kennywu76

kennywu76 回答了问题 • 2018-11-01 10:10 • 4 个回复 不感兴趣

Elasticsearch中文分词器问题

赞同来自:

提供一个思路供参考:
 
公司名称可以索引为multi-filed,即一个为keyword类型,一个为text类型。 查询的时候,使用bool Query,对两个字段分别查询后用should连接, 这样完全匹配的公司名称相关度比部分匹配的高,排在前面优先返回。... 显示全部 »
提供一个思路供参考:
 
公司名称可以索引为multi-filed,即一个为keyword类型,一个为text类型。 查询的时候,使用bool Query,对两个字段分别查询后用should连接, 这样完全匹配的公司名称相关度比部分匹配的高,排在前面优先返回。
 
例如:
[code]{
"query": {
"bool": {
"should":
}
}
}
对于常用词的滤除,一个可以考虑在分词器中,将常用词定义为stop word, 从而在分词阶段就滤除掉。 另外也可以通过boosting Query,降低这类词的打分权重。 参考:  not-quite-not.html

集群分片数非常多的情况下,是否会造成master节点频繁gc

回复

Elasticsearchxiaohei 回复了问题 • 3 人关注 • 2 个回复 • 1990 次浏览 • 2023-07-07 16:23 • 来自相关话题

ES的正排索引(field data)转为doc values存储后如何做到disk上实时搜索的

回复

Elasticsearchhapjin 回复了问题 • 4 人关注 • 2 个回复 • 6273 次浏览 • 2023-06-20 11:47 • 来自相关话题

es进程异常退出,es日志和系统日志都无相关信息,求助各位大大~

回复

Elasticsearchlemontree666 回复了问题 • 3 人关注 • 2 个回复 • 7459 次浏览 • 2023-06-02 16:20 • 来自相关话题

关于es7中的节点失效探测(fault_detection)参数

回复

Elasticsearchshwtz 发起了问题 • 1 人关注 • 0 个回复 • 6241 次浏览 • 2023-01-17 14:56 • 来自相关话题

elasticsearch 自定义id引发的负载均衡问题

回复

Elasticsearchamc 回复了问题 • 2 人关注 • 1 个回复 • 2284 次浏览 • 2022-12-12 15:04 • 来自相关话题

es的bulk操做,相同的id,可以保证写入数据的顺序性吗?

回复

Elasticsearch陈水鱼 回复了问题 • 3 人关注 • 3 个回复 • 2397 次浏览 • 2022-11-11 11:10 • 来自相关话题

elasticsearch es如何统计用户文档数量范围内容聚合?

回复

ElasticsearchCharele 回复了问题 • 5 人关注 • 3 个回复 • 2412 次浏览 • 2022-06-01 13:42 • 来自相关话题

logstash推送数据到es执行两次脚本

回复

Logstashmedcl 回复了问题 • 2 人关注 • 1 个回复 • 2253 次浏览 • 2022-04-02 13:28 • 来自相关话题

elasticsearch 分索引后如何快速更新指定数据?

回复

Elasticsearchliujiacheng 回复了问题 • 2 人关注 • 1 个回复 • 1211 次浏览 • 2022-03-24 09:41 • 来自相关话题

segments的version_map_memory指标具体表示什么

回复

ElasticsearchCharele 回复了问题 • 3 人关注 • 2 个回复 • 1688 次浏览 • 2022-02-21 16:43 • 来自相关话题

match_phrase_prefix返回结果如何使越靠前的单词占有的权重越高,排序更靠前

回复

Elasticsearchxiaowuge 回复了问题 • 4 人关注 • 3 个回复 • 2317 次浏览 • 2022-01-25 09:01 • 来自相关话题

es的基础安全从哪个版本开始免费

回复

Elasticsearchenvy666 回复了问题 • 2 人关注 • 1 个回复 • 1401 次浏览 • 2021-11-04 08:49 • 来自相关话题

es7.6副本越少检索速度越快

回复

Elasticsearchtongchuan1992 回复了问题 • 3 人关注 • 3 个回复 • 1445 次浏览 • 2021-09-28 16:48 • 来自相关话题

ElasticSearch 同一个query查询响应时间差异大?

回复

Elasticsearchzmc 回复了问题 • 4 人关注 • 4 个回复 • 2904 次浏览 • 2021-07-21 19:33 • 来自相关话题

search after取出全量数据会比scoll更快吗

回复

Elasticsearchguoyanbiao520 回复了问题 • 7 人关注 • 6 个回复 • 3571 次浏览 • 2021-06-11 18:05 • 来自相关话题

极限网关助力好未来 Elasticsearch 容器化升级

ElasticsearchINFINI Labs 小助手 发表了文章 • 0 个评论 • 2118 次浏览 • 2024-06-12 15:01 • 来自相关话题

极限网关在好未来的最佳实践案例,轻松扛住日增百 TB 数据的流量,助力 ES 从物理机到云原生架构的改造,实现了流控、请求分析、安全管理、无缝迁移等场景。一次完美的客户体验~

背景

物理机架构时代

2022 年,好未来整个日志 Elasticsearch 拥有数十套服务集群,几百台物理机。这么多台机器耗费成本非常高,而且还要花费很大精力去维护。在人力资源有限情况下,存在非常多的弊端,运行成本高,不仅是机器折旧还有机柜等费用。

流量特征

这是来自某个业务线,如下图 1,真实流量,潮汐性非常明显。好未来有很多条业务线,几乎跟这个趋势都一致的,除了个别业务有“续报”、“开课”等活动特殊情况。潮汐性带来的问题就是高峰期 CPU、内存资源是可以消耗很高;低峰期资源使用量非常低,由于是物理架构,这些资源无法给其他业务线共享。

图1

图1

降本增效-容器化改造原动力

日志服务对成本的空前的压力促使我们推进 Elasticsearch 进行架构改造;如何改造,改造成什么样子,这两个问题一直是推进改造原动力。业界能够同时对水平扩展和垂直扩展就是 K8S,我们开始对 Elasticsearch 改造成能在 K8S 上运行进行探索,从而提升 CPU、内存利用率。

物理机时代,没办法把资源动态的扩缩,动态调配,资源隔离,单靠人力操作调度成本太高,几乎无法完成;集群对内存资源需求要比 CPU 资源大很多,由于机器型号配置是固定的,无法“定制”,这也会导致成本居高不下。所以,无论从那个方面来讲,容器化优势非常明显,既能够优化成本,也能够降低运维复杂度。

ES 容器化改造

进行架构升级重点难点- API 服务

改造过程,我们遇到了很多问题,比如容器 ES 版本和物理机 ES 版本不一致,如何让 ES API 能够兼容不同的 ES 版本,由于版本的不兼容,导致无法直接使用原有的 tribenode 进行服务,怎么提供一个高可用的 Elasticsearch API 服务。我们考虑到多个方面,比如使用官方推荐的 proxy 模式、第三方服务等进行选择,经过多方面对比,选择了极限网关 进行 tribenode 替换。

原始 ES API 服务痛点

  • API 访问没有流量控制
  • 可观测性差,而且稳定性一般
  • 版本兼容性差

物理机时代 API 架构

在物理机时代 ES 集群,API 架构如图 2,可以明显看到 tribe node 对所有 ES 集群的“侵入性”是非常大的,这就带来了很多问题,比较严重的就是单个集群对 ES tribenode 的影响和版本升级带来的不兼容问题。

图2

图2

混合时代 API 架构

通过图 3,我们可以看到,极限网关对于版本兼容性很好,能够适配不同的版本。因此,最终选择极限网关作为下一代 ES API 服务方。

图3

图3

里程碑:全部 ES 集群容器化

在 2023 年 3 月份,通过 Elastic 官方 ECK 模式,完成全部日志 ES 集群容器化改造,拥有数百节点,1PB+ 数据存储,每日新增数据 100T 左右。紧接着,除了日志服务外,同时支持了好未来多条业务线。

图4

图4

极限网关实践

下面主要讲述了,为什么选择极限网关,以及极限网关在好未来落地、应用这些内容。

为什么选择极限网关?

学习成本低

我们可以从文档中看到极限网关,其架构简洁,语法简单,直观易懂。学习成本比较低,上手非常快,对新手友好。

性能强悍

经过压测,发现极限网关速度非常快,且针对 Elasticsearch 做了非常细致的优化,能成倍提升写入和查询的速度。

安全性高

支持多种认证方式,最简单的账号密码认证,可以给自定义多个账户密码,大大简化了 Elasticsearch 的安全设置,同时,还可以支持 LDAP 安全验证。

跨版本支持

我们容器化改造过程需要兼容不同版本的 Elasticsrearch,极限网关针对不同的 Elasticsearch 版本做了兼容和针对性处理,能够让业务代码无缝的进行适配,后端 Elasticsearch 集群版本升级能够做到无缝过渡,降低版本升级和数据迁移的复杂度,非常匹配我们的业务场景。

灵活可扩展

可灵活对每个请求进行干预和路由,支持路由的智能学习,内置丰富的过滤器,通过配置动态修改每个请求的处理逻辑,也支持通过插件来进行扩展,满足我们对流量的控制,尤其是限流、用户、IP 等这些功能非常实用。

启用安全策略-为 API 服务保驾护航

痛点

在升级之前使用 tribe 作为 API 服务提供后端,几乎相当于裸奔,没有任何认证策略;另外,tribe 本身的稳定性也有问题,官方在新版本逐渐废弃这种 CCS(跨集群搜索),期间出现多次服务崩溃。

极限网关解决问题

极限网关通过,“basic_auth” 插件,提供最基本的安全校验,使用起来非常方便;同时,极限网关提供 LDAP 插件,可以接入公共的 LDAP 服务,对所有的访问用户进行校验,安全策略对所有的用户生效,不用担心因为 IP 问题泄漏数据等。

强大的过滤功能

在使用 ES 集群过程中,许多场景,需要对请求进行控制、限制等操作。在这方便,感受到了极限网关强大的产品力。比如下面的两个场景

对异常流量进行限流

  • 支持对 IP 限流
  • 支持对 hostname 限流
  • 支持 header 限流

对异常用户进行封禁

当 Elasticsearch 是通过 Basic Auth 或者 LDAP 方式来进行身份认证的时候,request_user_filter 过滤器可用来按请求的用户名信息来进行过滤。操作起来也非常简单,只需要 request_user_filter 这一个过滤器。

- request_user_filter:
    include:
        - "elastic"
    exclude:
        - "Ryan"

总结来讲,主要有这些方面的功能:

图5

图5

优秀的可观测性

痛点

改造前经常为看不到直观的数据指标感到头疼,查看指标需要多个地方同时打开,去筛选,查找,非常繁琐,付出的成本非常大。为此,大家都再考虑如何优化这种情况,无奈优先级比较低,一直没有真正的投入时间去优化这块。

完美解决

使用了极限网关,通过收集请求日志,非常清晰的收集到想要的数据,具体如下:

  • 总体方面:
    • 流量曲线
    • 状态码占比
    • 缓存统计
    • 每台网关请求流量
  • 细节方面:
    • 打印每次请求语句
    • 可以查看请求到具体 ES 节点流量
    • 可以查看过滤器的列表

通过下图,我们可以从管理视角直观的看到各种信息,这对于管理员来讲,省时省力,方便快捷。

图6

图6

意外收获:无缝迁移业务 Elasticsearch 上云

由于前期日志业务上云,受到非常好的反馈,多个业务线期望能够上云上服务,达到降本增效的目的。

支持双写

数据可以通过极限网关同时写入两个 ES 集群,能够保障数据完全一致,安全可靠。

无缝切换

切换很丝滑,影响非常小,能够让外界几乎感受不到服务波动。

图7

图7

通过使用极限网关,自建 ES 集群可以无缝的迁移上云,在整个迁移的过程中,两套集群通过网关进行了解耦,在迁移的过程中还能实现版本的无缝升级,极大降低了迁移成本,提高迁移效率,多次验证服务稳定可靠。

极限网关流量概览

这是其中一套极限网关的流量统计。用这部分数据进行巡检,一目了然,做到全局的掌控,提高感知力度。

图8

图8

极限网关使用总结

极限网关提供一系列高性能和高可靠性的网关服务。使用这样的服务给我们带来以下好处:

  1. 可观测性好:极限网关可以动态的对 Elasticsearch 运行过程中请求进行拦截和分析,通过指标和日志来了解集群运行状态,这些指标可以用于提升性能和业务优化。
  2. 增强安全性:包含先进的安全机制,如 basicauth、LDAP 等支持,保护用户数据不受未授权访问和各种网络威胁的侵害。
  3. 高稳定性:通过冗余设计和故障转移机制,极限网关能够确保网络服务的高可用性,即使在某些组件发生故障时也能保持服务不中断,单版本最长服务超过 15 个月。
  4. 易于管理:通过提供 INFINI Console 简洁直观的管理界面,让用户能够轻松配置和监控网络状态,提升管理效率。
  5. 客户支持:良好的客户服务支持可以帮助用户快速解决使用过程中遇到的问题,提供专业的技术指导。

综上所述,极限网关为用户提供了一个高速、安全、稳定且易于管理的 ES 网关,适合对网络性能有较高要求的个人和企业用户。

未来规划

第一阶段,完成了日志 ES 集群,所有集群的容器化改造,合并,成功的把成本降低了 60%以上。这期间积累了丰富容器化经验,为业务 ES 集群上容器做了良好的铺垫;成本优势和运维优势吸引越来越多的业务接入到容器化 ES 集群。

提升 ES 集群效能--新技术应用&&版本升级

  • 极限科技官方推荐的 Easysearch 在压缩率,查询速度等等方面有很多的优势,通过长时间的测试稳定性,新特性,对比云原生的 ES 集群,根据测试结果,给“客户”提供多种选择,这也是工作重点之一。
  • 我们当前使用的 ES 版本是 6.8,已经远远落后于官方版本,今年我们计划在选择合适的集群升级 ES 版本,拥抱更多官方提供的特性。

混合(多)云架构支持

随着越来越多的 ES 集群在机房的 K8S 集群部署,这里资源出现了紧张局面。 我们尝试在云上部署自建 ES 集群,弥补机房资源有限,无法大规模扩容,同时能够支持多活场景,满足更多客户的不同需求。混合云主要实现以下几种能力:

1、扩缩容:满足不同业务灵活适配

混合(多)云部署,可以让负载内部私有云 ES,同时部署到公有云,提升扩展 IT 基础设施不仅局限于 CPU、内存,还有存储。比如某一个业务要做活动,预估流量“大爆发”,需要提前准备大规模资源,在机房内根本来不及采购扩容支持,然而在公有云上就能很方便扩容、缩容。在云上搭建 ES 集群,设置满足需求的数量、容量、配置,配合极限网关路由策略,精准的把控流量流向。

图9

图9

2、灾备:紧急情况快速部署,恢复 ES 集群读写

当机房级别大规模故障,部分业务实现了多活,单一的机房故障不会影响其服务能力,而此时比如日志查看等仍有需求,为了满足这部分“客户”需求,可以在云上 K8S 集群,快速搭建 ES 集群,恢复日志读写功能。

图10

图10

参考文档:

作者:张华勋,前新浪 CDN 研发,工作主要涉及 Mysql、MongoDB、Redis、Elasticsearch、流量调度等组件和系统,以及运维自动化、平台化等工作。现就职于好未来。

关于好未来

好未来(NYSE:TAL)是一家以内容能力与科技能力为基础,以科教、科创、科普为战略方向,助力人的终身成长,并持续探索创新的科技公司。 好未来的前身学而思成立于 2003 年,2010 年在美国纽交所正式挂牌交易。好未来以“爱与科技助力终身成长”为使命,致力成为持续创新的组织。更多参见:https://www.100tal.com/

关于极限科技(INFINI Labs)

INFINI Labs

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。

极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。

官网:https://www.infinilabs.cn

联系我们

换掉ES? Redis官方搜索引擎,效率大幅提升

默认分类Fred2000 发表了文章 • 2 个评论 • 2875 次浏览 • 2024-05-30 10:08 • 来自相关话题

RediSearch是一个Redis模块,为Redis提供查询、二次索引和全文搜索。要使用RediSearch,首先要在Redis数据上声明索引。然后可以使用重新搜索查询语言来查询该数据。

RedSearch使用压缩的反向索引进行快速索引,占用内存少。RedSearch索引通过提供精确的短语匹配、模糊搜索和数字过滤等功能增强了

实现特性

  • 基于文档的多个字段全文索引
  • 高性能增量索引
  • 文档排序(由用户在索引时手动提供)
  • 在子查询之间使用 AND 或 NOT 操作符的复杂布尔查询
  • 可选的查询子句
  • 基于前缀的搜索
  • 支持字段权重设置
  • 自动完成建议(带有模糊前缀建议)
  • 精确的短语搜索
  • 在许多语言中基于词干分析的查询扩展
  • 支持用于查询扩展和评分的自定义函数
  • 将搜索限制到特定的文档字段
  • 数字过滤器和范围
  • 使用 Redis 自己的地理命令进行地理过滤
  • Unicode 支持(需要 UTF-8 字符集)
  • 检索完整的文档内容或只是ID 的检索
  • 支持文档删除和更新与索引垃圾收集
  • 支持部分更新和条件文档更新

对比 Elasticsearch

如下图所示,RediSearch 构建索引的时间为 221 秒,而 Elasticsearch 为 349 秒,快了 58%。

索引构建测试

我们模拟了一个多租户电子商务应用程序,其中每个租户代表一个产品类别并维护自己的索引。对于此基准测试,我们构建了 50K 个索引(或产品),每个索引最多存储 500 个文档(或项目),总共 2500 万个文档。

RediSearch 仅用了 201 秒就构建了索引,平均每秒运行 125K 个索引。然而,Elasticsearch 在 921 个索引后崩溃了,显然它不是为应对这种负载而设计的。

查询性能测试

一旦数据集被索引,我们就使用在专用负载生成器服务器上运行的 32 个客户端启动两个单词的搜索查询。如下图所示,RediSearch 吞吐量达到了 12.5K 操作/秒,而 Elasticsearch 为 3.1K 操作/秒,速度提高了 4 倍。

此外,RediSearch 延迟稍好一些,平均为 8 毫秒,而 Elasticsearch 为 10 毫秒。

安装

安装目前分为源码和docker安装两种方式。

源码安装

git clone https://github.com/RediSearch/RediSearch.git
cd RediSearch # 进入模块目录
make setup
make install

docker安装

note: RediSearch的安装比较复杂原包无法进行编译操作所以我们使用docker安装
docker run -p 6379:6379 redislabs/redisearch:latest

判断是否安装成功

127.0.0.1:0>module list
1) 1) "name"
   2) "ReJSON"
   3) "ver"
   4) "20007"

2) 1) "name"
   2) "search"
   3) "ver"
   4) "20209"

返回数组存在“ft”或 “search”(不同版本),表明 RediSearch 模块已经成功加载。

命令行操作

1、创建

1.1 创建索引

创建索引不妨想象成创建表结构,表一般基本属性有表名、字段和字段类别等,所以我们可以考虑将索引名代表表名,字段代表字段,属性即表示属性。

xxx.xxx.xxx.xxx:0>ft.create "student" schema "name" text weight 5.0 "sex" text "desc" text "class" tag
"OK"

student 表示索引名,name、sex、desc表示字段,text表示类型(这样表示只是为了便于理解)

“weight”为权重,默认值为 1.0

type student
"none"

我们创建的索引redis是不认识的,这证明使用的是插件。

1.2 创建文档

创建文档上下文的过程不妨想想成向表中插入数据,这里请注意字段名可以使用双引号但切记一定要用英文,这里之所以着重提出是因为有些编译器中文双引号和英文双引号用肉眼实在难以辨认否则会出现 “Fields must be specified in FIELD VALUE pairs”(其实是将“ 当作内容处理了以至于缺少了字段)

ft.add student 001 1.0 language "chinese" fields name "张三" sex "男" desc "这是一个学生" class "一班"
"OK"

其中001为文档ID,"1.0"为评分缺少此值会报"Could not parse document score"异常,language 指明使用的语言默认是英文编码 如果没有此标记存储是没有问题的但不可以通过中文字符查询

1.3 查询

1.3.1 基本查询

1.3.1.1 全量查询

xxx.xxx.xxx.xxx:0>FT.SEARCH student * SORTBY sex desc RETURN 3 name sex desc
1) "2"
2) "001"
3) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

4) "002"
5) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

1.3.1.2 匹配查询

xxx.xxx.xxx.xxx:0>ft.search student "张三" limit 0 10 RETURN 3 name sex desc
1) "2"
2) "001"
3) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

4) "002"
5) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

limit 与mysql相识主要用于分页,此处是全量匹配,如果没有设置language “chinese” 此处查询为0,

1.3.2 模糊匹配

1.3.2.1 后置匹配

ft.search student "李*"  SORTBY sex desc RETURN 3 name sex desc
1) "1"
2) "003"
3) 1) "name"
   2) "李四"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"

1.3.2.2 模糊搜索

xxx.xxx.xxx.xxx:0>FT.SEARCH beers "%%张店%%"
1) "1"
2) "beer:1"
3) 1) "name"
  2) "集团本部已发布【文明就餐公约】,2号楼办公人员午餐的就餐时间是11:45~13:00,现经行政服务部进行抽查,发现我们部门有员工违规就餐现象。请大家务必遵守,相互转告,对于外地回到集团办公的同事,亦请遵守,谢谢!"
   3) "org"
   4) "山东省淄博市张店区"
   5) "school"
   6) "山东理工大学"

别高兴太早全量模糊匹配是由很大限制的,他基于Levenshtein距离(LD)进行模糊匹配。术语的模糊匹配是通过在术语周围加“%”来实现的,模糊匹配的最大LD为3,确切的说这只是一种相识度查询,并非一般意义上的模糊搜索,但是如果仔细观察会发现通过精确匹配时不仅能够将完整value值查询出来而且还查询出其他处于文档某个位置的key请看官方提供的一个例子:

FT.CREATE idx SCHEMA txt TEXT
FT.ADD idx docCn 1.0 LANGUAGE chinese FIELDS txt

Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。

由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。

FT.CREATE idx SCHEMA txt TEXT
FT.ADD idx docCn 1.0 LANGUAGE chinese FIELDS txt "Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。[8]"
FT.SEARCH idx "数据" LANGUAGE chinese HIGHLIGHT SUMMARIZE
# Outputs:
# <b>数据</b>?... <b>数据</b>进行写操作。由于完全实现了发布... <b>数据</b>冗余很有帮助。[8...

之所以会出现这样的效果是因为redisearch对文本进行了分词,其使用的工具是friso相比es的ik还是弱一些前者主要是对中文分词,体积小可移植性强。

从而我们可以结合后后置匹配算法

xxx.xxx.xxx.xxx:0>FT.SEARCH idx "数*" LANGUAGE chinese HIGHLIGHT
1) "1"
2) "docCn"
3) 1) "txt"
  2) "Redis支持主从同步。<b>数据</b>可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。从盘可以有意无意的对<b>数据</b>进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和<b>数据</b>冗余很有帮助。[8]"

或者结合Levenshtein算法这样基本上能够满足业务查询需求

xxx.xxx.xxx.xxx:0>FT.SEARCH idx "%%单的树%%" LANGUAGE chinese HIGHLIGHT
1) "1"
2) "docCn"
3) 1) "txt"
  2) "Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层<b>树</b>复制。从盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步<b>树</b>时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。[8]"

1.3.2.3 字段查询

通过字段查询也可以实现模糊搜索,直接给例子,后面跟着官网上给的sql 和 redisearch的对照表

ft.search student *
1) "2"
2) "doudou"
3) 1) "name"
   2) "豆豆"
   3) "jtzz"
   4) "“检索”是很多产品中"
   5) "phone"
   6) "18563717107"

4) "ttao"
5) 1) "name"
   2) "姚元涛"
   3) "jtzz"
   4) "一个生病的人只"
   5) "phone"
   6) "18563717107"

ft.search student '@phone:185* @name:豆豆'
1) "1"
2) "doudou"
3) 1) "name"
   2) "豆豆"
   3) "jtzz"
   4) "“检索”是很多产品中"
   5) "phone"
   6) "18563717107"

1.4 删除

1.4.1 删除文档

xxx.xxx.xxx.xxx:0>ft.del student 002
"1"

1.4.3 删除索引

xxx.xxx.xxx.xxx:0>ft.drop student
"OK"

1.5 查看

1.5.1 查看所有索引

xxx.xxx.xxx.xxx:0>FT._LIST
1) "student1"
2) "ttao"
3) "idx"
4) "student"
5) "myidx"
6) "123"
7) "myIndex"
8) "testung"
9) "student2"

1.5.2 查看索引文档中的数据

1.5.2.1 获取单条数据

xxx.xxx.xxx.xxx:0>ft.get student 001
1) "name"
2) "张三"
3) "sex"
4) "男"
5) "desc"
6) "这是一个学生"
7) "class"
8) "一班"

1.5.2.2 获取多条数据

xxx.xxx.xxx.xxx:0>ft.mget student 001 002
1) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"
   7) "class"
   8) "一班"

2) 1) "name"
   2) "张三"
   3) "sex"
   4) "男"
   5) "desc"
   6) "这是一个学生"
   7) "class"
   8) "一班"

1.6 索引别名操作

1.6.1 添加别名

123.232.112.84:0>FT.ALIASADD xs student
"OK"

给索引student起个xs的别名,一个索引可以起多个别名

1.6.2 修改别名

1.6.3 删除别名

123.232.112.84:0>FT.ALIASDEL xs 
"OK"

作者:架构师公众号

来源:https://mp.weixin.qq.com/s/TmCXx3rLjLPggvOFjGqS9w

版权申明:内容来源网络,仅供学习研究,版权归原创者所有。如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

记某客户的一次 Elasticsearch 无缝数据迁移

Elasticsearchyangmf2040 发表了文章 • 0 个评论 • 3757 次浏览 • 2024-04-02 14:16 • 来自相关话题

背景

客户需要将 Elasticsearch 集群无缝迁移到移动云,迁移过程要保证业务的最小停机时间。

实现方式

通过采用成熟的 INFINI 网关来进行数据的双写,在集群的切换恢复过程中来记录数据变更,待全量数据恢复之后再追平后面增量数据,追平增量之后,进行校验确保数据一致再进行流量的切换。

总体流程

总体迁移流程如下:

  1. 客户业务代码,切流量,双写。(新增的变更都会记录在网关本地,但是暂停消费到移动云)
  2. 暂停网关移动云这边的增量数据消费。
  3. 迁移 11 月的数据,快照,快照上传到 S3;
  4. 下载 S3 的文件到移动云。
  5. 恢复快照到移动云的 11 月份的索引。
  6. 开启网关移动云这边的增量消费。
  7. 等待增量追平(接近追平)。
  8. 按照时间条件(如:时间 A,当前时间往前 30 分钟),验证文档数据量,Hash 校验等等。
  9. 停业务的写入,网关,腾讯云的写入(10 分钟)。
  10. 等待剩余的增量追完。
  11. 对时间 A 之后的,增量进行校验。
  12. 切换所有流量到移动云,业务端直接访问移动云 ES。

总体的迁移时间:

  1. 11 月备份时间(30 分钟)19 号开始
  2. 备份下载到移动云的时间(2-3 天)
  3. 备份恢复到移动云集群的时间(30 分钟)
  4. 11 月份增量备份(20 分钟)(双写开始)(21 号)
  5. 11 月份增量下载到移动云(6 小时)
  6. 11 月份增量恢复时间(20 分钟)
  7. 追增量数据(8 个小时产生的数据,需要 1 个小时)
  8. 校验比对(存量 1 个小时)
  9. 流量暂停,增量的校验(10 分钟)
  10. 切换(1 分钟)

总体流程如下示意图:

ES 集群信息

  1. ES 版本 7.10.1
  2. 2个热节点 3个温节点  总数 1.9 TB
  3. 索引   1041, 分片2085
  4. 无自定义插件
  5. 有 update_bu_query 使用
  6. 有 delete_by_query 使用
  7. 吞吐量没有测试过,当前日增文档数 1 千多万,目标日增加上亿  

    迁移操作手册(参考)

    环境

  • 自建 ES 5.4.2
  • 自建 ES 5.6.8
  • 自建 ES 7.5.0
  • 极限网关服务器 1
  • 极限网关服务器 2
  • 云端负载均衡 1 (监听 9200 端口,指向极限网关服务器 1/2 的 8000 端口)
  • 云端负载均衡 2 (监听 9200 端口,指向极限网关服务器 1/2 的 8001 端口)

    场景描述

    若干个自建 Elasticsearch 集群需要平滑迁移到移动云,业务不停写、不做代码改动。

    数据架构

    通过将应用端流量走网关的方式,请求同步转发给自建 ES,网关记录所有的写入请求,并确保顺序在云端 ES 上重放请求,两侧集群的各种故障都妥善进行了处理,从而实现透明的集群双写,实现安全无缝的数据迁移。 业务端如果已经部署在云上,可以使用云上的 SLB 服务来访问网关,确保后端网关的高可用,如果业务端和极限网关还在企业内网,可以使用极限网关自带的 4 层浮动 IP 来确保网关的高可用

数据描述

以数据从自建集群 5.4.2 迁移到云上的 5.6.16 为例进行说明,执行步骤依次说明。

执行步骤

部署 INFINI Gateway

为了保证数据的无缝透明迁移,通过 INFINI Gateway 来进行双写。

  1. 系统调优

    参考此文档

  2. 下载程序
    
    [root@iZbp1gxkifg8uetb33pvcoZ ~]# mkdir /opt/gateway
    [root@iZbp1gxkifg8uetb33pvcoZ ~]# cd /opt/gateway/
    [root@iZbp1gxkifg8uetb33pvcoZ gateway]# wget http://release.infinilabs.com/gateway/snapshot/gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz
    --2022-05-19 10:16:25--  http://release.infinilabs.com/gateway/snapshot/gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz
    正在解析主机 release.infinilabs.com (release.infinilabs.com)... 120.79.205.193
    正在连接 release.infinilabs.com (release.infinilabs.com)|120.79.205.193|:80... 已连接。
    已发出 HTTP 请求,正在等待回应... 200 OK
    长度:7430568 (7.1M) [application/octet-stream]
    正在保存至: “gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz”

100%[==============================================================================================================================================>] 7,430,568 22.8MB/s 用时 0.3s

2022-05-19 10:16:25 (22.8 MB/s) - 已保存 “gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz” [7430568/7430568])

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# tar vxzf gateway-1.6.0_SNAPSHOT-649-linux-amd64.tar.gz gateway-linux-amd64 gateway.yml sample-configs/ sample-configs/elasticsearch-with-ldap.yml sample-configs/indices-replace.yml sample-configs/record_and_play.yml sample-configs/cross-cluster-search.yml sample-configs/kibana-proxy.yml sample-configs/elasticsearch-proxy.yml sample-configs/v8-bulk-indexing-compatibility.yml sample-configs/use_old_style_search_response.yml sample-configs/context-update.yml sample-configs/elasticsearch-route-by-index.yml sample-configs/hello_world.yml sample-configs/entry-with-tls.yml sample-configs/javascript.yml sample-configs/log4j-request-filter.yml sample-configs/request-filter.yml sample-configs/condition.yml sample-configs/cross-cluster-replication.yml sample-configs/secured-elasticsearch-proxy.yml sample-configs/fast-bulk-indexing.yml sample-configs/es_migration.yml sample-configs/index-docs-diff.yml sample-configs/rate-limiter.yml sample-configs/async-bulk-indexing.yml sample-configs/elasticssearch-request-logging.yml sample-configs/router_rules.yml sample-configs/auth.yml sample-configs/index-backup.yml


3. 修改配置

将网关提供的示例配置拷贝,并根据实际集群的信息进行相应的修改,如下:

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# cp sample-configs/cross-cluster-replication.yml 5.4.2TO5.6.16.yml

首先修改集群的身份信息,如下:
![](https://www.infinilabs.com/img/blog/2024/seamless-data-migration/3.png)

然后修改集群的注册信息,如下:
![](https://www.infinilabs.com/img/blog/2024/seamless-data-migration/4.png)

根据需要修改网关监听的端口,以及是否开启 TLS (如果应用客户端通过 http 协议访问 ES,请将entry.tls.enabled 值改为 false),如下:
![](https://www.infinilabs.com/img/blog/2024/seamless-data-migration/5.png)
不同的集群可以使用不同的配置,分别监听不同的端口,用于业务的分开访问。

4. 启动网关

启动网关并指定刚刚创建的配置,如下:

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# ./gateway-linux-amd64 -config 5.4.2TO5.6.16.yml


/ \ /\ / \/\/ / /\ \ \/\ /_/\ / /\///\ / /\/\ \ \/ \/ //\_ / / /\/ \/ / // \ /\ / \/ \ ___/\/ \/\/ \/ \/ \/_/ _/_/

[GATEWAY] A light-weight, powerful and high-performance elasticsearch gateway. [GATEWAY] 1.6.0_SNAPSHOT, 2022-05-18 11:09:54, 2023-12-31 10:10:10, 73408e82a0f96352075f4c7d2974fd274eeafe11 [05-19 13:35:43] [INF] [app.go:174] initializing gateway. [05-19 13:35:43] [INF] [app.go:175] using config: /opt/gateway/5.4.2TO5.6.16.yml. [05-19 13:35:43] [INF] [instance.go:72] workspace: /opt/gateway/data1/gateway/nodes/ca2tc22j7ad0gneois80 [05-19 13:35:43] [INF] [app.go:283] gateway is up and running now. [05-19 13:35:50] [INF] [actions.go:358] elasticsearch [primary] is available [05-19 13:35:50] [INF] [api.go:262] api listen at: http://0.0.0.0:2900 [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [primary] hosts: [] => [192.168.0.19:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [backup] hosts: [] => [es-cn-tl32p9fkk0006m56k.elasticsearch.aliyuncs.com:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [primary] hosts: [] => [192.168.0.19:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [backup] hosts: [] => [es-cn-tl32p9fkk0006m56k.elasticsearch.aliyuncs.com:9200] [05-19 13:35:50] [INF] [reverseproxy.go:261] elasticsearch [primary] hosts: [] => [192.168.0.19:9200] [05-19 13:35:50] [INF] [entry.go:322] entry [my_es_entry/] listen at: https://0.0.0.0:8000 [05-19 13:35:50] [INF] [module.go:116] all modules are started


5. 后台运行

[root@iZbp1gxkifg8uetb33pvcoZ gateway]# nohup ./gateway-linux-amd64 -config 5.4.2TO5.6.16.yml &


6. 应用授权

curl -XPOST http://localhost:2900/_license/apply -d' { "license": "XXXXXXXXXXXXXXXXXXXXXXXXX" }'

#### 部署 INFINI Console
为了方便在多个集群之间快速切换,使用 INFINI [Console](https://infinilabs.cn/products/console/) 来进行管理。

1. 下载安装

[root@iZbp1gxkifg8uetb33pvcpZ console]# wget http://release.infinilabs.com/console/snapshot/console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz --2022-05-19 10:57:24-- http://release.infinilabs.com/console/snapshot/console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz 正在解析主机 release.infinilabs.com (release.infinilabs.com)... 120.79.205.193 正在连接 release.infinilabs.com (release.infinilabs.com)|120.79.205.193|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度:13576234 (13M) [application/octet-stream] 正在保存至: “console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz”

100%[==============================================================================================================================================>] 13,576,234 33.2MB/s 用时 0.4s

2022-05-19 10:57:25 (33.2 MB/s) - 已保存 “console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz” [13576234/13576234])

[root@iZbp1gxkifg8uetb33pvcpZ console]# tar vxzf console-0.3.0_SNAPSHOT-596-linux-amd64.tar.gz console-linux-amd64 console.yml


2. 修改配置

[root@iZbp1gxkifg8uetb33pvcpZ console]# cat console.yml

for the system cluster, please use Elasticsearch v7.3+

elasticsearch:

  1. 启动服务

    [root@iZbp1gxkifg8uetb33pvcpZ console]# ./console-linux-amd64 -service install
    Success
    [root@iZbp1gxkifg8uetb33pvcpZ console]# ./console-linux-amd64 -service start
    Success
  2. 访问后台

访问该主机的 9000 端口,即可打开 Console 后台,http://x.x.x.x:9000/ 打开菜单 [System][Cluster] ,注册当前需要管理的 Elasticsearch 集群和网关地址,用来快速管理,如下:

测试 INFINI Gateway

为了验证网关是否正常工作,我们通过 INFINI Console 来快速验证一下。 首先通过走网关的接口来创建一个索引,并写入一个文档,如下: 查看 5.4.2 集群的数据情况,如下: 查看集群 5.6.16 的数据情况,如下: 说明网关配置都正常,验证结束。

调整网关的消费策略

因为我们需要在全量数据迁移之后,才能进行增量数据的追加,在全量数据迁移完成之前,我们应该暂停增量数据的消费。修改网关配置里面 Pipeline consume-queue_backup-to-backupconsume-queue_primary-failure-to-backup的参数 auto_startfalse,表示不自动启动该任务,具体配置方法如下: 修改完配置之后,需要重新启动网关。 为了方便管理,可以使用 INFINI Console 来注册和管理网关,如下: 待全量迁移完成之后,可以通过后台的 Task 管理来进行后续的任务启动、停止,如下:

切换流量

接下来,将业务正常写的流量切换到网关,也就是需要把之前指向 ES 5.4.2 的地址指向网关的地址,如果 5.4.2 集群开启了身份验证,业务端代码同样需要传递身份信息,和 5.4.2 之前的用法保持不变。 切换流量到网关之后,用户的请求还是以同步的方式正常访问自建集群,网关记录到的请求会按顺序记录到 MQ 里面,但是消费是暂停状态。 如果业务端代码使用的 ES 的 SDK 支持 Sniff,并且业务代码开启了 Sniff,那么应该关闭 Sniff,避免业务端通过 Sniff 直接链接到后端的 ES 节点,所有的流量现在应该都只通过网关来进行访问。

全量数据迁移

在流量迁移到网关之后,我们开始对自建 Elasticsearch 集群的数据进行全量迁移到云端 Elasticsearch 集群。 全量迁移已有的数据的方式有很多种:

  • 通过快照的方式进行恢复
  • 使用工具来导出导入,如: ESM

如果索引数量很多的话,可以按照索引依次进行导入,同时需要注意将 Mapping 和 Setting 提前导入。 以现在 5.4 集群的索引来为例,目前的待迁移索引为 demo_5_4_2,只有4 个文档: 我们使用网关自带的迁移功能来进行数据迁移,拷贝自带的样例文件,如下:

[root@iZbp1gxkifg8uetb33pvcpZ gateway]# cp sample-configs/es_migration.yml  5.4TO5.6.yml

修改其中代表集群和索引的相关配置,可以根据需要配置是否需要重命名索引和统一 Type( 用于跨版本统一 Type),如下图红框位置: 创建好模板和索引,如果目标集群不允许动态创建文档,需要提前创建好索引,如下图: 然后就可以开始数据的迁移了,执行网关程序并指定刚刚定义的配置,如下: 执行完成后,可以确认下数据的情况,如下图: 全量数据至此导入完成。

增量数据迁移

在全量导入的过程中,可能存在数据的增量修改,不过这部分请求都已经完整记录下来了,我们只需要开启网关的消费任务即可将挤压的请求应用到云端的 Elasticsearch 集群。 示例操作如下: 如果从 5.6 的集群来看的话,这部分的修改还没同步过来,如下: 这部分增量的数据变更,在网关层面都进行了完整记录,我们只需要开启网关的增量消费任务,如下: 通过观察队列是否消费完成来判断增量数据是否做完,如下: 现在我们再看一下 5.6 集群的数据情况,如下: 数据的增量更新就过来了。

执行数据比对

由于集群内部的数据可能比较多,我们需要进行一个完整的比对才能确保数据的完整性,可以通过网关自带的数据比对工具来进行,将样例自带的文件拷贝一份,如下:

[root@iZbp1gxkifg8uetb33pvcpZ gateway]# cp sample-configs/index-docs-diff.yml  5.4DIFF5.6.yml

修改需要比对的集群和索引信息,可以加上过滤条件,如时间范围窗口来进行增量 Diff,如下图:

执行网关程序,并指定该配置文件,如下图: 如图,两个集群完全一致。

切换集群

如果验证完之后,两个集群的数据已经完全一致了,可以将程序切换到新集群,或者将网关的配置里面的主备进行互换,同步写 5.6 集群。 双集群在线运行一段时间,待业务完全验证之后,再安全下线旧集群,如遇到问题,也可以随时回切到老集群。

小结

通过使用极限网关,自建 ES 集群可以安全无缝的迁移到移动云 ES,在迁移的过程中,两套集群通过网关进行了解耦,两套集群的版本也可以不一样,在迁移的过程中还能实现版本的无缝升级。 如有任何问题,请随时联系我,期待与您交流!

Elasticsearch 国产化

Easysearchyangmf2040 发表了文章 • 0 个评论 • 1613 次浏览 • 2024-03-16 16:36 • 来自相关话题

背景

Elasticsearch 这些年来在搜索领域一直是领头羊。国内也有非常多的企业在使用 Elasticsearch 来做查询搜索、数据分析、安全分析等等。甚至一些很重要的行业、系统都在使用 Elasticsearch。在使用 Elasticsearch 的道路上狂飙的时候,我们也观察到了一些问题:

  1. Elasticsearch 不再是开源软件了。
  2. Elastic 公司退出了中国直销市场,不提供本土化支持了。
  3. 国家对信创、自主可控的战略化布局。
  4. 国际形势从合作共赢到自闭对垒。
  5. Elasticsearch 软件本身安全问题频发。
  6. Elasticsearch 软件在性能、稳定性和扩展性方面存在很大的提升空间。

基于以上这些问题,推出一个 Elasticsearch 国产化解决方案就很有必要了。我们的解决方案是推出一款名为 Easysearch 的软件,作为 Elasticsearch 国产化替代 。
出发点是在兼容原 Elasticsearch 软件的基础之上,完善更多的企业级功能,同时提高产品的性能、稳定性和扩展性。
下面我将从几个方面简单介绍下 Easysearch 软件。

兼容性

支持原生 Elasticsearch 的 DSL 查询语法,原业务代码无需调整。 支持 SQL ,方便熟悉 SQL 的开发人员上手分析数据。 兼容 Elasticsearch 的 SDK。 兼容现有索引存储格式。 支持冷热架构和索引生命周期,真正做到无缝衔接。

功能增强

提供企业级的安全管理,可对接 LDAP、AD 认证。 重构分布式架构,保持稳定的同时,能支持更大规模的数据。 在不降低性能的同时,实现更高压缩比的数据压缩,直接节省磁盘 40% 以上。 支持 KNN、异步搜索、数据脱敏、可搜索快照、审计等企业级功能。

容灾

支持基于 CDC 的集群复制技术,实现同版本间的容灾。
支持基于请求双写的复制技术,实现跨版本容灾。

信创

全面适配国产 CPU、操作系统,并获得厂家认证。

迁移方案

支持原索引存储格式,可通过快照备份直接恢复到 Easysearch 集群。
提供迁移工具,直接可视化操作迁移数据。

简单的介绍就到这里了,更多信息请访问:https://www.infinilabs.com/products/easysearch

最后

如有需要请联系我,让我们一起位祖国的信创事业添砖加瓦。

如何防止 Elasticsearch 服务 OOM?

Easysearchyangmf2040 发表了文章 • 0 个评论 • 2151 次浏览 • 2024-02-26 10:12 • 来自相关话题

Elasticsearch(简称:ES) 和传统关系型数据库有很多区别, 比如传统数据中普遍都有一个叫“最大连接数”的设置。目的是使数据库系统工作在可控的负载下,避免出现负载过高,资源耗尽,谁也无法登录的局面。

那 ES 在这方面有类似参数吗?答案是没有,这也是为何 ES 会被流量打爆的原因之一。

针对大并发访问 ES 服务,造成 ES 节点 OOM,服务中断的情况,极限科技旗下的 INFINI Gateway 产品(以下简称 “极限网关”)可从两个方面入手,保障 ES 服务的可用性。

  1. 限制最大并发访问连接数。
  2. 限制非重要索引的请求速度,保障重要业务索引的访问速度。

下面我们来详细聊聊。

架构图

所有访问 ES 的请求都发给网关,可部署多个网关。

限制最大连接数

在网关配置文件中,默认有最大并发连接数限制,默认最大 10000。

entry:
  - name: my_es_entry
    enabled: true
    router: my_router
    max_concurrency: 10000
    network:
      binding: $[[env.GW_BINDING]]
      # See `gateway.disable_reuse_port_by_default` for more information.
      reuse_port: true

使用压测程序测试,看看到达10000个连接后,能否限制新的连接。 超过的连接请求,被丢弃。更多信息参考官方文档

限制索引写入速度

我们先看看不做限制的时候,测试环境的写入速度,在 9w - 15w docs/s 之间波动。虽然峰值很高,但不稳定。 接下来,我们通过网关把写入速度控制在最大 1w docs/s 。 对网关的配置文件 gateway.yml ,做以下修改。

env: # env 下添加
    THROTTLE_BULK_INDEXING_MAX_BYTES: 40485760 #40MB/s
    THROTTLE_BULK_INDEXING_MAX_REQUESTS: 10000 #10k docs/s
    THROTTLE_BULK_INDEXING_ACTION: retry #retry,drop
    THROTTLE_BULK_INDEXING_MAX_RETRY_TIMES: 10 #1000
    THROTTLE_BULK_INDEXING_RETRY_DELAY_IN_MS: 100 #10

router: # route 部分修改 flow
  - name: my_router
    default_flow: default_flow
    tracing_flow: logging_flow
    rules:
      - method:
          - "*"
        pattern:
          - "/_bulk"
          - "/{any_index}/_bulk"
        flow:
          - write_flow

flow: #flow 部分增加下面两段    
  - name: write_flow
    filter:
      - flow:
          flows:
            - bulking_indexing_limit
      - elasticsearch:
          elasticsearch: prod
          max_connection_per_node: 1000
  - name: bulking_indexing_limit
    filter:
      - bulk_request_throttle:
          indices:
            "test-index":
              max_bytes: $[[env.THROTTLE_BULK_INDEXING_MAX_BYTES]]
              max_requests: $[[env.THROTTLE_BULK_INDEXING_MAX_REQUESTS]]
              action: $[[env.THROTTLE_BULK_INDEXING_ACTION]]
              retry_delay_in_ms: $[[env.THROTTLE_BULK_INDEXING_RETRY_DELAY_IN_MS]]
              max_retry_times: $[[env.THROTTLE_BULK_INDEXING_MAX_RETRY_TIMES]]
              message: "bulk writing too fast" #触发限流告警message自定义
              log_warn_message: true

再次压测,test-index 索引写入速度被限制在了 1w docs/s 。

限制多个索引写入速度

上面的配置是针对 test-index 索引的写入速度控制。如果想添加其他的索引,新增一段配置即可。 比如,我允许 abc 索引写入达到 2w docs/s,test-index 索引最多不超过 1w docs/s ,可配置如下。

  - name: bulking_indexing_limit
    filter:
      - bulk_request_throttle:
          indices:
            "abc":
              max_requests: 20000
              action: drop
              message: "abc doc写入超阈值" #触发限流告警message自定义
              log_warn_message: true
            "test-index":
              max_bytes: $[[env.THROTTLE_BULK_INDEXING_MAX_BYTES]]
              max_requests: $[[env.THROTTLE_BULK_INDEXING_MAX_REQUESTS]]
              action: $[[env.THROTTLE_BULK_INDEXING_ACTION]]
              retry_delay_in_ms: $[[env.THROTTLE_BULK_INDEXING_RETRY_DELAY_IN_MS]]
              max_retry_times: $[[env.THROTTLE_BULK_INDEXING_MAX_RETRY_TIMES]]
              message: "bulk writing too fast" #触发限流告警message自定义
              log_warn_message: true

限速效果如下

限制读请求速度

我们先看看不做限制的时候,测试环境的读取速度,7w qps 。 接下来我们通过网关把读取速度控制在最大 1w qps 。 继续对网关的配置文件 gateway.yml 做以下修改。

  - name: default_flow
    filter:
      - request_path_limiter:
          message: "Hey, You just reached our request limit!"                                      rules:      
            - pattern: "/(?P<index_name>abc)/_search"                          
              max_qps: 10000
              group: index_name                                    
      - elasticsearch: 
          elasticsearch: prod                            
          max_connection_per_node: 1000

再次进行测试,读取速度被限制在了 1w qps 。

限制多个索引读取速度

上面的配置是针对 abc 索引的写入速度控制。如果想添加其他的索引,新增一段配置即可。 比如,我允许 abc 索引读取达到 1w qps,test-index 索引最多不超过 2w qps ,可配置如下。

  - name: default_flow
    filter:
      - request_path_limiter:
          message: "Hey, You just reached our request limit!"
          rules:
            - pattern: "/(?P<index_name>abc)/_search"
              max_qps: 10000
              group: index_name
            - pattern: "/(?P<index_name>test-index)/_search"
              max_qps: 20000
              group: index_name
      - elasticsearch:
          elasticsearch: prod
          max_connection_per_node: 1000

多个网关限速

限速是每个网关自身的控制,如果有多个网关,那么后端 ES 集群收到的请求数等于多个网关限速的总和。 本次介绍就到这里了。相信大家在使用 ES 的过程中也遇到过各种各样的问题。欢迎大家来我们这个平台分享自己的问题、解决方案等。如有任何问题,请随时联系我,期待与您交流!

用 Easysearch 帮助大型车企降本增效

Easysearchyangmf2040 发表了文章 • 0 个评论 • 4439 次浏览 • 2024-02-02 15:15 • 来自相关话题

最近某头部汽车集团需要针对当前 ES 集群进行优化,背景如下: ES 用于支撑包括核心营销系统、管理支持系统、财务类、IT 基础设施类、研发、自动驾驶等多个重要应用,合计超 50 余套集群,累计数据超 1.5PB 。 本文针对其中一个 ES 集群进行分享,该集群原本使用的是 ES 7.3.2 免费版,数据已经 130TB 了,14 个节点。写入数据时经常掉节点,写入性能也不稳定,当天的数据写不完。迫切需要新的解决方案。 分析业务场景后总结需求要点:主要是写,很少查。审计需求,数据需要长期保存。 这个需求比较普遍,处理起来也很简单:

  • 使用 Easysearch 软件,只需少量节点存储近两天的数据。
  • 索引设置开启 ZSTD 压缩功能,节省磁盘空间。
  • 每天索引数据写完后,第二天执行快照备份存放到 S3 存储。
  • 备份成功后,删除索引释放磁盘空间。
  • 需要搜索数据时,直接从快照搜索。

将近期的数据,存放到本地磁盘,保障写入速度。写入完毕的索引,在执行快照备份后,可删除索引,释放本地磁盘空间。

Easysearch 配置要点

path.repo: ["/S3-path"]
node.roles: ["data","search"]
node.search.cache.size: 500mb
  • path.repo : 指定 S3 存储路径,上传快照用。
  • node.roles : 只有 search 角色的节点,才能去搜索快照中的数据。
  • node.search.cache.size : 执行快照搜索时的,缓存大小。

更多信息请参考官方文档

旧数据迁移

通过 Console 将原 ES 集群的数据,迁移到新 Easysearch 集群。迁移时,复制 mapping 和 setting,并在 setting 中添加如下设置。

"codec": "ZSTD",
"source_reuse": true,

原索引数据量大,可拆分成多个小任务。 迁移完,索引存储空间一般节省 50% 左右。 原索引 279GB ,迁移完后 138GB。

搜索快照数据

挂载快照后,搜索快照里的索引和搜索本地的索引,语法完全一样。 如何判断一个索引是在快照还是本地磁盘呢?可以查看索引设置里的 settings.index.store.type 如果是 remote_snapshot ,说明是快照中的数据。如果是空值,则是集群本地的数据。
这次迁移,节省了 6 台主机资源。更重要的是,用上对象存储后,主机磁盘空间压力骤减。
这次介绍就到这里了,有问题联系我。

关于 Easysearch

Easysearch

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。

官网文档:https://infinilabs.com/docs/latest/easysearch

【搜索客社区日报】第1769期 (2024-01-05)

社区日报laoyang360 发表了文章 • 0 个评论 • 2922 次浏览 • 2024-01-05 15:41 • 来自相关话题

1、一个Elasticsearch 监控 vue 客户端(昨天还在更新) https://github.com/cars10/elasticvue 2、Elasticsearch 系统设计小抄 https://betterprogramming.pub/ ... 60463 https://towardsdatascience.com ... ebfff 3、CKibana——为了能够在原生kibana上直接使用ElasticSearch语法查询ClickHouse的服务 https://github.com/TongchengOpenSource/ckibana 4、从 Elasticsearch 7.17 迁移到 Elasticsearch 8.x:陷阱和经验教训 https://engineering.zalando.co ... .html 编辑:铭毅天下  更多资讯:http://news.searchkit.cn

开启安全功能 ES 集群就安全了吗?

Easysearchyangmf2040 发表了文章 • 0 个评论 • 3184 次浏览 • 2023-12-27 10:38 • 来自相关话题

背景

经常跟 ES 打交道的朋友都知道,现在主流的 ES 集群安全方案是:RBAC + TLS for Internal + HTTPS 。

作为终端用户一般只需要关心用户名和密码就行了。作为管理和运维 ES 的人员来说,可能希望 ES 能提供密码策略来强制密码强度和密码使用周期。遗憾的是 ES 对密码强度和密码使用周期没有任何强制要求。如果不注意,可能我们天天都在使用“弱密码”或从不修改的密码(直到无法登录)。而且 ES 对连续的认证失败,不会做任何处理,这让 ES 很容易遭受暴力破解的入侵。

那还有没有别的办法,进一步提高安全呢? 其实,网关可以来帮忙。

虽然网关无法强制提高密码复杂度,但可以提高 ES 集群被暴力破解的难度。

大家都知道,暴力破解--本质就是不停的“猜”你的密码。以现在的 CPU 算力,一秒钟“猜”个几千上万次不过是洒洒水,而且 CPU 监控都不带波动的,很难发现异常。从这里入手,一方面,网关可以延长认证失败的过程--延迟返回结果,让破解不再暴力。另一方面,网关可以记录认证失败的情况,做到实时监控,有条件的告警。一旦出现苗头,可以使用网关阻断该 IP 或用户发来的任何请求。

场景模拟

首先,用网关代理 ES 集群,并在 default_flow 中增加一段 response_status_filter 过滤器配置,对返回码是 401 的请求,跳转到 rate_limit_flow 进行降速,延迟 5 秒返回。

  - name: default_flow
    filter:
      - elasticsearch:
          elasticsearch: prod
          max_connection_per_node: 1000
      - response_status_filter:
          exclude:
            - 401
          action: redirect_flow
          flow: rate_limit_flow
  - name: rate_limit_flow
    filter:
      - sleep:
          sleep_in_million_seconds: 5000

其次,对于失败的认证,我们可以通过 Console 来做个看板实时分析,展示。

折线图、饼图图、柱状图等,多种展示方式,大家可充分发挥。

最后,可在 Console 的告警中心,配置对应的告警规则,实时监控该类事件,方便及时跟进处置。

效果测试

先带上正确的用户名密码测试,看看返回速度。

0.011 秒返回。再使用错误的密码测试。

整整 5 秒多后,才回返结果。如果要暴力破解,每 5 秒钟甚至更久才尝试一个密码,这还叫暴力吗?

看板示例

此处仅仅是抛砖引玉,欢迎大家发挥想象。

告警示例

建立告警规则,用户 1 分钟内超过 3 次登录失败,就产生告警。

可在告警中心查看详情,也可将告警推送至微信、钉钉、飞书、邮件等。

查看告警详情,是 es 用户触发了告警。

最后,剩下的工作就是对该账号的处置了。如果有需要可以考虑阻止该用户或 IP 的请求,对应的过滤器文档在这里,老规矩加到 default_flow 里就行了。

如果小伙伴有其他办法提升 ES 集群安全,欢迎和我们一起讨论、交流。我们的宗旨是:让搜索更简单!

给 ES 插上向量检索的翅膀 | DataFunSummit 2023 峰会演讲内容速达

Elasticsearchliaosy 发表了文章 • 0 个评论 • 1506 次浏览 • 2023-07-12 18:37 • 来自相关话题

近日,由 DataFun 主办的 DataFunSummit 2023 数据基础架构峰会 圆满落下帷幕,本次峰会邀请了腾讯、百度、字节、极限科技、Zilliz 等众多企业技术专家为大家带来分布式存储以及向量数据库的架构原理、性能优化与实践解析分享。

向量数据库架构与实践论坛 中,极限科技搜索引擎研发工程师张磊受邀出席做了《给 ES 插上向量检索的翅膀》的主题演讲。据介绍,本次演讲主要介绍了 Elasticsearch(ES)与向量技术的融合,展示其在不同行业中的应用场景和优势,同时也对 ES 与向量的技术细节进行详细讨论,并通过具体案例演示如何利用向量提升搜索能力。

讲师介绍

张磊,极限科技 Easysearch 引擎研发工程师,2013 年开始接触 Elasticsearch,10 余年搜索相关经验,之前主要做一些围绕 Elasticsearch 在日志检索和公安大数据相关业务的开发,对 Elasticsearch 和 Lucene 源码比较熟悉,目前专注于公司内部搜索产品的开发。

《给 ES 插上向量检索的翅膀》PPT 内容

更多 PPT 内容参见 https://elasticsearch.cn/slides/322

关于 Easysearch

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 衍生自基于开源协议 Apache 2.0 的 Elasticsearch 7.10 版本。Easysearch 的目标是提供一个轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和继续保持其产品的简洁与易用性。

官网文档:https://www.infinilabs.com/docs/latest/easysearch

下载地址:https://www.infinilabs.com/download

INFINI 产品更新啦 20220923

资讯动态liaosy 发表了文章 • 0 个评论 • 1939 次浏览 • 2022-09-23 22:47 • 来自相关话题

INFINI Labs 产品更新发布

今天 INFINI Labs 为大家又带来了一波产品更新,请查阅。

INFINI Gateway v1.8.0

极限网关本次迭代更新如下:

  • 修复上下文条件 consumer_has_lag参数和 配置、文档不一致的 Bug。
  • 修改备集群故障,主集群不能正常写数据的 Bug。
  • 修复 Bulk 请求处理异常造成数据复制不一致的问题。
  • 修复请求日志里面关于 Bulk 统计数据丢失的问题。
  • 修复大并发情况下,请求体为空的异常。

INFINI Console v0.6.0

口碑爆棚的 Elasticsearch 多集群管控平台 INFINI Console 更新如下:

  • 新增主机概览。

1-640.png

  • 新增主机监控。

2-640.png

  • 节点概览新增日志查看功能(需安装 Agent)。

3-640.png

  • Insight 配置框新增 Search 配置。
  • 优化 Discover 时间范围 Auto Fit,设为15分钟。
  • 优化 Discover 保存搜索,会保存当前的字段过滤和 Insight 图表配置。
  • 优化本地列表搜索查找,支持通配符过滤。
  • 优化告警规则必填字段标记显示。
  • 修复了 Discover 字段过滤白屏问题。
  • 修复了 Discover 表格添加字段后排序失效问题。(感谢@卢宝贤反馈)
  • 修复了 Elasticsearch 8.x 删除文档报错不兼容的问题。(感谢@卢宝贤反馈)
  • 修复了创建新索引不成功时,异常处理的问题。
  • 修复了低版本浏览器js不兼容导致集群注册不成功的问题。
  • 修复了开发工具中使用加载命令失败报错的问题。

INFINI Agent v0.2.0

数据采集工具探针(INFINI Agent)更新如下:

  • 新增按节点读日志文件列表的API
  • 新增读具体日志文件内容的API
  • 新增 Elasticsearch 节点掉线后的基础信息保存
  • 新增主机在线状态的采集
  • 新增基于 Centos 的 Docker 镜像
  • 新增主机配置信息采集: 操作系统信息、磁盘大小、内存大小、CPU配置等
  • 新增主机指标的采集: CPU使用率、磁盘使用率、磁盘IO、内存使用率、swap 使用率、网络IO等
  • 新增 Elasticsearch 进程信息采集
  • 修复发现 Elasticsearch 进程时频繁提示端口访问错误的Bug
  • 修复 Elasticsearch 节点地址为 0.0.0.0 时无法获取节点信息的Bug
  • 修复 CPU 指标数据显示异常的Bug
  • 修复 stats API 在 Windows 平台的兼容性

INFINI Framework 2000923

INFINI Framework 也带来了很多改进:

  • 重构了磁盘队列压缩相关配置,支持段文件的压缩。
  • 当集群不可用的情况下,跳过集群节点元数据的获取。
  • 完善节点可用性检测,避免频繁的不可用状态切换。
  • 修复 Elasticsearch 主机地址为空的异常。
  • 完善本地磁盘队列文件的清理,避免删除正在使用的文件。

期待反馈

如果您在使用过程中遇到如何疑问或者问题,欢迎前往 INFINI Labs Github(https://github.com/infinilabs)中的对应项目中提交 Feature Request 或提交 Bug。

您还可以通过邮件联系我们:hello@infini.ltd

或者拨打我们的热线电话:(+86) 400-139-9200

也欢迎大家微信扫码添加小助手,加入用户群讨论,或者扫码加入我们的知识星球一起学习交流。 联系我们

感谢大家的围观,祝大家周末愉快。

有了这两个小脚本,不需要再傻乎乎地手动安装 Elasticsearch了

Elasticsearchspoofer 发表了文章 • 0 个评论 • 2115 次浏览 • 2022-03-11 19:40 • 来自相关话题

在学习 ES 前一般都需要安装 ES,虽然 ES 可以开箱即用,但如果要学习分布式特性的时候,需要安装多个节点,这个时候还是有点工作量的。下面提供两个小脚本,一个是在 Ubuntu 中安装 3 节点的 ES 伪集群,一个是在 docker 中安装3节点 ES 集群。除了安装 ES 外,脚本还提供了对应版本的 Kibana、Cerebro 0.9.4 的安装。

1、在 Ubuntu 中安装 ES 7.13

这里我们采取下载 ES 安装包并且解压安装的方式,并没有走 Ubuntu apt 的方式。ES 的安装非常简单,这里先献上安装脚本

下面介绍比较重要的配置项:

  • discovery.seed_hosts 在开箱即用的情境下(本机环境)无需配置,ES 会自动扫描本机的 9300 到 9305 端口。一旦进行了网络环境配置,这个自动扫描操作就不会执行。discovery.seed_hosts 配置为 master 候选者节点即可。如果需要指定端口的话,其值可以为:["localhost:9300", "localhost:9301"]

  • cluster.initial_master_nodes 指定新集群 master 候选者列表,其值为节点的名字列表。如果配置了 node.name: my_node_1,所以其值为 ["my_node_1"],而不是 ip 列表 !

  • network.host 和 http.port 是 ES 提供服务的监听地址和端口,线上一定不能配置 ip 为 0.0.0.0,这是非常危险的行为!!!

怎么样来理解这个 discovery.seed_hosts 和 cluster.initial_master_nodes 呢?

cluster.initial_master_nodes 是候选者列表,一般我们线上环境候选者的数量比较少,毕竟是用来做备用的。而且这个配置只跟选举 master 有关,也就是跟其他类型的节点没有关系。就算你有100个数据节点,然后经常增加或者剔除都不需要动这个列表。

discovery.seed_hosts 这个可以理解为是做服务或者节点发现的,其他节点必须知道他们才能进入集群~ 一般配置为集群的master 候选者的列表。

但是这些 master 候选者(组织联系人)可能经常变化,那怎么办呢?这个配置项除了支持 ip 外还支持域名 ~所以可以用域名来解决这个问题,其他节点的配置上写的是域名,域名解析到对应的 ip,如果机器挂了,新的节点 ip 换了,就把域名解析到新的ip即可,这样其他节点的配就不用修改了。所以非 master 候选节点要配 discovery.seed_hosts (组织联系人)

除了修改 ES 服务配置外,还需要配置 JVM 的配置,我们主要配置服务占用的堆内存的大小。JVM 配置需要以下几点:

  • 这两个 jvm 的配置必须配置一样的数值。启动时就分配好内存空间,避免运行时申请分配内存造成系统抖动。
  • Xmx不要超过机器内存的 50%,留下些内存供 JVM 堆外内存使用
  • 并且Xmx不要超过 32G。建议最大配置为 30G。接近 32G,JVM 会启用压缩对象指针的功能,导致性能下降。具体可以参考:a-heap-of-trouble

安装成功后,可以访问: ES:localhost:9211

Kibana: localhost:5601

cerebro: localhost:9800

2、在docker 中安装 ES 7.13

在做一切工作之前,我们必须安装 docker。如果你已经安装好了 docker、docker-compose,可以访问我为你准备的 docker-compose.yaml 文件。

如果你没有安装 docker,完整的教程可以参考在 docker 中安装 ES 文档

下载此文件,将文件保存为 docker-compose.yaml 后,进入这个文件的目录,执行以下指令即可:

docker-compose up

如果你没有下载镜像文件,docker-compose 会自动帮你下载镜像,并且启动容器。

如果 docker-compose 启动失败,说是无权限链接 docker 的话,其报错如下:

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: 

Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1&filters=%7B%22label%22%3A%7B%22com.docker.compose.project%3Ddocker_es%22%3Atrue%7D%7D&limit=0": 

dial unix /var/run/docker.sock: connect: permission denied

可以运行以下指令临时修改:

sudo chmod 666 /var/run/docker.sock

其原因是因为你的 docker 用了 root 启动了。

最后可以访问:

cerebro:ip:9000

Kibana:ip:5601

Elasticsearch: ip:9200,ip:9202,ip:9203

其他学习资料

创建自己的 ES Docker Image

在 docker image 中安装 Elasticsearch 插件

一个开源的 ELK docker-compose 配置

docker 中安装 ES 7.13

docker 中安装 Kibana 7.13

最后附上我写的小册,欢迎刚入门的朋友来订阅~

WX20220224-174733.png

熬了几个月的夜,我的ES小册终于发布啦,适合初学者或者有点基础的同学学习~

Elasticsearchspoofer 发表了文章 • 2 个评论 • 2466 次浏览 • 2022-03-01 12:19 • 来自相关话题

课程简介.png

本小册分为 4 个部分,将由浅入深为你介绍 Elasticsearch 7.x 中的核心技术。主要知识点包括基本概念、常用 API 的使用实践、核心特性的底层原理与思想、集群管理与调优、源码阅读等知识。整个小册的思维导图如下:

知识点.png

你会学到什么?

本小册将会从非常浅显的概念开始与你学习 Elasticsearch 7.x 中的常用 API,在熟悉使用 Elasticsearch 后,我们将会对 Elasticsearch 中部分重要的特性、概念的底层实现原理进行介绍。在了解这些原理后,我们将学习如何部署、运维线上小规模集群,并且与你一起搭建一个简单的 ELK 系统。最后我们会搭建源码阅读的环境并且与你一起阅读部分模块的源码。

所以,通过本小册 4 大部分的学习,你可以收获:

  • 熟练使用 Elasticsearch 来解决搜索需求;
  • 强化 Elasticsearch 集群运维、调优的能力;
  • 通晓 Elasticsearch 核心技术的底层实现;
  • 牢固掌握源码阅读与调试的技巧。

也就是说,学完本课程后,你不仅可以掌握 ElasticSearch 相关的技术,还可以帮助你根据业务的特点快速构建出相应的搜索业务、数据分析、日志系统。真正实现学以致用。

适宜人群

  • 对 Elasticsearch 或搜索引擎感兴趣的同学。
  • 有了解和使用过 Elasticsearch,现在想进一步了解 Elasticsearch 的同学。
  • 准备从事数据搜索、分析相关工作的同学。
  • 从事 Elasticsearch 集群运维的同学。

【年度盛会】Elastic 中国开发者大会 2021 八折购票火热进行中

活动liaosy 发表了文章 • 0 个评论 • 2148 次浏览 • 2021-12-29 11:06 • 来自相关话题

【年度盛会】2021 Elastic 中国开发者大会,来自Elastic、阿里、腾讯、谷歌、字节等业界专家带来的干货分享,精彩内容不容错过,八折购票火热进行中(折扣码: 80OFF),扫码即可报名购票。  
开发者大会2021议题海报2_讲师.png
  【更多演讲嘉宾介绍】 https://conf.elasticsearch.cn/2021/speaker.html 【大会官网】 https://conf.elasticsearch.cn
【年度盛会】2021 Elastic 中国开发者大会,来自Elastic、阿里、腾讯、谷歌、字节等业界专家带来的干货分享,精彩内容不容错过,八折购票火热进行中(折扣码: 80OFF),扫码即可报名购票。  
开发者大会2021议题海报2_讲师.png
  【更多演讲嘉宾介绍】 https://conf.elasticsearch.cn/2021/speaker.html 【大会官网】 https://conf.elasticsearch.cn

【1月8日】Elastic 中国开发者大会 2021 日程新鲜出炉!福利票抢先购!

Elasticsearchliaosy 发表了文章 • 0 个评论 • 3113 次浏览 • 2021-12-27 21:46 • 来自相关话题

重要的事情说三遍

  • Elastic 中国开发者大会 2021 的精彩日程现已上线!
  • Elastic 中国开发者大会 2021 的精彩日程现已上线!
  • Elastic 中国开发者大会 2021 的精彩日程现已上线!

关于本次大会

Elastic 中国开发者大会 2021 是由 Elastic 官方、Elastic 中文社区和极限科技联合主办的开发者大会,作为中国国内唯一一个专门讨论 Elasticsearch 开源技术的大会,是中国最权威和最具实力干货的技术大会,其专业性和内容的质量一直以来在业内都是有口皆碑。本次大会邀请的演讲嘉宾有来自 Elastic 官方、Google、腾讯、阿里巴巴、字节跳动、vivo等众多公司的技术专家,为中国广大的 Elasticsearch 开发者提供一个技术交流和学习切磋的地方,汇集业界众多的成功案例,集思广益,发散思维,促进社区和行业的进步。

更多详细介绍请参见大会官网:

https://conf.elasticsearch.cn

关于大会议程

开发者大会2021议程_8折.png

精彩内容不容错过,八折购票火热进行中(折扣码: 80OFF),扫码购买。

ES Aggs根据聚合的结果(数值)进行过滤

Elasticsearchziyou 发表了文章 • 1 个评论 • 22442 次浏览 • 2019-10-10 14:32 • 来自相关话题

前言

我们在使用聚合时总是有各种各样的聚合需求,其中一个比较常用的就是根据聚合的结果过滤聚合的桶,例如:1、每个IP登录次数超过5次的IP;2、每个IP登录人数超过2的IP。 还有我之前的一个案例,访问量超过1000的人数,这些都是很常见的统计需求。

案例需求

我们在使用聚合计算的时候一般都有两类,一种是计算文档的数量,另一种是计算文档内字段的值的数量(去重计算)或者值的数学计算。两种聚合计算在过滤的时候采用不同的方法来计算。

我们使用以下案例来说明两种过滤的不同: 用户每次登录都会记录一个登录记录:

{"userID":"a","IP":"10.70.25.1","time":"2019-10-10 12:12:12.222"}

然后提出以下两个需求: 1、每个IP登录次数超过5次的IP; 2、每个IP登录人数超过2的IP。

实现

每个IP登录次数超过5次的IP

这个是对登录记录个数的桶聚合统计,然后过滤。使用IP做term聚合,就可以得出每个IP的登录次数,然后term聚合中有一个参数min_doc_count这个字段就可以对文档数量进行过滤,具体的语句如下: 查询语句

{
  "aggs": {
    "IP": {
      "terms": {
        "field": "IP",
        "size": 3000,
        "order": {
          "_count": "desc"
        },
        "min_doc_count": 5
      }
    }
  },
  "size": 0
}

结果

{
  "took" : 614,
  "timed_out" : false,
  "num_reduce_phases" : 3,
  "_shards" : {
    "total" : 1105,
    "successful" : 1105,
    "skipped" : 75,
    "failed" : 0
  },
  "hits" : {
    "total" : 2826,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "IP" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "10.25.90.139",
          "doc_count" : 61
        },
        {
          "key" : "10.25.78.146",
          "doc_count" : 45
        },
        {
          "key" : "10.25.94.22",
          "doc_count" : 21
        },
        {
          "key" : "10.25.75.52",
          "doc_count" : 18
        },
        {
          "key" : "10.25.89.32",
          "doc_count" : 13
        },
        {
          "key" : "10.25.93.243",
          "doc_count" : 10
        },
        {
          "key" : "10.25.78.189",
          "doc_count" : 9
        },
        {
          "key" : "10.25.90.82",
          "doc_count" : 8
        },
        {
          "key" : "10.25.91.240",
          "doc_count" : 8
        },
        {
          "key" : "10.25.90.57",
          "doc_count" : 7
        },
        {
          "key" : "10.25.91.251",
          "doc_count" : 7
        },
        {
          "key" : "10.25.95.166",
          "doc_count" : 6
        },
        {
          "key" : "10.25.89.33",
          "doc_count" : 5
        },
        {
          "key" : "10.25.90.88",
          "doc_count" : 5
        },
        {
          "key" : "10.25.92.53",
          "doc_count" : 5
        }
      ]
    }
  }
}

每个IP登录人数超过2的IP

这个是对登录记录用户ID的去重数聚合,然后过滤。对用户ID进行去重可以使用Cardinality Aggregation聚合,然后再使用Bucket Selector Aggregation聚合过滤器过滤数据。具体内容如下: 查询语句

{
  "aggs": {
    "IP": {
      "terms": {
        "field": "IP",
        "size": 3000,
        "order": {
          "distinct": "desc"
        },
        "min_doc_count": 5
      },
      "aggs": {
        "distinct": {
          "cardinality": {
            "field": "IP.keyword"
          }
        },
        "dd":{
          "bucket_selector": {
            "buckets_path": {"userCount":"distinct"},
            "script": "params.userCount > 2"
          }
        }
      }
    }
  },
  "size": 0
}

结果

{
  "took" : 317,
  "timed_out" : false,
  "num_reduce_phases" : 3,
  "_shards" : {
    "total" : 1105,
    "successful" : 1105,
    "skipped" : 75,
    "failed" : 0
  },
  "hits" : {
    "total" : 2826,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "IP" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "10.25.75.52",
          "doc_count" : 18,
          "distinct" : {
            "value" : 4
          }
        },
        {
          "key" : "10.25.78.146",
          "doc_count" : 45,
          "distinct" : {
            "value" : 3
          }
        },
        {
          "key" : "10.25.90.139",
          "doc_count" : 61,
          "distinct" : {
            "value" : 3
          }
        },
        {
          "key" : "10.25.91.240",
          "doc_count" : 8,
          "distinct" : {
            "value" : 3
          }
        },
        {
          "key" : "10.25.94.22",
          "doc_count" : 21,
          "distinct" : {
            "value" : 3
          }
        }
      ]
    }
  }
}

桶聚合选择器: https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-pipeline-bucket-selector-aggregation.html