[docker-compose中间件集群系列] - 5 elastic search的作用、原理的简单介绍以及集群搭建

文章介绍了Elasticsearch作为开源搜索分析引擎的核心原理,包括全文检索、倒排索引以及与Lucene的关系。接着,文章详细阐述了Elasticsearch的集群架构,包括节点、分片和副本的概念,以及数据路由算法。最后,文章提供了使用Docker搭建Elasticsearch集群的步骤,包括配置文件和环境变量的设置。
摘要由CSDN通过智能技术生成

上篇我们介绍了kafka。这篇我们到介绍elastic search(以下简称es),也是按照原理到集群搭建的顺序。


es是什么

        es是一个分布式的、开源的搜索分析引擎。输入关键字,获取到想要的关键字相关的信息,这就是搜索。还有非结构化数据的分析处理。ok,两句话说明白了,es就是用来干搜索干分析这些事的,就像我们的百度,Google这些搜索引擎,我们输入关键字,他就出来一堆含有我们输入关键字并且相关度较高的结果,这就是搜索。那比如我们的系统日志收集,然后分析业务流量呀,这是分析。那接下来我们看一下它是怎么干的,为什么它适合这些事。

        当然现在ChatGPT出来了是不是意味着我们传统的搜索引擎就要被毕业了呢,毕竟ai能直接回答我的问题,又不需要我自己在结果里面找答案是吧。但是,好像也不一定哈,毕竟ai也不一定对嘛,ai的判断力也不一定有我们人类高嘛。还有一些非结构化数据处理比如日志收集呀,大数据等业务也是需要一个中间件处理的嘛。那这些就不扯了,我们继续看我们的es。


es原理

        上面提到es是干搜索的,那它为什么适合做搜索呢?那就必须提到一个词,叫全文检索。

  • 什么是全文检索?从非结构化数据中提取出分词,然后重新组织分词信息,这个重新组织的信息叫索引。先建立索引,再对索引进行搜索的过程,就叫全文检索。
  • 那什么是分词?“i love you”这句话,将这句话根据一定规则提取出来一个一个词,就是分词。“i”、“love”、“you”这三个词就是提取出来的词。

        从全文检索的概念中,提到了非结构化数据,那相对肯定是有结构化数据的是吧。那什么是非结构化数据呢。那就从我们数据库中的表说起比较容易理解,因为表,字段,这种有行有列而且数据格式、数据长度都是固定的,是结构化数据。

        那相反,非结构化数据就是没有固定行列,字段不统一,数据结构不规则不完整,没有预定义的数据模型。就是非结构化数据。

        不像结构化,我要搜索某某字段,那我就光搜索那个字段的值就好了。那遇到非结构化数据,数据库表这种方式肯定是不合适的,所以我们的es就上场了。

        提到了es的原理,就要提到Lucene这个东西了,Lucene是apache的一个子项目,是一个开放源代码的全文检索引擎工具包,但是它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,还有部分的文本分析引擎。es就是基于Lucene弄出来的一个封装了许多Lucene底层功能,提供了分布式的服务的搜索与数据分析引擎。

        在Lucene中,对文档的检索是基于倒排索引实现的。

倒排索引

        什么是倒排索引,我们举个例子:

document -> to -> words        

        通过一篇篇文章,找到文章中的单词,这叫「正向索引」,

word -> to -> document

        输入一个单词,找到含有这个单词或者和这个单词有关系的文章,这叫「反向索引」,也称之为倒排索引。

那实际使用,是怎么用的呢,再举一个例子。

id句子
1i am the king of the world
2I am not an emotional type
3king kong

那如果用单词作为索引,而句子的id作为被索引的元素,那么索引就反过来了

id单词索引
i{1,2}
am{1,2}
the{1}
king{1,3}
of{1}
world{1}
not{2}
an{2}
emotional{2}
type{2}
kong{3}

ok,那如果这个时候,我们的搜索关键字是i am king,那根据上面的表格,那即是取出{1,2}、{1,2}、{1,3}这三个单词索引出来,然后取个交集,就得到了id是1的句子。

那这个时候可能就会有疑问了,那这样,不是会耗费很大量的空间吗?那答案是,是的。当然在空间方面也会有压缩之类的处理。这里就先不展开说了。

为什么要使用倒排索引

那假设我们在搜索栏上搜索,apple,那假设用正向索引,那就需要扫描所有文档,然后每一个文档都找一下有没有apple这个单词,然后经过一定机制排序返回。可是文档的数目简直是天文数字,这样的做法是不可能短时间返回给用户的。所以搜索引擎会将正向索引重新构建为倒排索引,通过关键字得到文档id,再把文档返回给用户。

