• ES Elasticsearch


    ES

    本章知识点

    三 ES简介

    3.1 数据分类

    我们生活中的数据总体分为三种:结构化数据,非结构化数据,半结构化数据
    
     结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。 
    
     非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等
    
     半结构化数据,如XML,HTML等。 例如html 可以添加文本 、图片、音视频等内容,但是其是由标签组成。
        
    
     非结构化数据又一种叫法   -------------------   全文数据。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.2 对数据的搜索方式

    对结构化数据的搜索:
        如对数据库的搜索,用SQL语句。利用表结构 结合SQL.结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和[程序设计语言]
        
        对元数据的搜索,如利用windows搜索对文件名,类型,修改时间进行搜索等。(按照文件的名字 类型 如果搜索的是文件内容)
    
    对非结构化数据的搜索:如利用windows的搜索也可以搜索文件内容,Linux下的grep命令,再如用Google和百度可以搜索大量内容数据。
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.3 非结构化数据的搜索

    顺序扫描:比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。
    
    如利用windows的搜索也可以搜索文件内容,只是相当的慢。如果你有一个80G硬盘,如果想在上面找到一个内容包含某字符串的文件,不花他几个小时,怕是做不到。
    
    Linux下的grep命令也是这一种方式。大家可能觉得这种方法比较原始,但对于小数据量的文件,这种方法还是最直接,最方便的。但是对于大量的文件,这种方法就很慢了。
    
     
    全文检索的基本思路:将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。 
    
    这部分从非结构化数据中提取出的然后重新组织的信息,我们称之   索引。
    
    这种先建立索引,再对索引进行搜索的过程就叫    全文检索(Full-text Search)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    3.4 es简介

    官网:https://www.elastic.co/cn/
    
    文档教程:  https://www.elastic.co/guide/en/elasticsearch/reference/6.0/getting-started.html
    
    
    Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,Elasticsearch 会集中存储您的数据,让您飞快完成搜索,微调相关性,进行强大的分析,并轻松缩放规模。
        
    Logstash 是免费且开放的服务器端数据处理管道,能够从多个来源采集数据,转换数据,然后将数据发送到您最喜欢的“存储库”中。       
        
    Kibana 是一个免费且开放的用户界面,能够让您对 Elasticsearch 数据进行可视化,并让您在 Elastic Stack 中进行导航。您可以进行各种操作,从跟踪查询负载,到理解请求如何流经您的整个应用,都能轻松完成。
        
     ELK平台   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    四 ES中的核心概念

    4.1 ES作用

    Elasticsearch是一个高度可扩展的开源全文本搜索和分析引擎。它使您可以快速,近乎实时地存储,搜索和分析大量数据。它通常用作支持具有复杂搜索功能和要求的应用程序的基础引擎/技术。
    
    以下是一些可用于Elasticsearch的示例用例:
    
    - 您经营一个在线网上商店,您可以在其中允许客户搜索您出售的产品。在这种情况下,您可以使用Elasticsearch存储整个产品目录和库存,并为其提供搜索和自动完成建议。
    
    - 您要收集日志或交易数据,并且要分析和挖掘此数据以查找趋势,统计信息,摘要或异常。在这种情况下,您可以使用LogstashElasticsearch / Logstash / Kibana堆栈的一部分)来收集,聚合和解析数据,然后让Logstash将这些数据提供给Elasticsearch。数据放入Elasticsearch后,您可以运行搜索和聚合以挖掘您感兴趣的任何信息。
    
    - 您运行一个价格警报平台,该平台允许精通价格的客户指定诸如“我有兴趣购买特定的电子小工具,并且如果小工具的价格在下个月内从任何供应商处降到$ X以下,我希望收到通知”。 在这种情况下,您可以抓取供应商价格,将其推入Elasticsearch并使用其反向搜索(Percolator)功能将价格变动与客户查询进行匹配,并在找到匹配项后最终将警报发送给客户。50 推送
    
    - 您具有分析/业务智能需求,并且想要快速调查,分析,可视化并对许多数据(即数百万或数十亿条记录)提出临时问题。在这种情况下,您可以使用Elasticsearch存储数据,然后使用KibanaElasticsearch / Logstash / Kibana堆栈的一部分)构建自定义仪表板,这些仪表板可以可视化对您重要的数据方面。此外,您可以使用Elasticsearch聚合功能对数据执行复杂的商业智能查询。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.2 ES中的概念

    cluster:集群
    
    群集是一个或多个节点(服务器)的集合,这些节点一起保存您的全部数据,并在所有节点之间提供联合索引和搜索功能。集群由唯一名称标识,默认情况下为“ elasticsearch”。此名称很重要,因为如果节点被设置为通过其名称加入群集,则该节点只能是群集的一部分。
    确保不要在不同的环境中重复使用相同的集群名称,否则最终可能会导致节点加入错误的集群。例如,您可以将`logging-dev`,`logging-stage`和`logging-prod` 用于开发,登台和生产集群。
    请注意,只有一个节点的群集是有效且完全可以的。此外,您可能还具有多个独立的群集,每个群集都有其自己的唯一群集名称。
    
    Node:节点
    
    节点是单个服务器,它是群集的一部分,存储数据并参与群集的索引和搜索功能。就像群集一样,节点由名称标识,该名称默认为在启动时分配给该节点的随机通用唯一标识符(UUID)。如果不想使用默认的节点名称,则可以定义任何节点名称。此名称对于管理目的很重要,在管理中您要识别网络中的哪些服务器与Elasticsearch群集中的哪些节点相对应。
    
    可以将节点配置为通过集群名称加入特定集群。默认情况下,每个节点都设置为加入一个名为的集群`elasticsearch`,这意味着如果您在网络上启动了多个节点,并且假设它们可以相互发现,它们将全部自动形成并加入一个名为的集群`elasticsearch`。
    
    在单个群集中,您可以根据需要拥有任意数量的节点。此外,如果您的网络上当前没有其他Elasticsearch节点在运行,则默认情况下启动单个节点将形成一个名为的新单节点集群`elasticsearch`。
    
    
    
    index  索引
    
    索引是具有相似特征的文档的集合。例如,您可以为客户数据创建索引,为产品目录创建另一个索引,为订单数据创建另一个索引。索引由名称标识(必须全为小写),并且对其中的文档执行索引,搜索,更新和删除操作时,该名称用于引用索引。在单个群集中,您可以定义任意多个索引。
    
    
    
    document 文档
    
    文档是可以建立索引的基本信息单位。例如,您可以有一个针对单个客户的文档,一个针对单个产品的文档,以及另一个针对单个订单的文档。本文档以[JSON]表示,这是无处不在的Internet数据交换格式。在索引/类型中,您可以存储任意数量的文档。请注意,尽管文档实际上位于索引中,但实际上必须将文档编入索引/分配给索引内的类型。
    
    
    
    Shards & Replicas  分片和副本
    
    索引可能存储大量数据,这些数据可能超过单个节点的硬件限制。例如,十亿个文档的单个索引占用了1TB的磁盘空间,可能不适合单个节点的磁盘,或者可能太慢而无法单独满足来自单个节点的搜索请求。
    
    为了解决此问题,Elasticsearch提供了将索引细分为多个碎片的功能。创建索引时,只需定义所需的分片数量即可。每个分片本身就是一个功能齐全且独立的“索引”,可以托管在群集中的任何节点上。
    
    分片很重要,主要有两个原因:
    
    - 它允许您水平分割/缩放内容量
    - 它允许您跨碎片(可能在多个节点上)分布和并行化操作,从而提高性能/吞吐量
    
    分片如何分布以及其文档如何聚合回到搜索请求中的机制完全由Elasticsearch管理,并且对您作为用户是透明的。
    
    在随时可能发生故障的网络/云环境中,非常有用,强烈建议您使用故障转移机制,以防碎片/节点因某种原因脱机或消失。为此,Elasticsearch允许您将索引分片的一个或多个副本制作为所谓的副本分片(简称副本)。
    
    复制很重要,主要有两个原因:
    
    - 如果分片/节点发生故障,它可提供高可用性。因此,重要的是要注意,副本分片永远不会与从其复制原始/主分片的节点分配在同一节点上。
    - 由于可以在所有副本上并行执行搜索,因此它可以扩展搜索量/吞吐量。
    
    总而言之,每个索引可以分为多个碎片。索引也可以被复制零(意味着没有副本)或更多次。复制后,每个索引将具有主碎片(从中进行复制的原始碎片)和副本碎片(主碎片的副本)。可以在创建索引时为每个索引定义分片和副本的数量。创建索引后,您可以随时动态更改副本数,但不能事后更改分片数。
    
    默认情况下,Elasticsearch中的每个索引分配有5个主碎片和1个副本,这意味着如果集群中至少有两个节点,则索引将具有5个主碎片和另外5个副本碎片(1个完整副本),总计每个索引10个碎片。
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    在这里插入图片描述

    五 ES集群搭建与应用

    5.1 单机ES

    克隆一台机器  要求有JDK 修改IP地址  housname  重启
        
    创建一个文件夹目录 :   mkdir   /home/es
    移动到这个目录下:   cd   /home/es
    使用xftp将es的安装包上传到这个路径下
    解压当前es安装包:  tar  -zxvf   elasticsearch-6.4.0.tar.gz
        
    配置环境变量
        我们先把es的路径复制一下: /home/es/elasticsearch-6.4.0
        进入到环境变量的配置文件中:  vim  /etc/profile
        
    ES_HOME=/home/es/elasticsearch-6.4.0
    JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64
    PATH=$PATH:$JAVA_HOME/bin:$ES_HOME/bin
    CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export JAVA_HOME  CLASSPATH  PATH  ES_HOME
    
        重新加载环境变量文件  :  source   /etc/profile
      
    配置ES
    1,创建数据data文件,后面配置用到: mkdir /home/es/elasticsearch-6.4.0/data
       (用来存储ES产生的磁盘文件)
         
    2,在/etc/sysctl.conf最后添加(解决:max virtual memory areas vm.max_map_count [65530] is too low错误,vm.max_map_count单个JVM能开启的最大线程数)
       vim /etc/sysctl.conf   
     vm.max_map_count=655360
     让文件生效:sysctl -p
        
    3 ,在/etc/security/limits.conf最后添加:(不配置缺省值:1024,解除 Linux 系统的最大进程数和最大文件打开数限制:* 代表针对所有用户  zhangsan表示启动用户名称,与下面创建用户一致  noproc 是代表最大进程数 nofile 是代表最大文件打开数   ES不能使用root账户启动 所以我们需要使用其他用户,其他用户的文件访问权限我们需要开启  此时我们配置的是用户zhangsan的权限  所以我们一会需要创建一个新用户叫zhangsan   soft 警告值  hard 上限)
    vim /etc/security/limits.conf
        
    zhangsan soft nofile 65536
    zhangsan hard nofile 131072
    zhangsan soft nproc 4096
    zhangsan hard nproc 4096
    
    4 修改节点的配置文件jvm.options
      vim  /home/es/elasticsearch-6.4.0/config/jvm.options   (22行)
                   -Xms512m  
                   -Xmx512m
      原则:最小堆的大小和最大堆的大小应该相等。Elasticsearch可获得越多的堆,并且内存也可以使用更多的缓存。但是需要注意,分配了太多的堆给你的项目,将会导致有长时间的垃圾搜集停留。设置最大堆的值不能超过你物理内存的50%,要确保有足够多的物理内存来保证内核文件缓存。不要将最大堆设置高于JVM用于压缩对象指针的截止值。
        
    5,修改配置文件  ElasticSearch.yml
       vim /home/es/elasticsearch-6.4.0/config/elasticsearch.yml
    
    # ======================== Elasticsearch Configuration =========================
    #
    # NOTE: Elasticsearch comes with reasonable defaults for most settings.
    #       Before you set out to tweak and tune the configuration, make sure you
    #       understand what are you trying to accomplish and the consequences.
    #
    # The primary way of configuring a node is via this file. This template lists
    # the most important settings you may want to configure for a production cluster.
    #
    # Please consult the documentation for further information on configuration options:
    # https://www.elastic.co/guide/en/elasticsearch/reference/index.html
    #
    # ---------------------------------- Cluster -----------------------------------
    #
    # Use a descriptive name for your cluster:
    # 集群的名字 多个es如果共属于一个集群 name名字要配置的一样
    cluster.name: my-application
    #
    # ------------------------------------ Node ------------------------------------
    #
    # Use a descriptive name for the node:
    # 当前节点的名字  同一个集群中 node.name 不能重复
    node.name: node-1
    #
    # Add custom attributes to the node:
    #
    #node.attr.rack: r1
    #
    # ----------------------------------- Paths ------------------------------------
    #
    # Path to directory where to store the data (separate multiple locations by comma):
    # 将来的数据存储到哪个文件夹
    path.data: /home/es/elasticsearch-6.4.0/data
    #
    # Path to log files:
    #
    path.logs: /home/es/elasticsearch-6.4.0/logs
    #
    # ----------------------------------- Memory -----------------------------------
    #
    # Lock the memory on startup:
    #锁定物理内存地址,防止elasticsearch内存被交换出去,也就是避免es使用swap交换分区
    bootstrap.memory_lock: false
    #是否支持过滤掉系统调用  默认配置文件中没有这个配置 我们需要自己粘上去
    bootstrap.system_call_filter: false
    #
    # Make sure that the heap size is set to about half the memory available
    # on the system and that the owner of the process is allowed to use this
    # limit.
    #
    # Elasticsearch performs poorly when the system is swapping the memory.
    #
    # ---------------------------------- Network -----------------------------------
    #
    # Set the bind address to a specific IP (IPv4 or IPv6):
    #
    network.host: 192.168.239.160
    #
    # Set a custom port for HTTP:
    #
    http.port: 9200
    #
    # For more information, consult the network module documentation.
    #
    # --------------------------------- Discovery ----------------------------------
    #
    # Pass an initial list of hosts to perform discovery when new node is started:
    # The default list of hosts is ["127.0.0.1", "[::1]"]
    #当启动新节点时,通过这个ip列表进行节点发现,组建集群  写法可以是 ["192.168.239.170","192.168.239.171"]
    # 或者这样写 ["host1" , "host2"]  此时指代的是当前电脑的 hosts文件中配置的地址别名  
    discovery.zen.ping.unicast.hosts: ["es1", "es2","es3"]
    #
    # Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1):
    #通过配置这个参数来防止集群脑裂现象 (集群总节点数量/2)+1    配置代表最少有多少个服务器同意则 当大哥
    discovery.zen.minimum_master_nodes:  2
    #
    # For more information, consult the zen discovery module documentation.
    #
    # ---------------------------------- Gateway -----------------------------------
    #
    # Block initial recovery after a full cluster restart until N nodes are started:
    #
    #gateway.recover_after_nodes: 3
    #
    # For more information, consult the gateway module documentation.
    #
    # ---------------------------------- Various -----------------------------------
    #
    # Require explicit names when deleting indices:
    #
    #action.destructive_requires_name: true
    
    
    
    6 修改hosts文件 : vim  /etc/hosts
     
    127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    
    
    192.168.239.160   es1
    192.168.239.161   es2
    192.168.239.162   es3
    
    7 创建用户张三                           useradd  zhangsan
      让zhangsan这个用户 能操作 es这个文件夹    chown -R zhangsan:zhangsan  es
          
    [root@es-170 home]# ll
    total 0
    -rw-r--r--. 1 root     root      0 Dec 17 15:37 ccc
    drwxr-xr-x. 3 zhangsan zhangsan 67 Jan  4 16:24 es
    drwxr-xr-x. 2 root     root     56 Dec 23 16:30 myshell
    drwxr-xr-x. 2 root     root     48 Dec 18 15:51 test
    drwxr-xr-x. 3 root     root     69 Dec 23 17:01 tomcat8
    drwx------. 2 zhangsan zhangsan 62 Jan  4 17:03 zhangsan
    
    8 切换用户 :  su  zhangsan
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163

    5.2 集群搭建

    克隆当前ES  修改IP地址 houstname  重启  xshell连接
        
    修改 vim   vim /home/es/elasticsearch-6.4.0/config/elasticsearch.yml  下的IP地址和node.name
    
    三台电脑都切换到 zhangsan用户  启动    
    elasticsearch  -d
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.3 ES常用地址

    当我们运行es之后 就可以 用过 地址栏访问ES状态

    我们可以在 linux中使用

    curl  192.168.239.160:9200  访问 
    {
      "name" : "node-1",
      "cluster_name" : "my-application",
      "cluster_uuid" : "rCRURKcRS6aIvu_gkzs0og",
      "version" : {
        "number" : "6.4.0",
        "build_flavor" : "default",
        "build_type" : "tar",
        "build_hash" : "595516e",
        "build_date" : "2018-08-17T23:18:47.308994Z",
        "build_snapshot" : false,
        "lucene_version" : "7.4.0",
        "minimum_wire_compatibility_version" : "5.6.0",
        "minimum_index_compatibility_version" : "5.0.0"
      },
      "tagline" : "You Know, for Search"
    }
    也可以通过浏览器直接访问 也可以使用postman访问
    我们可以通过    
        curl  192.168.239.150:9200/_cat  查看当前es的信息
    
    =^.^=
    /_cat/allocation
    /_cat/shards
    /_cat/shards/{index}
    /_cat/master    查询当前集群的主节点
    /_cat/nodes
    /_cat/tasks
    /_cat/indices
    /_cat/indices/{index}
    /_cat/segments
    /_cat/segments/{index}
    /_cat/count
    /_cat/count/{index}
    /_cat/recovery
    /_cat/recovery/{index}
    /_cat/health
    /_cat/pending_tasks
    /_cat/aliases
    /_cat/aliases/{alias}
    /_cat/thread_pool
    /_cat/thread_pool/{thread_pools}
    /_cat/plugins
    /_cat/fielddata
    /_cat/fielddata/{fields}
    /_cat/nodeattrs
    /_cat/repositories
    /_cat/snapshots/{repository}
    /_cat/templates
    
    curl  es1:9200/_cat/nodes?v
    curl  es1:9200/_cat/health?v
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
       查看集群支持命令:
          curl 192.168.23.30:9200/_cat
      查看集群是否健康
          curl 192.168.23.30:9200/_cat/health
       查看master:
          curl 192.168.23.30:9200/_cat/master?v
       命令支持help:
          curl 192.168.23.30:9200/_cat/master?help
       查看所有索引:
           curl  192.168.23.30:9200/_cat/indices
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.4 ES添加索引

    数据类型
    核心类型(Core datatype)
    字符串:string,string类型包含 text 和 keyword。
        
    text:该类型被用来索引长文本,在创建索引前会将这些文本进行分词,转化为词的组合,建立索引;
          允许es来检索这些词,text类型不能用来排序和聚合。
    keyword:该类型不需要进行分词,可以被用来检索过滤、排序和聚合,keyword类型自读那只能用本身来进行检索
             (不可用text分词后的模糊检索)。
    数值型:long、integer、shortbytedoublefloat
    日期型:date 
    布尔型:boolean 
    二进制型:binary
    
    
    我们在es中创建一个索引(相当于我们创建了一个数据库)
    创建索引的时候 发送PUT请求  http://192.168.150.160:9200/索引的名称
    并且本次请求需要传递JSON数据类型的参数
    number_of_shards:每个索引的主分片数,这个配置在索引创建后不能修改。默认值为5
    number_of_replicas:每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改。   
    {
    	"settings": {
    		"number_of_shards": 3,
    		"number_of_replicas": 3
    	},
    	"mappings": {
    		"hahaha": {
    			"properties": {
    				"id": {
    					"type": "integer"
    				},
    				"name": {
    					"type": "text"
    				},
    				"age": {
    					"type": "integer"
    				},
    				"address": {
    					"type": "keyword"
    				}
    			}
    		}
    	}
    }
    此时使用postman发送请求  http://192.168.239.170:9200/test_index
    在请求的的body中选择raw选择json 把我们的建索引json参数添加  点击send 如果出现       
    {
        "acknowledged": true,
        "shards_acknowledged": true,
        "index": "test_index"
    }
    
    此时我们还可以修改索引
    修改索引
    PUT /索引名字/_settings
    {
      "number_of_replicas": 1
    }
    注意 副本可以改 分片不能改
    {"acknowledged":true}
    
    
    删除索引
    DELETE /索引名字                //删除单个索引
    DELETE /索引名字1,索引名字2      //删除多个索引
    DELETE /index_*               //删除以index_开头的索引
    DELETE /_all                  //删除所有索引
        
    {"acknowledged":true}
    可以设置下面的属性,使DELETE /_all 失效,必须指定索引名称,才可以删除。
    elasticsearch.yml
    action.destructive_requires_name: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    5.5 ES中添加数据

    添加数据 发送POST请求
    http://192.168.239.170:9200/test_index/hahaha/1    最后的1 代表第一条数据
    此时还需要通过参数将数据传递到ES中
    {
        "id":1,
        "name":"张三",
        "age":18,
        "address":"背景"
    }
    
    此时会提示添加成功  result= created
    {
        "_index": "test_index",
        "_type": "hahaha",
        "_id": "5",
        "_version": 1,
        "result": "created",
        "_shards": {
            "total": 4,
            "successful": 3,
            "failed": 0
        },
        "_seq_no": 3,
        "_primary_term": 1
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    5.6 ES中查询数据

    GET请求发送
        http://192.168.239.160:9200/test_index/hahaha/_search?q=id:5
        http://192.168.239.170:9200/test_index/hahaha/_search?q=name:a*
        http://192.168.239.170:9200/test_index/hahaha/_search?q=age:18
        http://192.168.239.170:9200/test_index/hahaha/_search?q=*:*
    
    复杂的查询
    POST请求  http://192.168.239.170:9200/test_index/hahaha/_search
    在请求的的body中选择raw选择json 把我们的建索引json参数添加  
        {
           "query": {
            "range" : {
                "age" : {
                    "gte": "20", 
                    "lte": "60"
                     }
                 }
             }
        }
    点击send 如果出现 查询的结果    
    {
        "took": 23,
        "timed_out": false,
        "_shards": {
            "total": 3,
            "successful": 3,
            "skipped": 0,
            "failed": 0
            },
            "hits": {
            "total": 1,
            "max_score": 1.0,
            "hits": [
                 {
                    "_index": "test_index",
                    "_type": "hahaha",
                    "_id": "3",
                    "_score": 1.0,
                    "_source": {
                        "id": 3,
                        "name": "adsfasdf",
                        "age": 28,
                        "address": "shanghai"
                    }
                }
            ]
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    六 Logstash

    6.1 安装

    选择一个ES上安装 Logstash  170安装
    cd  /home/es/
    使用xftp上传文件
    解压当前文件:tar -zxvf logstash-6.4.3.tar.gz
    
        
    安装logstash-input-jdbc插件  cd /home/es/logstash-6.4.3/bin
    执行脚本  ./logstash-plugin install logstash-input-jdbc
    cd   /home/es/logstash-6.4.3/config
    通过XFTP将我们的 mysql.conf 传输到当前文件夹
     input {
        jdbc {
          # 数据库
          jdbc_connection_string => "jdbc:mysql://192.168.31.155:3306/test?useSSL=false"
          # 用户名密码
          jdbc_user => "root"
          jdbc_password => "123456"
          # jar包的位置  路径不能写错 
          jdbc_driver_library => "/home/es/logstash-6.4.3/mysql-connector-java-5.1.47.jar"
          # mysql的Driver
          jdbc_driver_class => "com.mysql.jdbc.Driver"
          jdbc_paging_enabled => "true"
          jdbc_page_size => "50000"
          #清除第一次同步的时间,日志时间
          #clean_run => true 
    	  #写sql 例如 select  *  from t_student 
          statement_filepath => "/home/es/logstash-6.4.3/config/mysql.sql"
          # canel
          schedule => "* * * * *"
          #索引的类型  分词器类型
          type => "monitor_task_video_manual_history"
        }
    }
     
    filter {
        json {
            source => "message"
            remove_field => ["message"]
        }
    }
     
    output {
        elasticsearch {
            hosts => "192.168.239.160:9200"
            # index名
            index => "mysql_index"
            # 需要关联的数据库中一个id字段,对应索引的id号
            document_id => "%{id}"
        }
        stdout {
            codec => json_lines
        }
    } 
    新建并编辑SQL文件
    vim  /home/es/logstash-6.4.3/config/mysql.sql
        
    select  *  from student
    cd../home/es/logstash-6.4.3/下 将 数据库连接jar包存放到当前目录下
     
    一切准备就绪: 当前我们是root用户 修改权限
    chown  -R  zhangsan:zhangsan  /home/logstash-6.4.3
    切换用户  su  zhangsan
    cd /home/es/logstash-6.4.3/
            
    启动bin/logstash  -f    config/mysql.conf 
    
    
        
    测试数据
        
    GET  http://192.168.150.160:9200/mysql_index
    {
        "mysql_index": {
            "aliases": {},
            "mappings": {
                "doc": {
                    "properties": {
                        "@timestamp": {
                            "type": "date"
                        },
                        "@version": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "s_address": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "s_age": {
                            "type": "long"
                        },
                        "s_gid": {
                            "type": "long"
                        },
                        "s_id": {
                            "type": "long"
                        },
                        "s_name": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "type": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        }
                    }
                }
            },
            "settings": {
                "index": {
                    "creation_date": "1609835407433",
                    "number_of_shards": "5",
                    "number_of_replicas": "1",
                    "uuid": "Rti17zR-Rc2VsLAZrncTKg",
                    "version": {
                        "created": "6040099"
                    },
                    "provided_name": "mysql_index"
                }
            }
        }
    }
    
    GET 搜索数据
     http://192.168.239.150:9200/mysql_index/doc/_search?q=s_name:*
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145

    七 springboot整合es

    7.1 在pom文件中导入依赖

    总pom降低一下boot的版本
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.2.RELEASEversion>
      parent>
    在sys中导入
    <dependency>
              <groupId>org.springframework.bootgroupId>
              <artifactId>spring-boot-starter-data-elasticsearchartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    6.2 添加配置文件

    #ES集群的名字
    spring.data.elasticsearch.cluster-name=my-application
    #ES节点 ip:port  ① http请求 9200   JDK 9300
    spring.data.elasticsearch.cluster-nodes=192.168.239.170:9300,192.168.239.171:9300,192.168.239.172:9300
    
    • 1
    • 2
    • 3
    • 4

    6.3 添加实体类(entity domain)

    此时我们在es中导入的数据源是 MySQL中的test库里面的student表:s_id s_name s_age s_address.

    此时我们根据映射关系创建java对象存储当前每一行的数据

    @Data
    @Document(indexName = "mysql_index",type = "doc" ,shards=3 ,replicas = 3)
    public class ESStudent {
    
        @Id
        @JsonProperty("s_id")
        private  long      id;
        
        @JsonProperty("s_name")
        private  String    name;
        
        @JsonProperty("s_address")
        private  String    address;
        
        @JsonProperty("s_age")
        private  long      age;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    6.4 写一个DAO接口进行查询

    package com.aaa.dao;
    
    import com.aaa.entity.Student;
    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    
    public interface StudentDAO  extends ElasticsearchRepository<Student,Long> {   }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此时看一眼继承关系

    @NoRepositoryBean
    public interface ElasticsearchRepository<T, ID> extends ElasticsearchCrudRepository<T, ID> {
        <S extends T> S index(S var1);
    
        <S extends T> S indexWithoutRefresh(S var1);
    
        Iterable<T> search(QueryBuilder var1);
    
        Page<T> search(QueryBuilder var1, Pageable var2);
    
        Page<T> search(SearchQuery var1);
    
        Page<T> searchSimilar(T var1, String[] var2, Pageable var3);
    
        void refresh();
    
        Class<T> getEntityClass();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    @NoRepositoryBean
    public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
        Iterable<T> findAll(Sort var1);
    
        Page<T> findAll(Pageable var1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    @NoRepositoryBean
    public interface CrudRepository<T, ID> extends Repository<T, ID> {
        <S extends T> S save(S var1);
    
        <S extends T> Iterable<S> saveAll(Iterable<S> var1);
    
        Optional<T> findById(ID var1);
    
        boolean existsById(ID var1);
    
        Iterable<T> findAll();
    
        Iterable<T> findAllById(Iterable<ID> var1);
    
        long count();
    
        void deleteById(ID var1);
    
        void delete(T var1);
    
        void deleteAll(Iterable<? extends T> var1);
    
        void deleteAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    6.5 StudentDAO的使用方式

    @RestController
    @RequestMapping("/core")
    public class StudentController {
    
    
        @Autowired
        private StudentDAO  dao;
    
    
        /**
         * 获取所有的学生
         * 只能接收get的形式
         * @return
         */
       @GetMapping("/stu")
        public  Map  listAllStudent(){
    
           QueryBuilder  qb = null;
    
           Iterable<Student> search = dao.search(qb);
           Iterator<Student> iterator = search.iterator();
    
           List<Student> objects = new ArrayList<>();
    
           while (iterator.hasNext()){
               Student next = iterator.next();
               objects.add(next);
           }
    
           System.out.println(objects);
    
           HashMap<Object, Object> map = new HashMap<>();
            map.put("name","zhangsan");
            return map;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    此时我们就可以使用接口里面的CRUD方法对内容进行增删改查 我们重点使用查询方法

    6.6 JDK1.8对迭代的优化

    @GetMapping("/stu")
     public  Map  listAllStudent(){
    
        List<Student> objects = new ArrayList<>();
    
        QueryBuilder  qb = null;
    
        Iterable<Student> search = dao.search(qb);
    
        search.forEach(new Consumer<Student>() {
            @Override
            public void accept(Student student) {
                objects.add(student);
            }
        });
    
        System.out.println(objects);
    
        HashMap<Object, Object> map = new HashMap<>();
         map.put("name","zhangsan");
         return map;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    此时我们使用 forEach这个函数 对Iterable 迭代循环。用到匿名内部类的写法创建了Consumer对象。

    forEach是JDK1.8的新方法

     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEach(Consumer action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    但是我们new 匿名内部类的写法还是1.7的

    new Consumer<Student>() {
            @Override
            public void accept(Student student) {
                objects.add(student);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此时我们也可以对匿名内部类的写法进行1.8的优化 ----------------- lambda表达式

    @GetMapping("/stu")
     public  Map  listAllStudent(){
    
        List<Student> objects = new ArrayList<>();
    
        QueryBuilder  qb = null;
    
        Iterable<Student> search = dao.search(qb);
    
        search.forEach(   (Student student) -> objects.add(student)  );
    
        System.out.println(objects);
    
        HashMap<Object, Object> map = new HashMap<>();
         map.put("name","zhangsan");
         return map;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    6.7 搜索

    @Data
    public class StudentQuery implements Serializable {
    
        private  String  name;
        private  Integer  minAge;
        private  Integer  maxAge;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    创建一个搜索对象 用来接收前端传递过来的搜索的条件

     @PostMapping("/stu")
     public  Map  listAllStudent(StudentQuery  query){
    
        List<Student> objects = new ArrayList<>();
    
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    
        if(query.getName() != null && !"".equals(query.getName())){
            boolQueryBuilder.must(  QueryBuilders.wildcardQuery("s_name"  , "*"+query.getName()+"*")     );
        }
    
        if(query.getMinAge() != null ){
            boolQueryBuilder.must(  QueryBuilders.rangeQuery("s_age").gt(query.getMinAge())   );
        }
    
        if(query.getMaxAge() != null ){
            boolQueryBuilder.must(  QueryBuilders.rangeQuery("s_age").lt(query.getMaxAge())   );
        }
    
        Iterable<Student> search = dao.search(boolQueryBuilder);
    
        search.forEach(   (Student student) -> objects.add(student)  );
    
        System.out.println(objects);
    
        HashMap<Object, Object> map = new HashMap<>();
         map.put("name","zhangsan");
         return map;
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    6.8 分页功能

    @PostMapping("/stu")
    public  Map  listAllStudent(StudentQuery  query){
    
       List<Student> objects = new ArrayList<>();
    
       BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    
       if(query.getName() != null && !"".equals(query.getName())){
           boolQueryBuilder.must(  QueryBuilders.wildcardQuery("s_name"  , "*"+query.getName()+"*")     );
       }
    
       if(query.getMinAge() != null ){
           boolQueryBuilder.must(  QueryBuilders.rangeQuery("s_age").gt(query.getMinAge())   );
       }
    
       if(query.getMaxAge() != null ){
           boolQueryBuilder.must(  QueryBuilders.rangeQuery("s_age").lt(query.getMaxAge())   );
       }
    
       PageRequest page = PageRequest.of(1, 2);
    
       Iterable<Student> search = dao.search(null,page);
    
       search.forEach(   (Student student) -> objects.add(student)  );
    
       System.out.println(objects);
    
       HashMap<Object, Object> map = new HashMap<>();
       map.put("name","zhangsan");
       return map;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
  • 相关阅读:
    laravel框架解决sql注入问题
    2023北京信息科技大学考研介绍
    痞子衡嵌入式:瑞萨RA8系列高性能MCU开发初体验
    wzx-jmw:NFL合理,但可能被颠覆。2023-2024
    【VUE实战项目】使用typescript重构项目
    websocket学习笔记【springboot+websocket聊天室demo】
    《视觉SLAM十四讲》-- 后端 1(下)
    Rabbitmq的四种交换机类型
    GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图
    2023年安全员-C证证模拟考试题库及安全员-C证理论考试试题
  • 原文地址:https://blog.csdn.net/Liu_wen_wen/article/details/127433557