Elasticsearch是什么
•Elasticsearch 是一个分布式的开源搜索和分析引擎。
•适用于所有类型的数据,包括文本、数字、地理空间、结构化和非结构化数据。
•Elasticsearch 在Apache Lucene 的基础上开发而成,由Elasticsearch N.V.(即现在的Elastic)于2010 年首次发布。
Elastic Stack介绍
•Elasticsearch是Elastic Stack 的核心组件之一。
•Elastic Stack 是适用于数据采集、充实、存储、分析和可视化的一组开源工具。
•通常将Elastic Stack 称为ELK Stack(代指Elasticsearch、Logstash 和Kibana)。
•目前Elastic Stack 包括一系列丰富的轻量型数据采集代理,这些代理统称为Beats,可用来向Elasticsearch 发送数据。备注:单纯管理日志性能较难超过时序数据库。
Elasticsearch特点
•REST 风格API
•分布式
•速度快
•可扩展
Elasticsearch 主要功能
•快速数据访问:Elasticsearch 中的所有文档都存储在靠近索引中相应元数据的位置。这减少了数据所需的读取操作次数,从而缩短了整体搜索结果响应时间。
•自动节点恢复:如果节点因节点故障、故意移除等任何原因离开Elasticsearch 集群,主节点会采取必要的措施,将节点替换为其副本并重新平衡所有分片以自动管理负载。
•升级助手API:升级助手API 使用户能够检查其Elasticsearch 集群的升级状态并重新索引在以前版本的Elasticsearch 中创建的索引。该助手可帮助用户为Elasticsearch 的下一个主要版本做好准备。
•索引生命周期管理:Elasticsearch 索引生命周期管理(ILM) 允许用户定义和自动化许多策略,这些策略有助于控制Elasticsearch 索引在每个阶段的生存时间。它还允许用户设置在每个阶段对索引执行的操作。
•搜索引擎的可扩展性:Elasticsearch 实现了一个分布式架构,使其能够扩展到数千台服务器并处理PB 级的数据,而不会遇到任何性能问题。这种分布式设计由Elasticsearch 自动处理,因此客户可以专注于执行所需的操作。
Elasticsearch vs PostgreSQL (1)
•PG关系数据库⇒数据库⇒表⇒行⇒列(Columns)
•Elasticsearch ⇒索引(Index) ⇒类型(type) ⇒文档(Docments) ⇒字段(Fields) Elasticsearch性能上的优势在索引,它提供强大的索引能力,Elasticsearch 是通过Lucene 的倒排索引技术实现比关系型数据库更快的过滤
Elasticsearch的索引思路:将磁盘里的东西尽量搬进内存,减少磁盘随机读取次数(同时也利用磁盘顺序读特性),结合各种算法,用及其苛刻的态度使用内存
Elasticsearch vs PostgreSQL (2)
•数据库模型: NoSQL 分布式文档vs 结构化数据( 扩展)
•事务支持: 无vs 强支持
•架构灵活性: 可自动推断数据类型vs 需明确预定义
•CAP 定理实现: 可用性和分区容错vs 一致性和可用性
•安全性: 弱vs 访问控制 安全身份验证
•云产品: 多层次产品vs 依赖第3方
Elasticsearch vs PostgreSQL (3)
全文检索性能对比
•针对性优先后PG性能可以接近Elasticsearch
•PG的优化难度较大,成本较高参见https://www.rocky.dev/full-text-search
Elasticsearch vs Solr
ES开发
基础概念(1)集群(Cluster)
•Elasticsearch 集群部署使其可以随时可用和并按需扩容,并保证数据的安全性
•通过启动参数cluster.name 修改集群名称,默认名称为elasticsearch
•默认端口9200,启动后可用http://127.0.0.1:9200查看运行情况
基础概念(2a)节点(Node)
•一个节点是一个Java 进程实例,一台机器可以运行多个实例,一般情况下一台机器只允许一个节点
•一个集群有一个或者多个节点•通过启动参数node.name 定义节点名称
•每个节点都保存了集群的状态信息,只有Master 节点可以修改集群的状态信息
•集群状态信息包括:所有节点信息、索引、Mapping、Settings、分片路由等信息
基础概念(2b)
•Master-eligible 节点:
–每个节点启动,默认自己是一个Master-eligible 节点
–可以通过启动参数node.master: false 禁止当前启动节点是Master-eligible 节点
–所有Master-eligible 都可以参与选主流程,成为Master 节点
•Data 节点:
–保存分片数据的节点
–在数据扩展上起很大作用–通过启动参数node.data 设置•Coordinating 节点:
–接收客户端请求,将请求分发到合适的节点,最终再对结果进行汇集–每个节点默认都是Coordinating 节点
基础概念(2c)
•Hot & Warm 节点:硬件配置不同的节点
•Machine Learning 节点:机器学习,用来自动异常检测,自动报警,通过启动参数node.ml 进行设置基础概念(3)分片(Shard)
•分片是物理空间概念,索引中的数据都分布在分片上
•一个分片就是运行的一个Lucene 的实例
•分片分为主分片和副分片,一般主分片和副分片应该分布在不同的节点上
•主分片用于解决数据水平扩展的问题,主分片的数目在索引创建后指定,后续不容许修改(number_of_shards)
•副分片用来解决数据高可用问题,是主分片的拷贝,数量可以动态调整(number_of_replicas)
•分片数的设定–分片数设置太小,影响后续水平扩展,单个分片数据量太大将导致数据重新分配耗时–分片数设置过大,影响搜索结果的相关性打分,影响搜索结果数据准确性–分片数设置过大,导致单个节点上会有过多的分片,资源浪费,浪费性能
基础概念(4)索引(Index)
•一个集群下面可以新建多个索引,索引体现了逻辑空间概念
•索引是一类相似文档的集合,是文档的容器,类比关系型数据库中的一张表的Schema 的概念
•每个索引有自己的Mapping 用于定义文档的字段名和字段类型
•每个索引有自己的Settings 用于定义不同的数据分布,也就是索引使用分片的情况
基础概念(6)文档(Document)
•文档是所有可搜索数据的最小单位,类似关系数据库中某张表中的一行记录
•文档会被序列化成JSON 格式,JSON 对象由字段组成
•每个字段都有对应的字段类型,类型可以自己指定,也可以使用ElasticSearch 自动推算
•JSON 文档支持数组和嵌套
•每个文档都有一个唯一性ID,可以自己指定,也可以系统自动生成
•一个文档主要的元信息如下:
–_index: 文档所属的索引名
–_type: 文档所属的类型名
–_id: 文档的唯一ID
–_source: 文档存储的Json 数据
–_version:文档的版本信息
–_score: 相关性打分
基础概念(7)Elasticsearch 插件
Elasticsearch 提供插件功能,用户可以根据自己的需求安装相应的插件满足搜索,分析,安全,管理,数据备份等功能,比如可以安装elasticsearch-analysis-ik 来满足中文分词功能。
•bin/elasticsearch-plugin install 安装插件•bin/elasticsearch-plugin list 展示插件列表
•可以访问localhost:9200/_cat/plugins 接口显示已经安装的插件
基础概念(8)Elasticsearch 类比关系型数据库
Elasticsearch 相对关系型数据库,更适合相关性、高性能全文检索,并且支持restAPI 调用,而关系型数据库更适合事务性要求较强的场景,以下是两者概念上的类比:
关系型数据库 | ElasticSearch |
Table | Index |
Row | Document |
Column | Field |
Schema | Mapping |
SQL | DSL |
基础概念(9)倒排索引
Elasticsearch 使用一种称为”倒排索引"的结构,它适用于快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表,这样可以通过某个单词快速的找到其所在的文档:
倒排索引包含两部分:单词词典(Team Dictionary)和倒排列表(Posting List)
•单词词典记录单词到倒排列表的关联关系,一般通过B 树或者哈希链表实现
•倒排列表记录单词对应的文档结合,由倒排索引项组成
•倒排索引项由文档ID(docId),词频(term frequencies),单词位置(term postion),偏移量(character offsets)组成
•ElasticSearch 中默认会对文档中的每个字段做倒排索引,可以强行指定不对某些字段设置倒排索引
基础概念(10a)分词器
•Analysis 是把全文本转换为一系列单词的过程,也叫分词
•Analysis 通过Analyzer 分词器实现,可以使用ElasticSearch 内置的分词器或者定制化分词器
•在写入文档和搜索查询时都需要用到分词器
•在写入文档数据时,需要对TEXT 字段做分词然后建立倒排索引
•在搜索查询时,需要对输入的查询语句进行分词,然后通过倒排索引进行搜索
•Analyzer 分词器的组成:
1. Character Filters: 对原始文本进行预处理,比如去除HTML,字符串替换,正则匹配替换2. Tokenizer: 按照规则切分单词,ES 内置的有whitespace/standard/uax_url_email/pattern/keyword/path hierarchy 等Tokenizer
3. Token Filter: 对切分的单词进行加工,例如小写转换(Lowercase),删除stopwords(stop),增加同义
基础概念(10b)内置分词器:
•Standard Analyzer:默认分词器,按词切换,小写处理
•Simple Analyzer: 按照非字母切分,小写处理
•Stop Analyzer: 小写处理,停用词过滤
•Whitespace Analyzer:按照空格切分,不转换小写
•Keyword Analyzer: 不分词,直接将输入当作输出
•Patter Analyzer: 正则表达式分词
•Language Analyzer:提供30 多种常见语言的分词器
•Customer Analyzer:自定义分词器
基础概念(10c)常用的中文分词器:
•icu_analyzer: bin/elasticsearch-plugin install analysis-icu
•ik: bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.0/elasticsearch-analysis-ik-6.3.0.zip
•thulac: https://github.com/microbun/elasticsearch-thulac-plugin
基础概念(11)Mapping:
•Mapping 主要用于定义索引的字段名称和数据类型以及倒排索引等相关配置
•Mapping 可以系统自动推断生成,也可以由用户自己定义Mapping 样例格式:
基础概念(12a)字段的属性type:
字段的数据类型,并没有提供专门数组类型,通过TEXT 字段实现,Elasticsearch 主要支持以下几种数据类型:
•-Text:默认情况下会进行分词
•-Keyword:不会进行分词,全文本匹配
•-Date:日期类型
•-Integer/Floating:整数/浮点数
•-Boolean:布尔类型
•-IPv4 & IPv6
•-特殊类型:geo_point & geo_shape & percolator
基础概念(12b)index
index:表示该字段是否可以被搜索,是否需要建立倒排索引index_options 属性:控制倒排索引记录的内容,内容越多,占用空间越大,text 类型默认是positions,其它默认是docs
-docs: 记录docId
-freqs:记录docId 和term frequencies
-positions:记录docId 和term frequencies 和term postion
-offsets:记录docId 和term frequencies 和term postion 和character offsets
null_value:默认情况下null 是无法被直接搜索的,如果需要对Null 值进行搜索,可以设置该属性,表示null 值被当成什么来搜索
copy_to:将值拷贝到对应的字段上,多个字段可以同时copy_to 到同一个字段上,用于对于多个字段同时查询,目标字段不会出现在mapping 的定义中,但是可以用于搜索
fields: 多字段特性,可以增加一个keyword 字段,可以为搜索和索引指定不同的分词器等
基础概念(13)Index Template
•帮助你设定Mappings 和Settings,并按照一定的规则,自动匹配到新创建的索引之上
•Index Template 只是对于一个新创建的索引才起作用
•可以通过order 参数来控制模板的优先级
•一个Elasticsearch 可以设置多个Index Template
•创建一个索引时,按照以下顺序配置其Settings 和Mappings,后面的覆盖前面的配置
–ES 默认的Settings 和Mappings
–order 数值低的Index Template–order 数值高的Index Template
–用户对于当前索引指定的Settings 和Mappings
基础概念(14)Dynamic Mapping
在写入文档时,如果索引不存在ES 会自动创建索引,并且会根据用户写入的数据按照上面介绍的逻辑自动推断每个字段的类型和配置,每个索引有一个dynamic 属性来控制动态推断逻辑,该属性只会对新增数据写入起作用:
•当dynamic 属性true 时,当有有新字段的文档写入时,Mapping 也会同时被按照推荐自动更新
•当dynamic 属性false 时,当有有新字段的文档写入时,Mapping 不会被更新,新增字段无法被索引,但是信息会出现在文档的_source 属性中
•当dynamic 属性是Strict 时,文档不可以被写入,当然字段也不可以被索引,数据写入时直接报错
•对已有字段,一旦有数据写入,就不再支持修改字段定义,因为建立了倒排索引后就不允许修改了,如果希望修改字段类型,必须Reindex API,重建索引
•根据ES 识别的数据类型,结合字段名称来动态设置字段类型
•与Index Template 不同,Dynamic Template 是定义在某个具体的索引下的
开发
常用RestAPI(1)
•PUT {index_name}/_create/{id}:增加一条文档记录,必须保证对应 ID 的文档不存在
•POST {index_name}/_update/{id}:不会删除原先文档,实现真正的数据更新,可以增加字段或者修改某些字段
•PUT {index_name}/_doc/{id}:新增一条文档记录,如果记录已经存在,则删除原先文档,版本信息会加 1
•POST {index_name}/_doc/:新增一条文档记录,ID 会自动生成
•GET {index_name}/_doc/{id}:根据 ID 获取某一文档记录
•DELETE {index_name}/_doc/{id}:根据删除一条文档
•POST _bulk:文档的批量增删改
•GET _mget: 批量读取文档数据
文档的搜索
文档的搜索分为 URI Search 和 Request Body Search 两种方式,URI Search 主要在 URL 中通过 query string 的方式传参进行查询,方便简单;Request Body Search 是通过 POST 的请求体 Body 的方式传参进行搜索,支持丰富的搜索格式,下面是搜索相关的 rest API 如下:
•POST|GET /_search: 对集群中所有的索引进行搜索
•POST|GET /index1,index2/_search:搜索索引 index1 和 index2
•POST|GET /index*/_search: 搜索以 index 开头命名的索引
搜索结果的是否合理,主要取决于搜索的相关性,搜索相关性由下面三个属性决定:
•查准率:尽可能返回较少的无关文档
•查全率:尽量返回较多的相关文档
•排名:是否可以按照相关度进行排序
常见查询操作
•匹配查询
•过滤查询
•全文搜索
•短语搜索
•高亮搜索
•聚合
•排序与分页
其它 API
•GET _cluster/health: 查看集群的健康状态
•GET {index_name}: 查看对应索引的状态
•GET {index_name}/_count:查看索引的文档总数
•POST /_analyze: 使用某个分词器对文本进行分词
URI Search 相关示例
//搜索 users 索引下,user 字段包含 chenmangmanga,并对搜索结果按照 year 降序,获取前 10 个搜索结果,搜索超时时间为 1 秒
GET users/_search?q=user:chenmangmanga&sort=year:desc&from=0&size=10&timeout=1s
{
"profile": true
}
•q: 指定查询语句
•df: 指定查询的默认字段
•sort:按照什么字段进行排序
•from/size:用于分页
•profile:可以查看查询是如何被执行的
•timeout:查询超时时间
范围查询
•q=date:[2012-01-01 TO 2012-12-31]:查询 date 字段在 2012-01-01 和 2012-12-31 之间的文档
•q=count:[10 TO *]:count 字段大于 10 的范围查询
•q=age:(>=10 AND <20):查询 age 字段大于等于 10 且小于 20 的文档
通配符查询
通配符占用内存大,一般情况下不建议使用
•q=status:act?ve*a:“?”表示匹配一个任意字符,“*”表示匹配0个或者多个任意字符
正则查询
•q=name:/joh?n(ath[oa]n)/
模糊查询和近似查询
•q=title:befutifl~1 : 表示增加,删除,替换,或者字符位置转换不超过1的模糊匹配
•q=title:"lord rings"~2:表示lord 和 rings 中间不超过2个字符的模糊匹配情况
Request Body Search 示例
将查询语句通过 HTTP Request Body 的形式发送给 Elasticsearch,支持非常丰富的查询格式,详情请参考官方文档
聚合分析
类似关系型数据库,Elasticsearch 同样支持丰富的聚合运算,可以根据某个维度对数据进行求和,平均值,最大值等运算,并可以进行二次聚合运算. Elasticsearch 中聚合主要分为以下几类:
•Bucket Aggregation: 对满足特定条件的文档的聚合,分成不同的桶,类似关系型数据库中的 Group By
•Metric Aggregation:一些数学运算,可以对文档字段进行统计分析,比如最大值,最小值,平均值的计算等
•Pipeline Aggregation:对其它的聚合结果进行二次聚合
•Matrix Aggregation:支持对多个字段的操作并提供一个结果矩阵