搜索
1. 什么是搜索:百度、垂直搜索(站内搜索)
搜索:通过一个关键词或一段描述,得到你想要的(相关度高)结果。
关系型数据库:性能差、不可靠、结果不准确(相关度低)
2. Lucene
jar包,帮我们创建倒排索引,提供了复杂的API
特点
单点,可用性低
扩展性差,需要自己维护集群和负载
3. 如何实现搜索功能?
基本定义
基于Lucene的分布式的Restful风格的搜索,存储和分析引擎
分布式、高性能、高可用、可伸缩、易维护 ES≠搜索引擎
分布式的搜索,存储和数据分析引擎:
特点
分布式:节点对等
高性能:近实时(NTR)搜索,支持处理PB级数据
高可用:容错性高
可伸缩:支持横向和纵向扩展
易维护:开箱即用,文档全面
优势
面向开发者友好:屏蔽了Lucene的复杂特性
cluster discovery:集群自动发现
自动维护数据在多个节点上的建立
会帮我做搜索请求的负载均衡
自动维护冗余副本,保证了部分节点宕机的情况下仍然不会有任何数据丢失
ES基于Lucene提供了很多高级功能:复合查询、聚合分析、基于地理位置搜索等。
对于大公司,可以构建几百台服务器的大型分布式架构,处理PB级别数据;对于小公司,开箱即用,门槛低上手简单。
相遇传统数据库,提供了全文检索,同义词处理(美丽的cls>漂亮的cls),相关度排名。聚合分析以及海量数据的近实时(NTR)处理,这些传统数据库完全做不到。
应用领域
搜索引擎(全文检索、高亮、搜索推荐)
用户行为日志(用户点击、浏览、收藏、评论)
BI(Business Intelligence商业智能),数据分析:数据挖掘统计。
Github:代码托管平台,几千亿行代码
ELK:Elasticsearch(数据存储)、Logstash(日志采集)、Kibana(可视化)
核心概念
1. 倒排索引
由要搜索的关键词反推查询Key的过程,又叫反向索引。倒排索引适用于对文档进行全文检索,倒排索引包含了目标文档所有的不重复的分词。
2. 数据结构
包含当前关键词的documentlist
关键词在每个document中出现的次数,即tern frequency(TF),TF越高,则匹配相关度越高
关键词在整个索引中出现的次数 inverse document frequency(IDF),IDF越高,则匹配相关度越低
关键词在当前document中出现的次数
每个doc的长度,越长相关度越低
包含这个关键词的所有doc的平均长度
3. ES核心概念
cluster(集群):每个集群至少包含两个节点.
node:集群中的每个节点,一个节点不代表一台服务器
field:一个数据字段,与index和type一起,可以定位一个doc
document:ES最小的数据单元 Json
{
"id": "1",
"name": "小米",
"price": {
"标准版": 3999,
"尊享版": 4999,
"ypf签名定制版": 19999
}
}
Type:逻辑上的数据分类,es 7.x中删除了type的概念
Index:一类相同或者类似的doc,比如一个员工索引,商品索引。
Shard分片
两种分片类型
1. primary shard(主分片):在创建索引的时候,除非手动配置了primary shard的数量,否则es默认配置为5个primary,如果需要修改索引的primary的数量,需要重建索引
2. replica shard(副本分片):es默认为每个primary shard分配一个replica shard,replica shard数量可动态修改
特点
1. 每一个shard都是一个Lucene实例,具有完整的创建索引和处理搜索请求的能力
2. es会自动为我们做shard均衡
3. 一个dicument不可能同时存在于多个primary shard中,但是可以同时存在于多个replica shard中
4. primary shard不能和他的replica shard存在于同一个节点,这不符合高可用的规范,因为一旦节点宕机,主副分片同时丢失,所以最小的可用配置是两个节点,互为主备
ES分布式原理
1. 高可用
1. ES在分配单个索引的分片时会将每个分片尽可能分配到更多的节点上。但是,实际情况取决于集群拥有的分片和索引的数量以及它们的大小,所以这种情况只是理想状况。
2. ES不允许Primary和它的Replica放在同一个节点中(为了容错),并且同一个节点不接受完全相同的两个Replica,也就是说,因为同一个节点存放两个相同的副本既不能提升吞吐量,也不能提升查询速度,徒耗磁盘空间。
3. 每台节点的shard数量越少,每个shard分配的CPU、内存和IO资源越多,单个shard的性能越好,当一台机器一个Shard时,单个Shard性能最好。
4. 相同资源分配相同的前提下,单个shard的体积越大,查询性能越低,速度越慢
5. 稳定的Master节点对于群集健康非常重要!理论上讲,应该尽可能的减轻Master节点的压力,分片数量越多,Master节点维护管理shard的任务越重,并且节点可能就要承担更多的数据转发任务,可增加“仅协调”节点来缓解Master节点和Data节点的压力,但是在集群中添加过多的仅协调节点会增加整个集群的负担,因为选择的主节点必须等待每个节点的集群状态更新确认。
6. 如果相同资源分配相同的前提下,shard数量越少,单个shard的体积越大,查询性能越低,速度越慢,这个取舍应根据实际集群状况和结合应用场景等因素综合考虑
7. 数据节点和Master节点一定要分开,集群规模越大,这样做的意义也就越大
8. 数据节点处理与数据相关的操作,例如CRUD,搜索和聚合。这些操作是I / O,内存和CPU密集型的,所以他们需要更高配置的服务器以及更高的带宽,并且集群的性能冗余非常重要
9. 于仅投票节不参与Master竞选,所以和真正的Master节点相比,它需要的内存和CPU较少。但是,所有候选节点以及仅投票节点都可能是数据节点,所以他们都需要快速稳定低延迟的网络
10. 高可用性(HA)群集至少需要三个主节点,其中至少两个不是仅投票节点。即使其中一个节点发生故障,这样的群集也将能够选举一个主节点。生产环境最好设置3台仅Master候选节点(node.master = true node.data = true)
11. 为确保群集仍然可用,集群不能同时停止投票配置中的一半或更多节点。只要有一半以上的投票节点可用,群集仍可以正常工作。这意味着,如果存在三个或四个主节点合格的节点,则群集可以容忍其中一个节点不可用。如果有两个或更少的主机资格节点,则它们必须都保持可用
2. 容灾
1. Master选举
脑裂:可能会产生多个Master节点
解决:discovery.zen.minimum_master_nodes=N/2+1
2. Replica容错
3. 尝试重启故障机
4. 数据同步,同步的是增量数据
Master选举
- 集群健康值:
- 健康值检查
- _cat/health
- _cluster/health
- 健康值状态
- Green:所有Primary和Replica均为active,集群健康
- Yellow:至少一个Replica不可用,但是所有Primary均为active,数据仍然是可以保证完整性的。
- Red:至少有一个Primary为不可用状态,数据不完整,集群不可用。
- 健康值检查
- 基于XX系统的CRUD
- 创建索引:PUT /product?pretty
- 查询索引:GET _cat/indices?v
- 删除索引:DELETE /product?pretty
- 插入数据:
PUT /index/_doc/id
{
Json数据
}
- 更新数据
-
- 全量替换
- 指定字段更新
-
- 删除数据 DELETE /index/type/id
ES分布式文档系统
- ES如何实现高可用(生产环境均为一台机器一个节点)
- ES在分配单个索引的分片时会将每个分片尽可能分配到更多的节点上。但是,实际情况取决于集群拥有的分片和索引的数量以及它们的大小,不一定总是能均匀地分布。
- ES不允许Primary和它的Replica放在同一个节点中,并且同一个节点不接受完全相同的两个Replica
- 同一个节点允许多个索引的分片同时存在。
- 容错机制
- 啥叫容错?
- 傻X的代码你能看懂,牛X的代码你也能看懂
- 只能看懂自己的代码,容错性低
- PS:各种情况(支持的情况越多,容错性越好)下,都能保证work 正常运行
- 换到咱们ES上就是,就是在局部出错异常的情况下,保证服务正常运行并且有自行恢复能力。
- ES-node
-
- Master:主节点,每个集群都有且只有一个
- 尽量避免Master节点 node.data = true
- voting:投票节点
- Node.voting_only = true(仅投票节点,即使配置了data.master = true,也不会参选, 但是仍然可以作为数据节点)。
- coordinating:协调节点
- Master:主节点,每个集群都有且只有一个
-
- 啥叫容错?
每一个节点都隐式的是一个协调节点,如果同时设置了data.master = false和data.data=false,那么此节点将成为仅协调节点。
-
-
-
- Master-eligible node(候选节点):
- Data node(数据节点):
- Ingest node:
- Machine learning node(机器学习节点):
-
- 两个配置:node.master和node.data
- node.master = true node.data = true
-
这是ES节点默认配置,既作为候选节点又作为数据节点,这样的节点一旦被选举为Master,压力是比较大的,通常来说Master节点应该只承担较为轻量级的任务,比如创建删除索引,分片均衡等。
-
-
- node.master = true node.data = false
-
只作为候选节点,不作为数据节点,可参选Master节点,当选后成为真正的Master节点。
-
-
- node.master = false node.data = false
-
既不当候选节点,也不作为数据节点,那就是仅协调节点,负责负载均衡
-
-
- node.master=false node.data=true
-
不作为候选节点,但是作为数据节点,这样的节点主要负责数据存储和查询服务。
-
- 图解容错机制
- 第一步:Master选举(假如宕机节点是Master)
- 脑裂:可能会产生多个Master节点
- 解决:discovery.zen.minimum_master_nodes=N/2+1
- 第二步:Replica容错,新的(或者原有)Master节点会将丢失的Primary对应的某个副本提升为Primary
- 第三步:Master节点会尝试重启故障机
- 第四步:数据同步,Master会将宕机期间丢失的数据同步到重启机器对应的分片上去
- 第一步:Master选举(假如宕机节点是Master)
- 图解容错机制
3、总结(如何提高ES分布式系统的可用性以及性能最大化):
(1)每台节点的Shard数量越少,每个shard分配的CPU、内存和IO资源越多,单个Shard的性能越好,当一台机器一个Shard时,单个Shard性能最好。
(2)稳定的Master节点对于群集健康非常重要!理论上讲,应该尽可能的减轻Master节点的压力,分片数量越多,Master节点维护管理shard的任务越重,并且节点可能就要承担更多的数据转发任务,可增加“仅协调”节点来缓解Master节点和Data节点的压力,但是在集群中添加过多的仅协调节点会增加整个集群的负担,因为选择的主节点必须等待每个节点的集群状态更新确认。
(3)反过来说,如果相同资源分配相同的前提下,shard数量越少,单个shard的体积越大,查询性能越低,速度越慢,这个取舍应根据实际集群状况和结合应用场景等因素综合考虑。
(4)数据节点和Master节点一定要分开,集群规模越大,这样做的意义也就越大。
(5)数据节点处理与数据相关的操作,例如CRUD,搜索和聚合。这些操作是I / O,内存和CPU密集型的,所以他们需要更高配置的服务器以及更高的带宽,并且集群的性能冗余非常重要。
(6)由于仅投票节不参与Master竞选,所以和真正的Master节点相比,它需要的内存和CPU较少。但是,所有候选节点以及仅投票节点都可能是数据节点,所以他们都需要快速稳定低延迟的网络。
(7)高可用性(HA)群集至少需要三个主节点,其中至少两个不是仅投票节点。即使其中一个节点发生故障,这样的群集也将能够选举一个主节点。生产环境最好设置3台仅Master候选节点(node.master = true node.data = true)
(8)为确保群集仍然可用,集群不能同时停止投票配置中的一半或更多节点。只要有一半以上的投票节点可用,群集仍可以正常工作。这意味着,如果存在三个或四个主节点合格的节点,则群集可以容忍其中一个节点不可用。如果有两个或更少的主机资格节点,则它们必须都保持可用
数据
PUT /product/_doc/1
{
"name" : "xiaomi phone",
"desc" : "shouji zhong de zhandouji",
"price" : 3999,
"tags": [ "xingjiabi", "fashao", "buka" ]
}
PUT /product/_doc/2
{
"name" : "xiaomi nfc phone",
"desc" : "zhichi quangongneng nfc,shouji zhong de jianjiji",
"price" : 4999,
"tags": [ "xingjiabi", "fashao", "gongjiaoka" ]
}
PUT /product/_doc/3
{
"name" : "nfc phone",
"desc" : "shouji zhong de hongzhaji",
"price" : 2999,
"tags": [ "xingjiabi", "fashao", "menjinka" ]
}
PUT /product/_doc/4
{
"name" : "xiaomi erji",
"desc" : "erji zhong de huangmenji",
"price" : 999,
"tags": [ "low", "bufangshui", "yinzhicha" ]
}
PUT /product/_doc/5
{
"name" : "hongmi erji",
"desc" : "erji zhong de kendeji",
"price" : 399,
"tags": [ "lowbee", "xuhangduan", "zhiliangx" ]
}
/_cat/allocation #查看单节点的shard分配整体情况
/_cat/shards #查看各shard的详细情况
/_cat/shards/{index} #查看指定分片的详细情况
/_cat/master #查看master节点信息
/_cat/nodes #查看所有节点信息
/_cat/indices #查看集群中所有index的详细信息
/_cat/indices/{index} #查看集群中指定index的详细信息
/_cat/segments #查看各index的segment详细信息,包括segment名, 所属shard, 内存(磁盘)占用大小, 是否刷盘
/_cat/segments/{index}#查看指定index的segment详细信息
/_cat/count #查看当前集群的doc数量
/_cat/count/{index} #查看指定索引的doc数量
/_cat/recovery #查看集群内每个shard的recovery过程.调整replica。
/_cat/recovery/{index}#查看指定索引shard的recovery过程
/_cat/health #查看集群当前状态:红、黄、绿
/_cat/pending_tasks #查看当前集群的pending task
/_cat/aliases #查看集群中所有alias信息,路由配置等
/_cat/aliases/{alias} #查看指定索引的alias信息
/_cat/thread_pool #查看集群各节点内部不同类型的threadpool的统计信息,
/_cat/plugins #查看集群各个节点上的plugin信息
/_cat/fielddata #查看当前集群各个节点的fielddata内存使用情况
/_cat/fielddata/{fields} #查看指定field的内存使用情况,里面传field属性对应的值
/_cat/nodeattrs #查看单节点的自定义属性
/_cat/repositories #输出集群中注册快照存储库
/_cat/templates #输出当前正在存在的模板信息