以上是es的原理的一个简单的介绍,那如果想在业务上使用,集群那肯定是必不可少的了,我们先介绍一下es的集群是怎样的一个东西,主备之间是怎么做信息交互的。


es集群原理

在说集群原理前先把相关的概念名词介绍一下

  1. cluster 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是通过选举产生的,主从节点是对于内部来说的。es是无中心节点的,从外部来看es集群,在逻辑上是一个整体。意思就是对于外部来说,你与任何一个节点的通讯,都相当于与整个es集群通讯。
  2. shards 代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建之前指定,并且索引创建之后不允许修改。
  3. replicas 代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
  4. recovery 代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。

集群原理

        每个索引会被分成多个shards储存,默认创建索引是分配5个主分片进行储存。每个分片会分在多个不同的节点上进行部署。并且分别为其创建1个副本分片。也就是说,每个索引都由5个主分片组成,而每个主分片都会有对应的一个copy。主分片和副分片都能处理查询请求,它们唯一的却别在于只有主分片才能处理索引请求。

        用户可以在任何时候添加或删除副本。这句话有什么作用呢。意思就是,主分片的数目,决定着索引能保存的最大数据量,副分片是主分片的拷贝。那么,当插入大量数据的时候,那么对es集群造成了一定的压力,所以在插入大量数据之前,也就是建立索引的时候,我们最好把副分片数设置为0,等建立完索引后,再手动将副本数加大,这样可以提高数据的索引效率。

下图是2个节点的集群对于1个索引默认创建了5个分片的情况

当客户端发起创建document的时候,es需要确定这一个document放在这一个index的哪一个shard上,这个过程叫数据路由。

        路由算法:shard=hash(rounting)%number_of_primary_shards

        假设文档id是1,主分片是5,那就是1%5

另外,每一个节点不会拥有全部的主分片数据,但是节点的主分片+副分片=完整的索引数据。图中节点1是1、2、3主4、5副;节点2是1、2、3副,4、5主。这样的一个分配情况。


es集群搭建

接下来我们进行集群的搭建,我们依然是用server02、server03、server04这三台机器。

然后第一步先去dns服务器配置好我们的es域名解析,

es01.com.cn、es02.com.cn、es03.com.cn

然后去配置系统设置,分别是

/etc/security/limits.conf

/etc/sysctl.conf

这两个文件

limits.conf:

#<type> can have the two values:
#        - "soft" for enforcing the soft limits
#        - "hard" for enforcing hard limits
#
*	soft nofile 65535
*	hard nofile 65535

sysctl.conf:

vm.max_map_count=655360

两个文件都是追加些代码,原本是没有的。

然后依然是先创建好我们的文件夹elastic-search-cluster

创建我们的docker-compose.yaml

 server02:

version: '3'
services:
  es-cluster-node:
    image: elasticsearch:7.17.5
    container_name: es-cluster-node
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - network.bind_host=0.0.0.0
      - network.host=es01.com.cn
      - network.publish_host=es01.com.cn
      - http.port=9200
      - transport.tcp.port=9300
      - transport.host=es01.com.cn
      - transport.bind_host=0.0.0.0
      - transport.publish_host=es01.com.cn
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - node.master=true
      - node.data=true
      - discovery.seed_hosts=es02.com.cn,es03.com.cn
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.keystore.path=certs/elastic-stack-ca.p12
      - xpack.security.transport.ssl.truststore.path=certs/elastic-stack-ca.p12
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/data:/usr/share/elasticsearch/data
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/certs:/usr/share/elasticsearch/config/certs
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
    ports:
      - 9200:9200
      - 9300:9300

server03:

version: '3'
services:
  es-cluster-node:
    image: elasticsearch:7.17.5
    container_name: es-cluster-node
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - network.bind_host=0.0.0.0
      - network.host=es02.com.cn
      - network.publish_host=es02.com.cn
      - http.port=9200
      - transport.tcp.port=9300
      - transport.host=es02.com.cn
      - transport.bind_host=0.0.0.0
      - transport.publish_host=es02.com.cn
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - node.master=true
      - node.data=true
      - discovery.seed_hosts=es01.com.cn,es03.com.cn
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.keystore.path=certs/elastic-stack-ca.p12
      - xpack.security.transport.ssl.truststore.path=certs/elastic-stack-ca.p12
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/data:/usr/share/elasticsearch/data
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/certs:/usr/share/elasticsearch/config/certs
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
    ports:
      - 9200:9200
      - 9300:9300

