ES基础
ES基础
一、简介
ElasticSearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用ElasticSearch的水平伸缩性,能使数据在生产环境变得更有价值。ElasticSearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elastic Search 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。
特点:
1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司;也可以运行在单机上,服务小公司
2)Elasticsearch主要是将全文检索、数据分析以及分布式技术,合并在了一起,才形成了独一无二的ES;lucene(全文检索),商用的数据分析软件(也是有的),分布式数据库(mycat)
3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂
4)数据库的功能面对很多领域是不够用的(事务,还有各种联机事务型的操作);特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理;
二、核心概念
1全文检索
计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合。对于各种不同的语言而言,字有不同的含义,比如英文中字与词实际上是合一的,而中文中字与词有很大分别。按词检索指对文章中的词,即语义单位建立索引,检索时按词检索,并且可以处理同义项等。英文等西方文字由于按照空白切分词,因此实现上与按字处理类似,添加同义处理也很容易。中文等东方文字则需要切分字词,以达到按词索引的目的,关于这方面的问题,是当前全文检索技术尤其是中文全文检索技术中的难点 -> ik分词器(插件)
2倒排索引(分词)
以前是根据ID查内容,倒排索引之后是根据内容查ID,然后再拿着ID去查询出来真正需要的东西。(不用数据库去实现搜索功能)
3 NRT(Near Realtime)近实时
4 cluster集群,ES是一个分布式的系统
ES直接解压不需要配置就可以使用,在机器1上解压一个ES,在机器2上解压了一个ES,接下来把这两个ES启动起来。他们就构成了一个集群。在ES里面默认有一个配置,clustername 默认值就是ElasticSearch,如果这个值是一样的就属于同一个集群,不一样的值就是不一样的集群。
5 Node节点,就是集群中的一台服务器
6 index 索引
ES功能就像一个关系型数据库,在这个数据库我们可以往里面添加数据,查询数据。
ES中的索引非传统索引的含义,ES中的索引是存放数据的地方,是ES中的一个概念词汇
index类似于我们Mysql里面的一个数据库 create database user; 好比就是一个索引库
7 type类型
类型是用来定义数据结构的
在每一个index下面,可以有一个或者多个type,好比数据库里面的一张表。
相当于表结构的描述,描述每个字段的类型。
注:es官方正在逐渐取消type的概念,最新的版本默认每个index只有一个名为_doc的type
8 document:文档
文档就是最终的数据了,可以认为一个文档就是一条记录。
是ES里面最小的数据单元,就好比表里面的一条数据
9 Field 字段
好比关系型数据库中列的概念,一个document有一个或者多个field组成。
10 shard:分片
一台服务器,无法存储大量的数据,ES把一个index里面的数据,分为多个shard,分布式的存储在各个服务器上面。
kafka:为什么支持分布式的功能,因为里面是有topic,支持分区的概念。所以topic A可以存在不同的节点上面。就可以支持海量数据和高并发,提升性能和吞吐量
11 replica:副本
一个分布式的集群,难免会有一台或者多台服务器宕机,如果我们没有副本这个概念。就会造成我们的shard发生故障,无法提供正常服务。
我们为了保证数据的安全,我们引入了replica的概念,跟hdfs里面的概念是一个意思。
在ES集群中,我们一模一样的数据有多份,能正常提供查询和插入的分片我们叫做 primary shard,其余的我们就管他们叫做 replica shard(备份的分片)
当我们去查询数据的时候,我们数据是有备份的,它会同时发出命令让我们有数据的机器去查询结果,最后谁的查询结果快,我们就要谁的数据(这个不需要我们去控制,它内部就自己控制了)
三、为什么要实现集群
在单台ElasticSearch服务器节点上,随着业务量的发展索引文件慢慢增多,会影响到效率和内存存储问题等。我们可以采用ElasticSearch集群,将单个索引的分片到多个不同分布式物理机器上存储,从而实现高可用、容错性等。ElasticSearch会自动选举实现主备服务器。
四、如何解决高并发
ElasticSearch是一个分布式全文检索框架,隐藏了复杂的处理机制,内部使用分片机制、集群发现、分片负载均衡请求路由。
Shards分片:代表索引分片,ElasticSearch可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
Replicas分片:代表索引副本,ElasticSearch可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高ElasticSearch的查询效率,ElasticSearch会自动对搜索请求进行负载均衡。
五、集群核心原理分析
1)分片机制
插入数据的时候不是根据负载均衡来插入的,是根据一定的路由规则,比如我们就取哈希值取模,
shard_num = hash(_routing) % num_primary_shards -> primary shard无法被修改
我们在创建一个index库的时候,我们可以指定primary shard的数量,也可以指定replica的数量,如果不指定,那么默认primary shard=5 replica=1 所以 replica shard=5,过了一段时间发现数据量很大,我们primary shard不够用了,那么这个时候想修改shard 的个数,能不能改成20个?答案:不能!!原来本应该插入到8的位置,结果插入到了9的位置,这样计算查询规则就错了。所以主分片个数是不能修改的,但是副分片的个数是可以进行修改的。具体怎么完成的那是ES内部的事情,我们先不用考虑。我们写了段java的代码插入数据到主分片里面去了。具体怎么插入的,插入到哪个主分片里面是不需要我们来管的。所以就是把这些功能给隐藏起来了。
2)集群的发现机制
一开始我们只启动了一个ES的节点,这个时候这个ES的状态是yellow,后来我们又启动了一个ES节点,发现颜色变成了green,这说明,我们后面启动的这个节点,也自动加入了这个集群。那么这个机制就是集群的发现机制。对于我们也是隐藏起来了。我们没必要知道
3)shard 会进行负载均衡
Hbase中如果你新加入了一个Hbase节点,不会自动的进行负载均衡,需要执行一个命令
但是ES不一样。只要你加入了一个节点,会自动帮你进行负载均衡
4)ES集群的扩容问题
扩容分为:垂直和水平扩容
我们之前的大数据技术都是分布式的部署在集群上面的。如果我们的资源不够用了,这个时候就涉及到了扩容,我们是垂直扩容还是水平扩容呢?
假设我们每个节点能存储1T的数据,现在我们要存储5T的数据,
垂直扩容就是把其中的一台换了,换成性能更强的节点。有可能一台节点就能存5T。
水平扩容就是新加服务器直到能存下来5T的数据,我们一般都是用水平扩容,比如1T是1万。5台5万,但是单台5T的价钱可能是50万。所以我们几乎不太可能用这种方式。
每个节点会周期性的去探测所有的节点中是否存在Master节点,如果得不到回应,且自身也不是master,该节点会认为master挂了,当达到minimum_master_nodes个节点都认为master挂了,就会触发选举。
然后从候选节点(node.master:true)中去选举master,当某个节点收到票数过半时,此节点将成为master,昭告天下。然后其他节点去追随这个master。
参考链接:https://blog.csdn.net/darkness0604/article/details/106460726
5)ES的节点角色
Master: 主节点(主节点,每个集群都有且只有一个)
master节点的主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。
稳定的主节点对集群的健康是非常重要的,默认情况下任何一个集群中的节点都有可能被选为主节点,
索引数据和搜索查询等操作会占用大量的cpu,内存,io资源,为了确保一个集群的稳定,分离master和数据节点是一个比较好的选择:
也就是尽量避免Master节点设置 node.data = true
voting: 投票节点(不竞选主节点)
通过设置配置中的node.voting_only=true,(仅投票节点,即使配置了node.master = true,也不会参选, 但是仍然可以作为数据节点)。
Master-eligible node (候选节点)
当node.master为true时,其表示这个node是一个master的候选节点,可以参与选举,在ES的文档中常被称作master-eligible node,类似于MasterCandidate。ES正常运行时只能有一个master(即leader),多于1个时会发生脑裂。
Data node (数据节点)
当node.data为true时,这个节点作为一个数据节点,数据节点主要是存储索引数据的节点,主要对文档进行增删改查操作,聚合操作等。数据节点对cpu,内存,io要求较高, 在优化的时候需要监控数据节点的状态,当资源不够的时候,需要在集群中添加新的节点。
coordinating: 协调节点
当node.master和node.data配置都设置为false的时候,该节点只能处理路由请求,处理搜索,分发索引操作等,从本质上来说该客户节点表现为智能负载平衡器。
独立的协调节点在一个比较大的集群中是非常有用的,他协调主节点和数据节点,客户端节点加入集群可以得到集群的状态,根据集群的状态可以直接路由请求。
每一个节点都隐式的是一个协调节点,如果同时设置了node.master = false和node.data=false,那么此节点将成为仅协调节点。
建议
① 一个节点的缺省配置是:主节点+数据节点两属性为一身。对于3-5个节点的小集群来讲,通常让所有节点存储数据和具有获得主节点的资格。你可以将任何请求发送给任何节点,并且由于所有节点都具有集群状态的副本,它们知道如何路由请求。
② 通常只有较大的集群才能开始分离专用主节点、数据节点。对于许多用户场景,路由节点根本不一定是必需的。
③ 专用协调节点(也称为client节点或路由节点)从数据节点中消除了聚合/查询的请求解析和最终阶段,并允许他们专注于处理数据。在多大程度上这对集群有好处将因情况而异。 通常在查询大量使用情况下路由节点更常见。
六、ElasticSearch集群搭建
环境(ES版本6.3.2)
Linux系统:Centos7,Java版本:JDK1.8
1、JDK版本要求1.8及以上;
2、ES不能以root用户身份运行 确保运行用户对各使用到的目录的权限;
配置文件elasticsearch.yml
# 集群名称,相同集群的节点名称一致
cluster.name: my-elk
# 节点名称
node.name: es4
# 数据存储路径
path.data: D:\environment\es4\data
# 日志存储路径
path.logs: D:\environment\es4\logs
# 是否用作候选主节点,默认为 true
node.master: true
# 是否用作数据节点,默认为 true
node.data: true
# 允许外网所有ip访问
network.host: 0.0.0.0
# HTTP 端口,提供 RESTful 服务交互
http.port: 9204
# TCP 端口,集群节点之间通信
transport.tcp.port: 9304
# 集群中相互通信的节点
discovery.zen.ping.unicast.hosts: ["10.10.32.109:9304","10.10.32.109:9305","192.168.119.128:9301","192.168.119.128:9302","192.168.119.128:9303"]
# 集群最小主节点个数
discovery.zen.minimum_master_nodes: 1
# 解决跨域
http.cors.enabled: true
http.cors.allow-origin: "*"
七、其他
① java 使用一个叫内存指针压缩的技术来解决这个问题。它的指针不再表示对象在内存中的精确位置,而是表示偏移量。这意味着32位的指针可以引用40亿个对象,而不是40亿个字节。最终,也就是说堆内存长到32G的物理内存,也可以用32bit的指针表示。
一旦你越过那个神奇的30-32G的边界,指针就会切回普通对象的指针,每个对象的指针都变长了,就会使用更多的CPU内存带宽,也就是说你实际上失去了更多的内存。事实上当内存到达40-50GB的时候,有效内存才相当于使用内存对象指针压缩技术时候的32G内存。
即便你有足够的内存,也尽量不要超过32G,因为它浪费了内存,降低了CPU的性能,还要让GC应对大内存。
② 脑裂:
面试题:
https://www.cnblogs.com/ningskyer/articles/5984346.html