精华内容
下载资源
问答
  • Elasticsearch下载安装

    万次阅读 多人点赞 2019-07-31 19:26:09
    注:Elasticsearch 需要 Java 8 环境,在安装Elasticsearch之前先安装好JDK。 1、Windows版 1.1、下载 访问官网的下载地址:https://www.elastic.co/downloads/elasticsearch,windows版的下载ZIP格式的。 如果...

    注:Elasticsearch 需要 Java 8 环境,在安装Elasticsearch之前先安装好JDK。

    1、Windows版

    1.1、下载

    访问官网的下载地址:https://www.elastic.co/downloads/elasticsearch,windows版的下载ZIP格式的。

    如果不想下载最新版的,可以点击“past releases”选择过去的版本。我这里下载的是6.2.4版本的。

    1.2、解压

    解压下载的压缩包,比如我这里是解压到了D盘根目录,会出现D:\elasticsearch-6.2.4文件夹。

    1.3、启动

    进入elasticsearch的bin目录,双击elasticsearch.bat启动服务,默认端口是9200,如下图:

    启动完成之后,在浏览器中访问http://localhost:9200/,出现如下图所示内容表明Elasticsearch启动成功。

    2、linux版(centos7)

    2.1、下载

    可以按照windows版那样从官网下载TAR格式解压包,上传到linux服务器上。

    如果你的linux可以访问外网的话,推荐直接在linux中下载,执行如下命令:

    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz

    2.2、解压

    执行解压命令:

    tar -zxvf elasticsearch-6.2.4.tar.gz

    解压完成后,会出现elasticsearch-6.2.4目录。

    2.3、启动

    执行启动命令:

    ./bin/elasticsearch

    如果你是root用户启动的话,会报"can not run elasticsearch as root"的错误。因为安全问题elasticsearch不让用root用户直接运行,所以要创建新用户,继续阅读2.4步骤。

    2.4、创建新用户

    第一步:liunx创建新用户:"adduser yjclsx",然后给创建的用户加密码:"passwd yjclsx",输入两次密码。

    第二步:切换刚才创建的用户:"su yjclsx",然后启动elasticsearch。如果显示Permission denied权限不足,则继续进行第三步。

    第三步:给新用户赋权限,因为这个用户本身就没有权限,肯定自己不能给自己付权限。所以要用root用户登录并赋予权限,chown -R yjclsx/你的elasticsearch安装目录。

    通过上面三步就可以启动elasticsearch了。

    2.5、验证启动是否成功

    如果一切正常,Elasticsearch就会在默认的9200端口运行。这时,打开另一个命令行窗口,请求该端口:

    curl localhost:9200

    如果得到如下的返回,就说明启动成功了:

    2.6、远程访问elasticsearch服务

    默认情况下,Elasticsearch 只允许本机访问,如果需要远程访问,可以修改 Elasticsearch 安装目录中的config/elasticsearch.yml文件,去掉network.host的注释,将它的值改成0.0.0.0,让任何人都可以访问,然后重新启动 Elasticsearch 。

    network.host: 0.0.0.0

    上面代码中,"network.host:"和"0.0.0.0"中间有个空格,不能忽略,不然启动会报错。线上服务不要这样设置,要设成具体的 IP。

    2.7、常见错误及其解决方式

    错误一:max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]

    解决:执行下面的命令:

    sudo sysctl -w vm.max_map_count=262144

    错误二:max file descriptors [4096] for elasticsearch process likely too low, increase to at least [65536]

    解决:执行下面的命令:

    sudo vim /etc/security/limits.conf

    在limits.conf最下方加入下面两行(这里的yjclsx是之前2.4步骤中新建的用户名):

    yjclsx hard nofile 65536
    yjclsx soft nofile 65536

     

    展开全文
  • Elasticsearch配置文件(elasticsearch.yml)详解

    万次阅读 多人点赞 2019-07-31 19:26:52
    ##################### Elasticsearch Configuration Example ##################### # # 只是挑些重要的配置选项进行注释,其实自带的已经有非常细致的英文注释了! # https://www.elastic.co/g...

     原文地址:https://my.oschina.net/Yumikio/blog/805877

    ##################### Elasticsearch Configuration Example ##################### 
    #
    # 只是挑些重要的配置选项进行注释,其实自带的已经有非常细致的英文注释了!
    # https://www.elastic.co/guide/en/elasticsearch/reference/current/modules.html
    #
    ################################### Cluster ################################### 
    # 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的. 
    # es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。 
    # cluster.name可以确定你的集群名称,当你的elasticsearch集群在同一个网段中elasticsearch会自动的找到具有相同cluster.name的elasticsearch服务. 
    # 所以当同一个网段具有多个elasticsearch集群时cluster.name就成为同一个集群的标识. 
    
    # cluster.name: elasticsearch 
    
    #################################### Node ##################################### 
    # https://www.elastic.co/guide/en/elasticsearch/reference/5.1/modules-node.html#master-node
    # 节点名称同理,可自动生成也可手动配置. 
    # node.name: node-1
    
    # 允许一个节点是否可以成为一个master节点,es是默认集群中的第一台机器为master,如果这台机器停止就会重新选举master. 
    # node.master: true 
    
    # 允许该节点存储数据(默认开启) 
    # node.data: true 
    
    # 配置文件中给出了三种配置高性能集群拓扑结构的模式,如下: 
    # 1. 如果你想让节点从不选举为主节点,只用来存储数据,可作为负载器 
    # node.master: false 
    # node.data: true 
    # node.ingest: false
    
    # 2. 如果想让节点成为主节点,且不存储任何数据,并保有空闲资源,可作为协调器 
    # node.master: true 
    # node.data: false
    # node.ingest: false 
    
    # 3. 如果想让节点既不称为主节点,又不成为数据节点,那么可将他作为搜索器,从节点中获取数据,生成搜索结果等 
    # node.master: false 
    # node.data: false 
    # node.ingest: true (可不指定默认开启)
    
    # 4. 仅作为协调器 
    # node.master: false 
    # node.data: false
    # node.ingest: false
    
    # 监控集群状态有一下插件和API可以使用: 
    # Use the Cluster Health API [http://localhost:9200/_cluster/health], the 
    # Node Info API [http://localhost:9200/_nodes] or GUI tools # such as <http://www.elasticsearch.org/overview/marvel/>, 
    # <http://github.com/karmi/elasticsearch-paramedic>, 
    # <http://github.com/lukas-vlcek/bigdesk> and 
    # <http://mobz.github.com/elasticsearch-head> to inspect the cluster state. 
    
    # A node can have generic attributes associated with it, which can later be used 
    # for customized shard allocation filtering, or allocation awareness. An attribute 
    # is a simple key value pair, similar to node.key: value, here is an example: 
    # 每个节点都可以定义一些与之关联的通用属性,用于后期集群进行碎片分配时的过滤
    # node.rack: rack314 
    
    # 默认情况下,多个节点可以在同一个安装路径启动,如果你想让你的es只启动一个节点,可以进行如下设置
    # node.max_local_storage_nodes: 1 
    
    #################################### Index #################################### 
    # 设置索引的分片数,默认为5 
    #index.number_of_shards: 5 
    
    # 设置索引的副本数,默认为1: 
    #index.number_of_replicas: 1 
    
    # 配置文件中提到的最佳实践是,如果服务器够多,可以将分片提高,尽量将数据平均分布到大集群中去
    # 同时,如果增加副本数量可以有效的提高搜索性能 
    # 需要注意的是,"number_of_shards" 是索引创建后一次生成的,后续不可更改设置 
    # "number_of_replicas" 是可以通过API去实时修改设置的 
    
    #################################### Paths #################################### 
    # 配置文件存储位置 
    # path.conf: /path/to/conf 
    
    # 数据存储位置(单个目录设置) 
    # path.data: /path/to/data 
    # 多个数据存储位置,有利于性能提升 
    # path.data: /path/to/data1,/path/to/data2 
    
    # 临时文件的路径 
    # path.work: /path/to/work 
    
    # 日志文件的路径 
    # path.logs: /path/to/logs 
    
    # 插件安装路径 
    # path.plugins: /path/to/plugins 
    
    #################################### Plugin ################################### 
    # 设置插件作为启动条件,如果一下插件没有安装,则该节点服务不会启动 
    # plugin.mandatory: mapper-attachments,lang-groovy 
    
    ################################### Memory #################################### 
    # 当JVM开始写入交换空间时(swapping)ElasticSearch性能会低下,你应该保证它不会写入交换空间 
    # 设置这个属性为true来锁定内存,同时也要允许elasticsearch的进程可以锁住内存,linux下可以通过 `ulimit -l unlimited` 命令 
    # bootstrap.mlockall: true 
    
    # 确保 ES_MIN_MEM 和 ES_MAX_MEM 环境变量设置为相同的值,以及机器有足够的内存分配给Elasticsearch 
    # 注意:内存也不是越大越好,一般64位机器,最大分配内存别才超过32G 
    
    ############################## Network And HTTP ############################### 
    # 设置绑定的ip地址,可以是ipv4或ipv6的,默认为0.0.0.0 
    # network.bind_host: 192.168.0.1 
    
    # 设置其它节点和该节点交互的ip地址,如果不设置它会自动设置,值必须是个真实的ip地址 
    # network.publish_host: 192.168.0.1 
    
    # 同时设置bind_host和publish_host上面两个参数 
    # network.host: 192.168.0.1 
    
    # 设置节点间交互的tcp端口,默认是9300 
    # transport.tcp.port: 9300 
    
    # 设置是否压缩tcp传输时的数据,默认为false,不压缩
    # transport.tcp.compress: true 
    
    # 设置对外服务的http端口,默认为9200 
    # http.port: 9200 
    
    # 设置请求内容的最大容量,默认100mb 
    # http.max_content_length: 100mb 
    
    # 使用http协议对外提供服务,默认为true,开启 
    # http.enabled: false 
    
    ###################### 使用head等插件监控集群信息,需要打开以下配置项 ###########
    # http.cors.enabled: true
    # http.cors.allow-origin: "*"
    # http.cors.allow-credentials: true
    
    ################################### Gateway ################################### 
    # gateway的类型,默认为local即为本地文件系统,可以设置为本地文件系统 
    # gateway.type: local 
    
    # 下面的配置控制怎样以及何时启动一整个集群重启的初始化恢复过程 
    # (当使用shard gateway时,是为了尽可能的重用local data(本地数据)) 
    
    # 一个集群中的N个节点启动后,才允许进行恢复处理 
    # gateway.recover_after_nodes: 1 
    
    # 设置初始化恢复过程的超时时间,超时时间从上一个配置中配置的N个节点启动后算起 
    # gateway.recover_after_time: 5m 
    
    # 设置这个集群中期望有多少个节点.一旦这N个节点启动(并且recover_after_nodes也符合), 
    # 立即开始恢复过程(不等待recover_after_time超时) 
    # gateway.expected_nodes: 2
    
     ############################# Recovery Throttling ############################# 
    # 下面这些配置允许在初始化恢复,副本分配,再平衡,或者添加和删除节点时控制节点间的分片分配 
    # 设置一个节点的并行恢复数 
    # 1.初始化数据恢复时,并发恢复线程的个数,默认为4 
    # cluster.routing.allocation.node_initial_primaries_recoveries: 4 
    
    # 2.添加删除节点或负载均衡时并发恢复线程的个数,默认为2 
    # cluster.routing.allocation.node_concurrent_recoveries: 2 
    
    # 设置恢复时的吞吐量(例如:100mb,默认为0无限制.如果机器还有其他业务在跑的话还是限制一下的好) 
    # indices.recovery.max_bytes_per_sec: 20mb 
    
    # 设置来限制从其它分片恢复数据时最大同时打开并发流的个数,默认为5 
    # indices.recovery.concurrent_streams: 5 
    # 注意: 合理的设置以上参数能有效的提高集群节点的数据恢复以及初始化速度 
    
    ################################## Discovery ################################## 
    # 设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点.默认为1,对于大的集群来说,可以设置大一点的值(2-4) 
    # discovery.zen.minimum_master_nodes: 1 
    # 探查的超时时间,默认3秒,提高一点以应对网络不好的时候,防止脑裂 
    # discovery.zen.ping.timeout: 3s 
    
    # For more information, see 
    # <http://elasticsearch.org/guide/en/elasticsearch/reference/current/modules-discovery-zen.html> 
    
    # 设置是否打开多播发现节点.默认是true. 
    # 当多播不可用或者集群跨网段的时候集群通信还是用单播吧 
    # discovery.zen.ping.multicast.enabled: false 
    
    # 这是一个集群中的主节点的初始列表,当节点(主节点或者数据节点)启动时使用这个列表进行探测 
    # discovery.zen.ping.unicast.hosts: ["host1", "host2:port"] 
    
    # Slow Log部分与GC log部分略,不过可以通过相关日志优化搜索查询速度 
    
    ################  X-Pack ###########################################
    # 官方插件 相关设置请查看此处
    # https://www.elastic.co/guide/en/x-pack/current/xpack-settings.html
    # 
    ############## Memory(重点需要调优的部分) ################ 
    # Cache部分: 
    # es有很多种方式来缓存其内部与索引有关的数据.其中包括filter cache 
    
    # filter cache部分: 
    # filter cache是用来缓存filters的结果的.默认的cache type是node type.node type的机制是所有的索引内部的分片共享filter cache.node type采用的方式是LRU方式.即:当缓存达到了某个临界值之后,es会将最近没有使用的数据清除出filter cache.使让新的数据进入es. 
    
    # 这个临界值的设置方法如下:indices.cache.filter.size 值类型:eg.:512mb 20%。默认的值是10%。 
    
    # out of memory错误避免过于频繁的查询时集群假死 
    # 1.设置es的缓存类型为Soft Reference,它的主要特点是据有较强的引用功能.只有当内存不够的时候,才进行回收这类内存,因此在内存足够的时候,它们通常不被回收.另外,这些引用对象还能保证在Java抛出OutOfMemory异常之前,被设置为null.它可以用于实现一些常用图片的缓存,实现Cache的功能,保证最大限度的使用内存而不引起OutOfMemory.在es的配置文件加上index.cache.field.type: soft即可. 
    
    # 2.设置es最大缓存数据条数和缓存失效时间,通过设置index.cache.field.max_size: 50000来把缓存field的最大值设置为50000,设置index.cache.field.expire: 10m把过期时间设置成10分钟. 
    # index.cache.field.max_size: 50000 
    # index.cache.field.expire: 10m 
    # index.cache.field.type: soft 
    
    # field data部分&&circuit breaker部分: 
    # 用于fielddata缓存的内存数量,主要用于当使用排序,faceting操作时,elasticsearch会将一些热点数据加载到内存中来提供给客户端访问,但是这种缓存是比较珍贵的,所以对它进行合理的设置. 
    
    # 可以使用值:eg:50mb 或者 30%(节点 node heap内存量),默认是:unbounded #indices.fielddata.cache.size: unbounded 
    # field的超时时间.默认是-1,可以设置的值类型: 5m #indices.fielddata.cache.expire: -1 
    
    # circuit breaker部分: 
    # 断路器是elasticsearch为了防止内存溢出的一种操作,每一种circuit breaker都可以指定一个内存界限触发此操作,这种circuit breaker的设定有一个最高级别的设定:indices.breaker.total.limit 默认值是JVM heap的70%.当内存达到这个数量的时候会触发内存回收
    
    # 另外还有两组子设置: 
    #indices.breaker.fielddata.limit:当系统发现fielddata的数量达到一定数量时会触发内存回收.默认值是JVM heap的70% 
    #indices.breaker.fielddata.overhead:在系统要加载fielddata时会进行预先估计,当系统发现要加载进内存的值超过limit * overhead时会进行进行内存回收.默认是1.03 
    #indices.breaker.request.limit:这种断路器是elasticsearch为了防止OOM(内存溢出),在每次请求数据时设定了一个固定的内存数量.默认值是40% 
    #indices.breaker.request.overhead:同上,也是elasticsearch在发送请求时设定的一个预估系数,用来防止内存溢出.默认值是1 
    
    # Translog部分: 
    # 每一个分片(shard)都有一个transaction log或者是与它有关的预写日志,(write log),在es进行索引(index)或者删除(delete)操作时会将没有提交的数据记录在translog之中,当进行flush 操作的时候会将tranlog中的数据发送给Lucene进行相关的操作.一次flush操作的发生基于如下的几个配置 
    #index.translog.flush_threshold_ops:当发生多少次操作时进行一次flush.默认是 unlimited #index.translog.flush_threshold_size:当translog的大小达到此值时会进行一次flush操作.默认是512mb 
    #index.translog.flush_threshold_period:在指定的时间间隔内如果没有进行flush操作,会进行一次强制flush操作.默认是30m #index.translog.interval:多少时间间隔内会检查一次translog,来进行一次flush操作.es会随机的在这个值到这个值的2倍大小之间进行一次操作,默认是5s 
    #index.gateway.local.sync:多少时间进行一次的写磁盘操作,默认是5s 

    原文地址:https://my.oschina.net/Yumikio/blog/805877

    展开全文
  • springboot集成elasticsearch注意事项

    万次阅读 多人点赞 2019-07-31 19:27:29
    一、elasticsearch基础  这里假设各位已经简单了解过elasticsearch,并不对es进入更多的,更深层次的解释,如有必要,会在写文章专门进行es讲解。  Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。...

    一、elasticsearch基础

       这里假设各位已经简单了解过elasticsearch,并不对es进入更多的,更深层次的解释,如有必要,会在写文章专门进行es讲解。

      Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。

      但是,Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。

      Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

       index ==》索引 ==》Mysql中的一个库,库里面可以建立很多表,存储不同类型的数据,而表在ES中就是type。

       type ==》类型 ==》相当于Mysql中的一张表,存储json类型的数据

       document  ==》文档 ==》一个文档相当于Mysql一行的数据

       field ==》列 ==》相当于mysql中的列,也就是一个属性

     这里多说下:

    在Elasticsearch6.0.0或者或者更新版本中创建的索引只会包含一个映射类型(mappingtype)。在5.x中创建的具有多个映射类型的索引在Elasticsearch6.x中依然会正常工作。在Elasticsearch7.0.0中,映射类型type将会被完全移除。

    原文链接

      开始的时候,我们说“索引(index)”类似于SQL数据库中的“数据库”,将“类型(type)”等同于“表”。

      这是一个糟糕的类比,并且导致了一些错误的假设。在SQL数据库中,表之间是相互独立的。一个表中的各列并不会影响到其它表中的同名的列。而在映射类型(mappingtype)中却不是这样的。

       在同一个Elasticsearch索引中,其中不同映射类型中的同名字段在内部是由同一个Lucene字段来支持的。换句话说,使用上面的例子,user类型中的user_name字段与tweet类型中的user_name字段是完全一样的,并且两个user_name字段在两个类型中必须具有相同的映射(定义)。

       这会在某些情况下导致一些混乱,比如,在同一个索引中,当你想在其中的一个类型中将deleted字段作为date类型,而在另一个类型中将其作为boolean字段。

       在此之上需要考虑一点,如果同一个索引中存储的各个实体如果只有很少或者根本没有同样的字段,这种情况会导致稀疏数据,并且会影响到Lucene的高效压缩数据的能力。

       基于这些原因,将映射类型的概念从Elasticsearch中移除。

    二、springboot 对应的Es版本关系

    springboot elasticsearch
    2.0.0.RELEASE2.2.0
    1.4.0.M11.7.3
    1.3.0.RELEASE1.5.2
    1.2.0.RELEASE1.4.4
    1.1.0.RELEASE1.3.2
    1.0.0.RELEASE1.1.1

      1、None of the configured nodes are available 或者org.elasticsearch.transport.RemoteTransportException: Failed to deserialize exception response from stream

      原因:spring data elasticSearch 的版本与Spring boot、Elasticsearch版本不匹配。

    这是版本之间的对应关系。Spring boot 1.3.5默认的elasticsearch版本是1.5.2,此时启动1.7.2版本以下的Elasticsearch客户端连接正常。

      注:注意java的es默认连接端口是9300,9200是http端口,这两个在使用中应注意区分。

      2、Caused by: java.lang.IllegalArgumentException: @ConditionalOnMissingBean annotations must specify at least one bean (type, name or annotation)

      原因:spring boot是1.3.x版本,而es采用了2.x版本。在es的2.x版本去除了一些类,而这些类在spring boot的1.3.x版本中仍然被使用,导致此错误

        以上解决参考下面的对应关系

    Spring Boot Version (x)Spring Data Elasticsearch Version (y)Elasticsearch Version (z)
    x <= 1.3.5y <= 1.3.4z <= 1.7.2*
    x >= 1.4.x2.0.0 <=y < 5.0.0**2.0.0 <= z < 5.0.0**

       请一定注意版本兼容问题。这关系到很多maven依赖。Spring Data Elasticsearch Spring Boot version matrix

    ik 分词对应的版本关系:

      elasticsearch-analysis-ik

    Analyzer:

       ik_smart , ik_max_word , Tokenizer: ik_smart , ik_max_word

    Versions

    IK versionES version
    master6.x -> master
    6.2.26.2.2
    6.1.36.1.3
    5.6.85.6.8
    5.5.35.5.3
    5.4.35.4.3
    5.3.35.3.3
    5.2.25.2.2
    5.1.25.1.2
    1.10.62.4.6
    1.9.52.3.5
    1.8.12.2.1
    1.7.02.1.1
    1.5.02.0.0
    1.2.61.0.0
    1.2.50.90.x
    1.1.30.20.x
    1.0.00.16.2 -> 0.19.0

    三、环境构建

    maven依赖:前提是依赖

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>1.5.9.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

    配置文件:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    # ES

    #开启 Elasticsearch 仓库(默认值:true)

    spring.data.elasticsearch.repositories.enabled=true

    #默认 9300 是 Java 客户端的端口。9200 是支持 Restful HTTP 的接口

    spring.data.elasticsearch.cluster-nodes = 127.0.0.1:9300

    #spring.data.elasticsearch.cluster-name Elasticsearch 集群名(默认值: elasticsearch)

    #spring.data.elasticsearch.cluster-nodes 集群节点地址列表,用逗号分隔。如果没有指定,就启动一个客户端节点

    #spring.data.elasticsearch.propertie 用来配置客户端的额外属性

    #存储索引的位置

    spring.data.elasticsearch.properties.path.home=/data/project/target/elastic

    #连接超时的时间

    spring.data.elasticsearch.properties.transport.tcp.connect_timeout=120s

     四、es索引实体类

    Spring-data-elasticsearch为我们提供了@Document@Field等注解,如果某个实体需要建立索引,只需要加上这些注解即可

    1.类上注解:@Document (相当于Hibernate实体的@Entity/@Table)(必写),加上了@Document注解之后,默认情况下这个实体中所有的属性都会被建立索引、并且分词。

    类型属性名默认值说明
    StringindexName索引库的名称,建议以项目的名称命名
    Stringtype“”类型,建议以实体的名称命名
    shortshards5默认分区数
    shortreplica1每个分区默认的备份数
    StringrefreshInterval“1s”刷新间隔
    StringindexStoreType“fs”索引文件存储类型

    2.主键注解:@Id (相当于Hibernate实体的主键@Id注解)(必写)

    只是一个标识,并没有属性。

    3.属性注解 @Field (相当于Hibernate实体的@Column注解)

    @Field默认是可以不加的,默认所有属性都会添加到ES中。加上@Field之后,@document默认把所有字段加上索引失效,只有家@Field 才会被索引(同时也看设置索引的属性是否为no)

     

    类型属性名默认值说明
    FieldTypetypeFieldType.Auto自动检测属性的类型
    FieldIndexindexFieldIndex.analyzed默认情况下分词
    booleanstorefalse默认情况下不存储原文
    StringsearchAnalyzer“”指定字段搜索时使用的分词器
    StringindexAnalyzer“”指定字段建立索引时指定的分词器
    String[]ignoreFields{}如果某个字段需要被忽略
     

    五、相关查询方法

     官网参考

      实现方式比较多,已经存在的接口,使用根据需要继承即可:

      1、CrudRepository接口 

    public interface CrudRepository<T, ID extends Serializable>
      extends Repository<T, ID> {
    
      <S extends T> S save(S entity);      
    
      Optional<T> findById(ID primaryKey); 
    
      Iterable<T> findAll();               
    
      long count();                        
    
      void delete(T entity);               
    
      boolean existsById(ID primaryKey);   
    
      // … more functionality omitted.
    }

      2、PagingAndSortingRepository接口

    public interface PagingAndSortingRepository<T, ID extends Serializable>
      extends CrudRepository<T, ID> {
    
      Iterable<T> findAll(Sort sort);
    
      Page<T> findAll(Pageable pageable);
    }

     例子:

    分页:

    PagingAndSortingRepository<User, Long> repository = // … get access to a bean
    Page<User> users = repository.findAll(new PageRequest(1, 20));
    

    计数:

    interface UserRepository extends CrudRepository<User, Long> {
    
      long countByLastname(String lastname);
    }  

      3、其他,参考官网

    自定义查询实现

    那么我们如何自定义方法呢?我们只要使用特定的单词对方法名进行定义,那么Spring就会对我们写的方法名进行解析, 

    该机制条前缀find…Byread…Byquery…Bycount…By,和get…By从所述方法和开始分析它的其余部分。引入子句可以包含进一步的表达式,如Distinct在要创建的查询上设置不同的标志。然而,第一个By作为分隔符来指示实际标准的开始。在非常基础的层次上,您可以定义实体属性的条件并将它们与And和连接起来Or

    interface PersonRepository extends Repository<User, Long> {
    
      List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
    
      // Enables the distinct flag for the query
      List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
      List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
    
      // Enabling ignoring case for an individual property
      List<Person> findByLastnameIgnoreCase(String lastname);
      // Enabling ignoring case for all suitable properties
      List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
    
      // Enabling static ORDER BY for a query
      List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
      List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
    }

      构建查询属性算法原理

    如上例所示。在查询创建时,确保解析的属性是托管类的属性。但是,你也可以通过遍历嵌套属性来定义约束。假设Person x有一个Address和 ZipCode。在这种情况下,方法名称为

    List<Person> findByAddressZipCode(ZipCode zipCode);
    

    创建属性遍历x.address.zipCode。解析算法首先将整个part(AddressZipCode)作为属性进行解释,然后检查具有该名称属性的类。如果皮匹配成功,则使用该属性。如果不是属性,则算法拆分从右侧的驼峰部分头部和尾部,并试图找出相应的属性,在我们的例子,AddressZipCode。如果算法找到具有该头部的属性,它将采用尾部并继续从那里构建树,然后按照刚刚描述的方式分割尾部。如果第一个分割不匹配,则算法将分割点移动到左侧(AddressZipCode)并继续。

    虽然这应该适用于大多数情况,但算法仍可能会选择错误的属性。假设这个Person类也有一个addressZip属性。该算法将在第一轮拆分中匹配,并且基本上选择错误的属性并最终失败(因为addressZip可能没有code属性的类型)。

    为了解决这个歧义,你可以\_在你的方法名称中使用手动定义遍历点。所以我们的方法名称会像这样结束:

    List<Person> findByAddress_ZipCode(ZipCode zipCode);
    由于我们将下划线视为保留字符,因此我们强烈建议遵循标准的Java命名约定(即,不要在属性名称中使用下划线,而应使用驼峰大小写)
    
    其他分页查询
    
    Page<User> findByLastname(String lastname, Pageable pageable);
    
    Slice<User> findByLastname(String lastname, Pageable pageable);
    
    List<User> findByLastname(String lastname, Sort sort);
    

    也可以用Java8 Stream查询和sql语句查询

    1

    2

    3

    4

    5

    6

    7

    @Query("select u from User u")

    Stream<User> findAllByCustomQueryAndStream();

     

    Stream<User> readAllByFirstnameNotNull();

     

    @Query("select u from User u")

    Stream<User> streamAllPaged(Pageable pageable);

    有些在复杂的可以使用es查询语句

    我们可以使用@Query注解进行查询,这样要求我们需要自己写ES的查询语句

    public interface BookRepository extends ElasticsearchRepository<Book, String> {
        @Query("{"bool" : {"must" : {"field" : {"name" : "?0"}}}}")
        Page<Book> findByName(String name,Pageable pageable);
    }
    

    方法和es查询转换:

    KeywordSampleElasticsearch Query String

    And

    findByNameAndPrice

    {"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}

    Or

    findByNameOrPrice

    {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}

    Is

    findByName

    {"bool" : {"must" : {"field" : {"name" : "?"}}}}

    Not

    findByNameNot

    {"bool" : {"must_not" : {"field" : {"name" : "?"}}}}

    Between

    findByPriceBetween

    {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

    LessThanEqual

    findByPriceLessThan

    {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

    GreaterThanEqual

    findByPriceGreaterThan

    {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}

    Before

    findByPriceBefore

    {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}

    After

    findByPriceAfter

    {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}

    Like

    findByNameLike

    {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}

    StartingWith

    findByNameStartingWith

    {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}

    EndingWith

    findByNameEndingWith

    {"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}

    Contains/Containing

    findByNameContaining

    {"bool" : {"must" : {"field" : {"name" : {"query" : "?","analyze_wildcard" : true}}}}}

    In

    findByNameIn(Collection<String>names)

    {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}

    NotIn

    findByNameNotIn(Collection<String>names)

    {"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}

    Near

    findByStoreNear

    Not Supported Yet !

    True

    findByAvailableTrue

    {"bool" : {"must" : {"field" : {"available" : true}}}}

    False

    findByAvailableFalse

    {"bool" : {"must" : {"field" : {"available" : false}}}}

    OrderBy

    findByAvailableTrueOrderByNameDesc

    {"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

    六、between使用注意

      在使用的时候没有找到直接的例子,由于between是转换成range,所以需要范围参数from和to,

     举例如下:

    Page<Recruit> findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(String recruitWork, String recruitCitys, Integer workType, Date fromXjTime, Date toXjTime,Pageable pageable);

    注意:这里必须要注意的是:只要使用了between参数,****XjTimeBetween(......,from,to) ,使用该方法的时候,必须要传递范围参数from,to,不能同时为空。

    否则异常

    <strong>org.springframework.dao.InvalidDataAccessApiUsageException: Range [* TO *] is not allowed</strong>
    
        at org.springframework.data.elasticsearch.core.query.Criteria.between(Criteria.java:304)
    
        at org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator.from(ElasticsearchQueryCreator.java:127)
    
        at org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator.and(ElasticsearchQueryCreator.java:76)
    
        at org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator.and(ElasticsearchQueryCreator.java:46)
    
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createCriteria(AbstractQueryCreator.java:109)
    
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:88)
    
        at org.springframework.data.repository.query.parser.AbstractQueryCreator.createQuery(AbstractQueryCreator.java:73)
    
        at org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery.createQuery(ElasticsearchPartQuery.java:102)
    
        at org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery.execute(ElasticsearchPartQuery.java:51)
    
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:499)
    
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:477)
    
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    
        at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:56)
    
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
    
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
    
        at com.sun.proxy.$Proxy86.findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(Unknown Source)
    
        at com.zhimingdeng.service.impl.EsIndexServiceImpl.findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(EsIndexServiceImpl.java:155)

    因为底层要求参数不能同时为空

    七、es时间类型注意

       对于Elasticsearch原生支持date类型,json格式通过字符来表示date类型。所以在用json提交日期至elasticsearch的时候,es会隐式转换,把es认为是date类型的字符串直接转为date类型,间字段内容实际上就是转换成long类型作为内部存储的(所以完全可以接受其他时间格式作为时间字段的内容)。至于什么样的字符串es会认为可以转换成date类型,参考elasticsearch官网介绍

      date类型是包含时区信息的,如果我们没有在json代表日期的字符串中显式指定时区,对es来说没什么问题,但是对于我们来说可能会发现一些时间差8个小时的问题。

      Elastic本身有一种特殊的时间格式,其形式如"2016-01-25T00:00:00",此格式为ISO8601标准。具体时间日期格式要求可以参见es官方文档

      然而我们在计算日期间隔,甚至按日分类的时候,往往需要把这个String时间转化为Unix时间戳(Unix Timestamp(时间戳))的形式,再进行计算。而通常,这个时间戳会以毫秒的形式(Java)保存在一个long类型里面,这就涉及到了String与long类型的相互转化。

      此外在使用Java Client聚合查询日期的时候,需要注意时区问题,因为默认的es是按照UTC标准时区算的,所以不设置的聚合统计结果是不正确的。默认不设置时区参数,es是安装UTC的时间进行查询的,所以分组的结果可能与预期不一样。  

      JSON 没有日期类型,因此在 Elasticsearch 中可以表达成:

    1. 日期格式化的字符串,比如: "2018-01-01" 或者 "2018/01/01 01:01:30";
    2. 毫秒级别的 long 类型或秒级别的 integer 类型,比如: 1515150699465, 1515150699;

      实际上不管日期以何种格式写入,在 ES 内部都会先穿换成 UTC 时间并存储为 long 类型。日期格式可以自定义,如果没有指定的话会使用以下的默认格式:

      "strict_date_optional_time||epoch_millis"

      因此总结来说,不管哪种可以表示时间的格式写入,都可以用来表示时间

      所以这里引出多种解决方案:

       1、es 默认的是 utc 时间,而国内服务器是 cst 时间,首先有时间上的差距需要转换。但是如果底层以及上层都统一用时间戳,完美解决时区问题。但是时间戳对我们来说不直观 

      2、我们在往es提交日期数据的时候,直接提交带有时区信息的日期字符串,如:“2016-07-15T12:58:17.136+0800”

      3、还有另外的一种:   

     直接设置format为你想要的格式,比如 "yyyy-MM-dd HH:mm:ss" 然后存储的时候,指定格式,并且Mapping  也是指定相同的format 。

      第一次使用方式:

    1

    2

    3

    4

     @Field( type = FieldType.Date,

                format = DateFormat.custom,pattern = date_optional_time"

        )

    private Date gmtCreate;

    我这里是数据是从数据库直接读取,使用的datetime类型,原来直接使用的时候,抛异常:

      MapperParsingException[failed to parse [***]]; nested: IllegalArgumentException[Invalid format: "格式"];

      原因是: jackson库在转换为json的时候,将Date类型转为为了long型的字符串表示,而我们定义的是date_optional_time格式的字符串,所以解析错误,

      具体的解决办法:去掉注解中的format=DateFormat.date_optional_time,让其使用默认的格式,也就是 'strict_date_optional_time||epoch_millis' , 既能接受        date_optional_time格式的,也能接受epoch_millis格式,由于为了查看更直观感受改为如下:

      @Field( type = FieldType.Date,
                format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        )
    private Date gmtCreate;

     改成这样后,底层多种格式都可以存储,如果没有根据时间进行范围查找,这里基本上已经就告一段落了。

    时间范围查找需求:存储Date,和取出来也是Dete

    存储的时候利用各种JSON对象,如 Jackson 等。存储的时候就可以用JSON Format一下再存储,然后取出来后

      @Field( type = FieldType.Date,
                format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss"
        )
        @JsonFormat (shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
        private Date xjTime;

     有了这个注解后,

        timezone="GMT+8" 主要是因为底层存放的数据日期时区是UTC,这里转换成GMT
    

     真实存储格式如下(高能瞎眼):

    时间范围查找需求注意:

    根据条件查询的时候,时间范围需要传入range,这里涉及到了两种选择,底层查询方法实现的时候range的参数为

     1.date:

     传入的是date参数,然后就行查询的时候,会报异常,因为我把日期转成了yyyy-MM-dd HH:mm:ss,但是底层数据是2018-03-27T16:00:00.000Z这种格式,导致错误,详细异常如下

    org.elasticsearch.action.search.SearchPhaseExecutionException: all shards failed
    
        at org.elasticsearch.action.search.AbstractSearchAsyncAction.onFirstPhaseResult(AbstractSearchAsyncAction.java:206)
    
        at org.elasticsearch.action.search.AbstractSearchAsyncAction$1.onFailure(AbstractSearchAsyncAction.java:152)
    
        at org.elasticsearch.action.ActionListenerResponseHandler.handleException(ActionListenerResponseHandler.java:46)
    
        at org.elasticsearch.transport.TransportService$DirectResponseChannel.processException(TransportService.java:855)
    
        at org.elasticsearch.transport.TransportService$DirectResponseChannel.sendResponse(TransportService.java:833)
    
        at org.elasticsearch.transport.TransportService$4.onFailure(TransportService.java:387)
    
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:39)
    
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    
        at java.lang.Thread.run(Thread.java:745)
    
    <strong>Caused by: org.elasticsearch.ElasticsearchParseException: failed to parse date field [2018-03-27T16:00:00.000Z] with format [yyyy-MM-dd HH:mm:ss]</strong>
    
        at org.elasticsearch.common.joda.DateMathParser.parseDateTime(DateMathParser.java:203)
    
        at org.elasticsearch.common.joda.DateMathParser.parse(DateMathParser.java:67)
    
        at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType.parseToMilliseconds(DateFieldMapper.java:451)
    
        at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType.innerRangeQuery(DateFieldMapper.java:435)
    
        at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType.access$000(DateFieldMapper.java:199)
    
        at org.elasticsearch.index.mapper.core.DateFieldMapper$DateFieldType$LateParsingQuery.rewrite(DateFieldMapper.java:224)
    
        at org.apache.lucene.search.BooleanQuery.rewrite(BooleanQuery.java:278)
    
        at org.apache.lucene.search.IndexSearcher.rewrite(IndexSearcher.java:837)
    
        at org.elasticsearch.search.internal.ContextIndexSearcher.rewrite(ContextIndexSearcher.java:81)
    
        at org.elasticsearch.search.internal.DefaultSearchContext.preProcess(DefaultSearchContext.java:231)
    
        at org.elasticsearch.search.query.QueryPhase.preProcess(QueryPhase.java:103)
    
        at org.elasticsearch.search.SearchService.createContext(SearchService.java:676)
    
        at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:620)
    
        at org.elasticsearch.search.SearchService.executeDfsPhase(SearchService.java:264)
    
        at org.elasticsearch.search.action.SearchServiceTransportAction$SearchDfsTransportHandler.messageReceived(SearchServiceTransportAction.java:360)
    
        at org.elasticsearch.search.action.SearchServiceTransportAction$SearchDfsTransportHandler.messageReceived(SearchServiceTransportAction.java:357)
    
        at org.elasticsearch.transport.TransportRequestHandler.messageReceived(TransportRequestHandler.java:33)
    
        at org.elasticsearch.transport.RequestHandlerRegistry.processMessageReceived(RequestHandlerRegistry.java:75)
    
        at org.elasticsearch.transport.TransportService$4.doRun(TransportService.java:376)
    
        at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37)
    
        ... 3 common frames omitted
    
    <strong>Caused by: java.lang.IllegalArgumentException: Invalid format: "2018-03-27T16:00:00.000Z" is malformed at "T16:00:00.000Z"</strong>
    
        at org.joda.time.format.DateTimeParserBucket.doParseMillis(DateTimeParserBucket.java:187)
    
        at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:826)
    
        at org.elasticsearch.common.joda.DateMathParser.parseDateTime(DateMathParser.java:200)
    
        ... 22 common frames omitted

    实现参考:解决:传入的date参数格式化成底层的类型  

    Page<Recruit> findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(String recruitWork, String recruitCitys, Integer workType, Date fromXjTime, Date toXjTime,Pageable pageable);
    

      2.String:

     参数直接使用string,避免上层转换成不合适的时间格式,使用框架底层自己转换,避免错误。

    实现参考:
    Page<Recruit> findByRecruitWorkAndRecruitCitysAndWorkTypeAndXjTimeBetween(String recruitWork, String recruitCitys, Integer workType, String fromXjTime, String toXjTime,Pageable pageable);
    

    es时间自定义类型

    https://stackoverflow.com/questions/29122071/elasticsearch-failed-to-parse-date

    https://stackoverflow.com/questions/29496081/spring-data-elasticsearchs-field-annotation-not-working

    https://stackoverflow.com/questions/32042430/elasticsearch-spring-data-date-format-always-is-long

    八、使用注意

      个人认为springboot 这种集成es的方法,最大的优点是开发速度快,不要求对es一些api要求熟悉,能快速上手,即使之前对es不胜了解,也能通过方法名或者sql快速写出自己需要的逻辑,而具体转换成api层的操作,则有框架底层帮你实现。

      缺点也显而易见首先,使用的springboot的版本对es的版本也有了要求,不能超过es的某些版本号,部署时需要注意。第二,速度提升的同时,也失去了一些实用api的灵活性。一些比较灵活的条件封装不能很容易的实现。各有利弊,各位权衡。

    原文地址:http://www.cnblogs.com/guozp/p/8686904.html

    展开全文
  • Elasticsearch学习,请先看这一篇!

    万次阅读 多人点赞 2016-08-18 21:08:36
    题记:Elasticsearch研究有一段时间了,现特将Elasticsearch相关核心知识、原理从初学者认知、学习的角度,从以下9个方面进行详细梳理。欢迎讨论……0. 带着问题上路——ES是如何产生的?(1)思考:大规模数据如何...

    全网最新 | Elasticsearch 7.X 进阶实战视频课

    Elasticsearch 最少必要知识实战教程直播回放

    题记:

    Elasticsearch研究有一段时间了,现特将Elasticsearch相关核心知识、原理从初学者认知、学习的角度,从以下9个方面进行详细梳理。欢迎讨论…

    0. 带着问题上路——ES是如何产生的?

    (1)思考:大规模数据如何检索?

    如:当系统数据量上了10亿、100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题:
    1)用什么数据库好?(mysql、sybase、oracle、达梦、神通、mongodb、hbase…)
    2)如何解决单点故障;(lvs、F5、A10、Zookeep、MQ)
    3)如何保证数据安全性;(热备、冷备、异地多活)
    4)如何解决检索难题;(数据库代理中间件:mysql-proxy、Cobar、MaxScale等;)
    5)如何解决统计分析问题;(离线、近实时)

    (2)传统数据库的应对解决方案

    对于关系型数据,我们通常采用以下或类似架构去解决查询瓶颈和写入瓶颈:
    解决要点:
    1)通过主从备份解决数据安全性问题;
    2)通过数据库代理中间件心跳监测,解决单点故障问题;
    3)通过代理中间件将查询语句分发到各个slave节点进行查询,并汇总结果
    这里写图片描述

    (3)非关系型数据库的解决方案

    对于Nosql数据库,以mongodb为例,其它原理类似:
    解决要点:
    1)通过副本备份保证数据安全性;
    2)通过节点竞选机制解决单点问题;
    3)先从配置库检索分片信息,然后将请求分发到各个节点,最后由路由节点合并汇总结果
    这里写图片描述

    另辟蹊径——完全把数据放入内存怎么样?

    我们知道,完全把数据放在内存中是不可靠的,实际上也不太现实,当我们的数据达到PB级别时,按照每个节点96G内存计算,在内存完全装满的数据情况下,我们需要的机器是:1PB=1024T=1048576G
    节点数=1048576/96=10922个
    实际上,考虑到数据备份,节点数往往在2.5万台左右。成本巨大决定了其不现实!

    从前面讨论我们了解到,把数据放在内存也好,不放在内存也好,都不能完完全全解决问题。
    全部放在内存速度问题是解决了,但成本问题上来了。
    为解决以上问题,从源头着手分析,通常会从以下方式来寻找方法:
    1、存储数据时按有序存储;
    2、将数据和索引分离;
    3、压缩数据;
    这就引出了Elasticsearch。

    1. ES 基础一网打尽

    1.1 ES定义

    ES=elaticsearch简写, Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。
    Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

    1.2 Lucene与ES关系?

    1)Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。

    2)Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

    1.3 ES主要解决问题:

    1)检索相关数据;
    2)返回统计结果;
    3)速度要快。

    1.4 ES工作原理

    当ElasticSearch的节点启动后,它会利用多播(multicast)(或者单播,如果用户更改了配置)寻找集群中的其它节点,并与之建立连接。这个过程如下图所示:
    这里写图片描述

    1.5 ES核心概念

    1)Cluster:集群。

    ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。

    2)Node:节点。

    形成集群的每个服务器称为节点。

    3)Shard:分片。

    当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片。每个分片放到不同的服务器上。
    当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在。即:这个过程对用户来说是透明的。

    4)Replia:副本。

    为提高查询吞吐量或实现高可用性,可以使用分片副本。
    副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片。
    当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

    5)全文检索。

    全文检索就是对一篇文章进行索引,可以根据关键字搜索,类似于mysql里的like语句。
    全文索引就是把内容根据词的意义进行分词,然后分别创建索引,例如”你们的激情是因为什么事情来的” 可能会被分词成:“你们“,”激情“,“什么事情“,”来“ 等token,这样当你搜索“你们” 或者 “激情” 都会把这句搜出来。

    1.6 ES数据架构的主要概念(与关系数据库Mysql对比)

    这里写图片描述
    (1)关系型数据库中的数据库(DataBase),等价于ES中的索引(Index)
    (2)一个数据库下面有N张表(Table),等价于1个索引Index下面有N多类型(Type),
    (3)一个数据库表(Table)下的数据由多行(ROW)多列(column,属性)组成,等价于1个Type由多个文档(Document)和多Field组成。
    (4)在一个关系型数据库里面,schema定义了表、每个表的字段,还有表和字段之间的关系。 与之对应的,在ES中:Mapping定义索引下的Type的字段处理规则,即索引如何建立、索引类型、是否保存原始索引JSON文档、是否压缩原始JSON文档、是否需要分词处理、如何进行分词处理等。
    (5)在数据库中的增insert、删delete、改update、查search操作等价于ES中的增PUT/POST、删Delete、改_update、查GET.

    1.7 ELK是什么?

    ELK=elasticsearch+Logstash+kibana
    elasticsearch:后台分布式存储以及全文检索
    logstash: 日志加工、“搬运工”
    kibana:数据可视化展示。
    ELK架构为数据分布式存储、可视化查询和日志解析创建了一个功能强大的管理链。 三者相互配合,取长补短,共同完成分布式大数据处理工作。

    2. ES特点和优势

    1)分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到。
    2)实时分析的分布式搜索引擎。
    分布式:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作;
    负载再平衡和路由在大多数情况下自动完成。
    3)可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。也可以运行在单台PC上(已测试)
    4)支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。

    3、ES性能

    3.1 性能结果展示

    (1)硬件配置:
    CPU 16核 AuthenticAMD
    内存 总量:32GB
    硬盘 总量:500GB 非SSD

    (2)在上述硬件指标的基础上测试性能如下:
    1)平均索引吞吐量: 12307docs/s(每个文档大小:40B/docs)
    2)平均CPU使用率: 887.7%(16核,平均每核:55.48%)
    3)构建索引大小: 3.30111 GB
    4)总写入量: 20.2123 GB
    5)测试总耗时: 28m 54s.

    3.2 性能esrally工具(推荐)

    使用参考:http://blog.csdn.net/laoyang360/article/details/52155481

    4、为什么要用ES?

    4.1 ES国内外使用优秀案例

    1) 2013年初,GitHub抛弃了Solr,采取ElasticSearch 来做PB级的搜索。 “GitHub使用ElasticSearch搜索20TB的数据,包括13亿文件和1300亿行代码”。

    2)维基百科:启动以elasticsearch为基础的核心搜索架构。
    3)SoundCloud:“SoundCloud使用ElasticSearch为1.8亿用户提供即时而精准的音乐搜索服务”。
    4)百度:百度目前广泛使用ElasticSearch作为文本数据分析,采集百度所有服务器上的各类指标数据及用户自定义数据,通过对各种数据进行多维分析展示,辅助定位分析实例异常或业务层面异常。目前覆盖百度内部20多个业务线(包括casio、云分析、网盟、预测、文库、直达号、钱包、风控等),单集群最大100台机器,200个ES节点,每天导入30TB+数据。

    4.2 我们也需要

    实际项目开发实战中,几乎每个系统都会有一个搜索的功能,当搜索做到一定程度时,维护和扩展起来难度就会慢慢变大,所以很多公司都会把搜索单独独立出一个模块,用ElasticSearch等来实现。

    近年ElasticSearch发展迅猛,已经超越了其最初的纯搜索引擎的角色,现在已经增加了数据聚合分析(aggregation)和可视化的特性,如果你有数百万的文档需要通过关键词进行定位时,ElasticSearch肯定是最佳选择。当然,如果你的文档是JSON的,你也可以把ElasticSearch当作一种“NoSQL数据库”, 应用ElasticSearch数据聚合分析(aggregation)的特性,针对数据进行多维度的分析。

    【知乎:热酷架构师潘飞】ES在某些场景下替代传统DB
    个人以为Elasticsearch作为内部存储来说还是不错的,效率也基本能够满足,在某些方面替代传统DB也是可以的,前提是你的业务不对操作的事性务有特殊要求;而权限管理也不用那么细,因为ES的权限这块还不完善。
    由于我们对ES的应用场景仅仅是在于对某段时间内的数据聚合操作,没有大量的单文档请求(比如通过userid来找到一个用户的文档,类似于NoSQL的应用场景),所以能否替代NoSQL还需要各位自己的测试。
    如果让我选择的话,我会尝试使用ES来替代传统的NoSQL,因为它的横向扩展机制太方便了。

    5. ES的应用场景是怎样的?

    5.1 通常我们面临问题有两个:

    1)新系统开发尝试使用ES作为存储和检索服务器;
    2)现有系统升级需要支持全文检索服务,需要使用ES。
    以上两种架构的使用,以下链接进行详细阐述。
    http://blog.csdn.net/laoyang360/article/details/52227541

    5.2 一线公司ES使用场景:

    1)新浪ES 如何分析处理32亿条实时日志 http://dockone.io/article/505
    2)阿里ES 构建挖财自己的日志采集和分析体系 http://afoo.me/columns/tec/logging-platform-spec.html
    3)有赞ES 业务日志处理 http://tech.youzan.com/you-zan-tong-ri-zhi-ping-tai-chu-tan/
    4)ES实现站内搜索 http://www.wtoutiao.com/p/13bkqiZ.html

    6. 如何部署ES?

    6.1 ES部署(无需安装)

    1)零配置,开箱即用
    2)没有繁琐的安装配置
    3)java版本要求:最低1.7
    我使用的1.8
    [root@laoyang config_lhy]# echo $JAVA_HOME
    /opt/jdk1.8.0_91
    4)下载地址:
    https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/zip/elasticsearch/2.3.5/elasticsearch-2.3.5.zip
    5)启动
    cd /usr/local/elasticsearch-2.3.5
    ./bin/elasticsearch
    bin/elasticsearch -d(后台运行)

    6.2 ES必要的插件

    必要的Head、kibana、IK(中文分词)、graph等插件的详细安装和使用。
    http://blog.csdn.net/column/details/deep-elasticsearch.html

    6.3 ES windows下一键安装

    自写bat脚本实现windows下一键安装。
    1)一键安装ES及必要插件(head、kibana、IK、logstash等)
    2)安装后以服务形式运行ES。
    3)比自己摸索安装节省至少2小时时间,效率非常高。
    脚本说明:
    http://blog.csdn.net/laoyang360/article/details/51900235

    7. ES对外接口(开发人员关注)

    1)JAVA API接口

    http://www.ibm.com/developerworks/library/j-use-elasticsearch-java-apps/index.html

    2)RESTful API接口

    常见的增、删、改、查操作实现:
    http://blog.csdn.net/laoyang360/article/details/51931981

    8.ES遇到问题怎么办?

    1)国外:https://discuss.elastic.co/
    2)国内:http://elasticsearch.cn/

    参考:

    [1] http://www.tuicool.com/articles/7fueUbb
    [2] http://zhaoyanblog.com/archives/495.html
    [3]《Elasticsearch服务器开发》
    [4]《实战Elasticsearch、Logstash、Kibana》
    [5]《Elasticsearch In Action》
    [6]《某ES大牛PPT》

    9、还有吗?

    《死磕 Elasticsearch 方法论》:普通程序员高效精进的 10 大狠招!(免费完整版)
    https://blog.csdn.net/laoyang360/article/details/79293493
    ——————————————————————————————————
    更多ES相关实战干货经验分享,请扫描下方【铭毅天下】微信公众号二维码关注。
    (每周至少更新一篇!)

    这里写图片描述
    和你一起,死磕Elasticsearch
    ——————————————————————————————————

    2016-08-18 21:10 思于家中床前

    作者:铭毅天下
    转载请标明出处,原文地址:
    http://blog.csdn.net/laoyang360/article/details/52244917
    如果感觉本文对您有帮助,请点击‘顶’支持一下,您的支持是我坚持写作最大的动力,谢谢!

    展开全文
  • ElasticSearch分布式搜索引擎安装教程

    万次阅读 多人点赞 2021-03-10 11:27:49
    ElasticSearch分布式搜索引擎安装教程 ​ 专注小Du博客,每天分享干货知识。CSDN博客地址: 在正式开始安装教程之前,小Du先带大家来了解什么是ElasticSearch。 一.Hr:ElasticSearch是什么? ​ 答:Elasticsearch...
  • Elasticsearch的使用场景深入详解

    万次阅读 多人点赞 2016-08-17 08:40:56
    1、场景—:使用Elasticsearch作为主要的后端传统项目中,搜索引擎是部署在成熟的数据存储的顶部,以提供快速且相关的搜索能力。这是因为早期的搜索引擎不能提供耐用的​​存储或其他经常需要的功能,如统计。 ...
  • ElasticSearch简介

    万次阅读 多人点赞 2019-05-18 08:51:31
    摘自Elasticsearch-基础介绍及索引原理分析 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单...
  • elasticsearch-jdbc实现MySQL同步到ElasticSearch深入详解

    万次阅读 多人点赞 2016-06-16 20:43:07
    1.如何实现mysql与elasticsearch的数据同步?逐条转换为json显然不合适,需要借助第三方工具或者自己实现。核心功能点:同步增、删、改、查同步。2、mysql与elasticsearch同步的方法有哪些?优缺点对比?目前该领域...
  • docker安装Elasticsearch和Elasticsearch-head

    万次阅读 2021-02-04 11:47:30
    docker安装Elasticsearch和Elasticsearch-head一、Elasticsearch是什么?二、安装步骤1.docker安装Elasticsearch2.docker安装Elasticsearch-head总结 一、Elasticsearch是什么? Elasticsearch是一个基于Lucene的...
  • ElasticSearch是否有架构? 1、ElasticSearch可以有一个架构。架构是描述文档类型以及如何处理文档的不同字段的一个或多个字段的描述。Elasticsearch中的架构是一种映射,它描述了JSON文档中的字段及其数据类型,...
  • Elasticsearch增、删、改、查操作深入详解

    万次阅读 多人点赞 2016-07-17 13:30:19
    全网最新 | Elasticsearch 7.X 进阶实战视频课 Elasticsearch 最少必要知识实战教程直播回放 引言: 对于刚接触ES的童鞋,经常搞不明白ES的各个概念的含义。尤其对“索引”二字更是与关系型数据库混淆的不行。本文...
  • Elasticsearch 简介

    万次阅读 多人点赞 2019-08-08 16:04:31
    Elasticsearch是一个非常强大的搜索引擎。它目前被广泛地使用于各个IT公司。Elasticsearch是由Elastic公司创建并开源维护的。它的开源代码位于https://github.com/elastic/elasticsearch。同时,Elastic公司也拥有...
  • 有一种情况,当我们启动elasticsearch之后, 经过很长一段时间没有操作, 自己已经忘了是否已经启动了elasticsearch, 这时候我们可以通过下面的方式验证是否启动,并重新启动: step1 查找ES进程号 ps -ef | ...
  • Linux上安装配置Elasticsearch

    万次阅读 2021-02-25 15:04:01
    Linux上安装配置Elasticsearch安装配置Elasticsearch环境准备环境配置 安装配置Elasticsearch 环境准备 下载 自行去Elasticsearch官网进行下载,也可到百度网盘(提取码:kudt)下载7.6.2版本 安装前准备 上传下载...
  • 如何监控 Elasticsearch 集群状态? Marvel 让你可以很简单的通过 Kibana 监控 Elasticsearch。你可以实时查看你的集群健康状态和性能,也可以分析过去的集群、索引和节点指标。
  • Elasticsearch Search API

    千次阅读 2018-06-22 12:29:39
    实现对es中存储的数据进行查询分析,endpoint为_search,查询主要有两种形式: URI Search:操作简便,方便通过命令行测试,仅包含部分查询语法 Request Body Search:es提供完备查询语法Query DSL(Domain ...
  • SpringBoot整合ElasticSearch详细过程

    万次阅读 多人点赞 2018-10-19 16:01:10
    使用IntelliJ创建SpringBoot工程 SpringBoot版本为2.0.4 ElasticSearch为5.6.10 删掉蓝框中的文件(如上) 最后我们的目录结构(如下) 下面pom文件主要修改的是把spring boot从IntelliJ默认的版本换成2.0.4以及...
  • 干货 | Elasticsearch Nested类型深入详解

    万次阅读 多人点赞 2018-10-06 13:08:20
    在Elasticsearch实战场景中,我们或多或少会遇到嵌套文档的组合形式,反映在ES中称为父子文档。 父子文档的实现,至少包含以下两种方式: 1)父子文档 父子文档在5.X版本中通过parent-child父子type实现,即:1个...
  • Linux上搭建Elasticsearch 7.6.2 集群

    万次阅读 2021-02-25 15:40:59
    Linux上搭建Elasticsearch 7.6.2 集群 Elasticsearch 7.6.2 集群搭建1. 环境准备2. 配置集群 Elasticsearch 7.6.2 集群搭建 1. 环境准备 安装Elasticsearch 7.6.2 服务器: 192.168.232.4 (Master) 192.168.232....
  • 详述 Elasticsearch 通过范围条件查询索引数据的方法

    万次阅读 多人点赞 2019-04-05 11:15:59
    在使用 Elasticsearch 的时候,我们可能会遇到需要**以范围为条件查询索引数据**的需求。有两种方法可以实现我们的需求: - 第一种:在服务器或者终端,使用命令来查询索引数据; - 第二种:编写程序,通过 Elastic...
  • ElasticSearch中的分析器是什么? 1、在ElasticSearch中索引数据时,数据由为索引定义的Analyzer在内部进行转换。 分析器由一个Tokenizer和零个或多个TokenFilter组成。编译器可以在一个或多个CharFilter之前。分析...
  • 近期,Elastic开发者向Elasticsearch-py提交了一个PR,增加了一个验证逻辑,限制用户使用Elasticsearch客户端连接到由AWS创建维护的Elasticsearch分支OpenSearch,以及跟AWS相关的Elasticsearch产品和服务。...
  • Elasticsearch6.3内置支持 SQL,我们可以像操作 MySQL一样使用 Elasticsearch,这样我们就可以减少 DSL 的学习成本,这个 SQL 模块是属于 X-Pack 的一部分。Elasticsearch SQL 主要有以下几个特点: 1. 允许我们在 ...
  • ElasticSearch7.0.0安装sql

    万次阅读 2020-04-08 11:23:58
    切换到elasticsearch的home目录执行: bin/elasticsearch-plugin install https://github.com/NLPchina/elasticsearch-sql/releases/download/7.0.0.0/elasticsearch-sql-7.0.0.0.zip 修改config/elasticsearch....
  • 新版本的SpringBoot 2的spring-boot-starter-data-elasticsearch中支持的Elasticsearch版本是2.X, 但Elasticsearch实际上已经发展到6.5.X版本了,为了更好的使用Elasticsearch的新特性, 所以弃用了spring-boot-...
  • docker pull elasticsearch:7.8.0 docker run -d --name elasticsearch \ -p 9200:9200 -p 9300:9300 \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ -e "discovery.type=single-node" \ elasticsearch:7.8.0 ...
  • Elasticsearch实战

    万次阅读 2020-12-02 09:06:50
    第一课时:Elasticsearch、Kibana安装
  • Elasticsearch-JSON串查询总结

    万次阅读 2017-10-06 08:55:08
    对Elasticsearch的JSON方式查询总结
  • 【elasticsearch系列】安装elasticsearch-head插件

    千次阅读 多人点赞 2021-09-05 13:35:28
    目录环境安装node安装gruntelasticsearch-head运行修改elasticsearch.yml排查问题 环境 安装elasticsearch-head插件,需要依赖nodeJs环境,故首先我们先搭建nodeJs环境; 此part先将此篇文章需要的各个官网列出来: ...
  • 20、为什么要使用Elasticsearch? 因为在我们商城中的数据,将来会非常多,所以采用以往的模糊查询,模糊查询前置配置,会放弃索引,导致商品查询是全表扫面,在百万级别的数据库中,效率非常低下,而我们使用ES做一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,529,203
精华内容 611,681
关键字:

search