server04:

version: '3'
services:
  es-cluster-node:
    image: elasticsearch:7.17.5
    container_name: es-cluster-node
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - network.bind_host=0.0.0.0
      - network.host=es03.com.cn
      - network.publish_host=es03.com.cn
      - http.port=9200
      - transport.tcp.port=9300
      - transport.host=es03.com.cn
      - transport.bind_host=0.0.0.0
      - transport.publish_host=es03.com.cn
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - node.master=true
      - node.data=true
      - discovery.seed_hosts=es01.com.cn,es02.com.cn
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - xpack.security.transport.ssl.enabled=true
      - xpack.security.transport.ssl.verification_mode=certificate
      - xpack.security.transport.ssl.keystore.path=certs/elastic-stack-ca.p12
      - xpack.security.transport.ssl.truststore.path=certs/elastic-stack-ca.p12
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/data:/usr/share/elasticsearch/data
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/certs:/usr/share/elasticsearch/config/certs
      - /data/deploy/xdeas-docker/elastic-search-cluster/volumes/elasticsearch.keystore:/usr/share/elasticsearch/config/elasticsearch.keystore
    ports:
      - 9200:9200
      - 9300:9300

这里有个点要注意,细心的朋友会看见我这边的ssl.verification_mode=certificate这个设置,我这边开启了ssl的还有一个账号密码的校验,因此对应下面的cert和elasticsearch.keystore的挂载我也写上了。如果不想开ssl校验,只需要把ssl那几个配置注释掉,就可以了。

下一个问题来了,我目前这个文件夹里面,根本没有这个文件的呀,那这里启动不会报错吗?答案是,会报错的,所以我们在启动集群之前,要先生成这一个账号密码的key文件。这里教一下大家怎么生成这个东西,需要借助单例elasticsearch生成。也就是说,我们需要先随便找一个服务器,启动一个单例的elasticsearch,不用什么特别配置,因为我们只是借助它去生成我们的keystore而已。

那我们直接跑一个docker命令去启动一个单例就行。我们选server02来启一个单例的,用完就删掉。建一个单例的文件夹

把启动单例需要的文件和文件夹都放在里面

data和plugins文件夹都给777权限,775启动好像会报错,各位也可以试一试。然后 elasticsearch.yml也没什么写的

 elasticsearch.yml:

cluster.name: "docker-cluster"
network.host: 0.0.0.0
##添加配置
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization
http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
discovery.zen.minimum_master_nodes: 1
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
# #配置单节点模式
discovery.type: single-node

注意运行指令挂载文件的路径,大家需要改成自己的文件夹路径 

最后运行

docker run -p 9200:9200 -p 9300:9300 --name elasticsearch -e "discovery.type=single-node" -e "xpack.security.audit.enabled=true" -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" -v /data/deploy/xdeas-docker/elastic_single_mode/plugins:/usr/share/elasticsearch/plugins -v /data/deploy/xdeas-docker/elastic_single_mode/data:/usr/share/elasticsearch/data -v /data/deploy/xdeas-docker/elastic_single_mode/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml -d elasticsearch:7.17.5

就启动了一个单例的elasticsearch了。

 这边还能看到我们之前搭的kafka和zookeeper。接下来我们进入这个es,去生成我们的密钥文件。

 docker exec -ti elasticsearch /bin/bash

然后运行 elasticsearch-setup-passwords interactive

 然后经过漫长的输入了不知道多少次密码之后

最后会告诉你成功。 这会就成功生成了elasticsearch.keystore文件了。

然后运行以下代码生成ca证书(如果不开启ssl的可以跳过这一步)

./bin/elasticsearch-certutil ca #一直回车,默认文件名,没有密码

./bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12  #因上一个步骤没有设置密码。一直回车就行,回车(文件使用默认名),密码(无密码)

然后在容器里面的 /usr/share/elasticsearch/config 文件夹里面会看见 elasticsearch.keystore 文件。/usr/shar/elasticsearch/文件夹下看见elastic-stack-ca.p12和elastic-certificates.p12文件.

我们需要把这三个文件复制到宿主机。那我们先从容器里面退出来,然后复制这三个文件到宿主机,.p12文件放到volumes/certs文件夹里面,keystore放到volumes文件夹里,那启动集群的准备工作,就算完成了。如果没有开启ssl的.p12文件的生成可以跳过

然后就可以停掉我们这个单例的elasticsearch了 。

接下来回去我们的集群文件夹。docker-compose up -d 大功告成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值