全文搜索存储引擎 Elasticsearch 一点点

开始请大家想一个问题,如何统计一个Web站点的有效PV?

针对用户请求的URL,统计时做模式匹配-------->即用户真正去打开一个站点的有效页面并对每个页面的入口的访问做一个统计浏览量;


简要搜索引擎

搜索引擎在互联网上特别多有专业(Startpage,Google,Yahoo,Baidu)等也有非专业开源(北大搜索、任何基于Lucene库的二次开发搜索代理引擎)等;
其重点都是用来做海量数据搜索存储、分析,并且根据用户指定的filter来过滤出用户所需要的数据。而背后所需基础组件无外乎是 索引链、搜索组件;

索引链:
能够把数据收集进来,存储下来并为其构建一个索引,即把数据收集起来构建索引;
索引链实现独立步骤:检索原始内容,根据原始内容创建文档,对文档完成索引构建等;
搜索组件:
程序的组成部分,主要提供用户界面(UI)比如 Elasticsearch;


核心 Lucene

  • Lucene是什么,它能做什么?
    • Lucene的重点是文档 如果你想操作lucene就得先给它创建“数据库”,在“数据表”中一行一行插入数据,数据插入成功后你就可以向操作MySQL那样来实现增删改查操作了;
    • 如果你想了解它更多信息可参考官方网,参考IBM站点我觉得你会理解的比较快基础,初识Lucene;
  • Lucene 文档
    • 文档:lucene里的文档是索引和搜索的最原子单位,包含了一个或多个域的容器,由field+value组成;
    • 什么叫"域":文档包含多个键值对,这个键值对就叫"域"。而一个文档可包含一个或多个键值对,真正搜索是对value进行搜索,且无需事先定义任何结构,无全局模式;
    • 域的分析过程: 创建域时可为域指定多个选项来控制lucene在将文档添加进域索引后对该域可以执行哪些操作,此过程我们称之为域的分析过程;
    • 域的多个选项: 即索引选项,存储选项,项量使用选项,可单独或组合使用;

      域索引选项:索引选项用于通过倒排索引来控制文本是否可被搜索,如何被索引;
      Index:ANYLYZED:
      分析(切词)并单独作为索引项;
      Index.Not_ANYLYZED:
      不分析(不切词),把整个文档当一个索引项;
      Index.ANYLYZED_NORMS:
      类似于Index:ANALYZED,但不存储token的Norms(加权基准)信息;
      Index.Not_ANYLYZED_NORMS:
      类似于Index.Not_ANYLYZED,但不存储值的Norms(加权基准)信息;
      Index.No:
      不对此域的值进行索引,因此不能被搜索;
      域存储选项:是否需要存储域的真实值,如何被存储;
      store.YES:存储真实值,占用存储空间并返回真实值;
      store.NO:不存储真实值,不占用存储空间;
      域向量选项:
      域向量选项用于在搜索期间该文档所有的唯一项都能完全从文档中检索时使用;
      文档和域的加权操作:
      搜索时如有多个文档都出现了某个词,我们认为即哪个文档权值更高哪个就排在前面,默认都无加权值;


在Lucene中搜索

  • 查询Lucene索引时它返回的是一个有序(根据评分返回)的scoreDOC对象。查询时lucene会为每个文档计算出分值/score并根据分值进行排序,如果想完成查询就需要利用自身API来查询;
  • Lucene 查询API:
    IndexSearcher:搜索索引入口
    Query及其子类:查询及其子类
    QueryParser:查询分析器
    TopDocs:保存查询分值较高的前10
    ScoreDoc:数组
  • Lucene的多样化查询:在IndexSearch类中的search方法搜索,有多种搜索方法;
    TermQuery:对索引中的特定项进行搜索。Term是索引中最小索引片段,每个Term包含了一个域的一个文本值
    TermRangQuery:在索引中的多个特定项中进行搜索,能搜索指定的多个域
    NumericRangeQuery;做数值范围搜索
    PrefixQuery:用来搜索以指定字符串开头的项
    BooleanQuery:实现组合搜索查询,逻辑有 AND,OR,NOT
    PhraseQuery:根据位置信息,定位文档
    WildcardQuery:通配符查询
    FuzzyQuery:模糊查询,根据模算法计算查询,levenshtein距离算法
  • 在Lucene当中每个可被搜索的文档(组件)就放在索引当中,多个文档组合就叫做索引;
  • 在Lucene当中每个索引就是一个有大量文档组合起来形成的组建,就叫做索引;
  • 在Lucene当中每个索引对应存储在磁盘上并表现为物理文件;
  • 在Lucene当中整个可被搜索文档都存储在整个索引中,可直接被搜索;

认识 ES

  • ES是一个基于Lucene实现的开源、分布式、Restful风格的全文本搜索引擎。实时文档存储,对每个文档的每个field均是被索引的数据且可都被搜索;
  • ES也是一个带实时分析功能的分布式搜索引擎,能够扩展至数以百计的节点实时处理PB级数据;
  • Git站点,这个站点是官方的关于ES的介绍都在这里 elastic/elasticsearch
  • ES官方的Doc文档及插件帮助页 Elasticsearch Reference

ES 的基本组件:

索引(index):文档容器可理解为索引是具有类似属性的文档集合,类似于表。切记索引名必须为小写字母;
类型(type):类型是索引内部的逻辑分区,其意义完全取决于用户需求,一个索引内部可定义一个或多个类型,类型就是其拥有相同的域的文档的预定义,建议一个索引只存一类数据;
文档(document):文档是lucene索引的搜索原子单位,它包含了一个或多个域。是域的容器;
每个域的组成部分:一个名字,一个或多个值。拥有多个值的域,通常称为‘多值域’;
映射(mapping):原始内容存储为文档需要事先分析(如何切词,哪些可以过滤等)分析完后要定义这个分析,定义这个分析后让它怎么去根据这个定义去搜索实现,这个过程就叫映射;
例如:切词、过滤掉某些词等。除此之外ES还为映射提供了诸如将域中的内容排序等功能;


ES 的集群组件:

Cluster:
ES的集群标识为集群名称,默认为elasticsearch。节点就是靠此名字来决定加入到哪个集群中。一个节点只能属于一个集群;
Node:
运行了单个ES实例的主机即为节点。用于存储数据、参与集群索引及搜索操作,节点的标识靠‘节点名’;
Shard:
将索引切割成为的物理存储组件,但每个shard都是一个独立且完整的索引;创建索引时ES默认将每个索引分割为5个shard,用户可自定义,不可更改;
shard两个类型:
   primary shard和replica(副本),每个主shard都应该有一个副本shard,副本用于数据冗余及查询时的负载均衡,用户可自定义副本动态创建多个replica;


ES 的集群工作过程:

  • ES启动时通过多播(默认)或单播方式监听在TCP/9300端口下去查找同一集群中的其它节点,并与之建立通信;
  • 集群中的所有节点会选举一个主节点负责管理整个集群状态,以及在集群范围内决定各shards的分布方式;
     (站在用户角度每个节点均可接收并响应用户的各类请求,无需区分谁是主节点)
  • 集群状态:green、red、yellow
    • 必要时主节点会读取各节点状态信息并启动修复过程,在此过程中主节点会检查所有可用shard的主shard并确定主shard是否存在,这时集群状态转换为yellow状态;
    • 在yellow状态下各副本shareds均处于未分配模式(只能使用主的),副本不可用,读请求无法执行,吞吐能力下降;
    • 要做的任务是:检查主shard是否在,如果在再检查副本shards是否够数,如果主shard不在就把某个主shard的副本提升为主shard,副本不够还要填足,等整个过程,执行完成后再从yellow转换为green状态;
    • 主节点每周期性检查各节点是否在线(类似心跳信息)并且可用状态,任意节点不可用修复模式立刻启动。集群将进行重新均衡;
    • ES的选举:在选举主节点时会自动执行;

ES 的安装及API:

  • 安装jdk
    ~]# yum install -y java-1.8.0-openjdk 
    ~]# wget https://download.elastic.co/elasticsearch/elasticsearch/elasticsearch-1.7.2.noarch.rpm
    ~]# yum install -y elasticsearch-1.7.2.noarch.rpm

  • 修改配置文件
    ~]# cp /etc/elasticsearch/elasticsearch.yml{,.bak}
    ~]# vim /etc/elasticsearch/elasticsearch.yml
    • 默认是一个节点可直接启动,没有切片和副本的意义,可设置 index.number_of_shards:1,index.number_of_replicas:0
    • 这里主要说些用的配置,其它的可自行参考官方文档进行配置
       cluster name: myes 集群名称,各node节点就是靠此名字来决定加入哪个集群中且一个节点只属一个集群
       node name:"node1" 自己节点的名字,运行单个ES实例的主机即为节点
       node.master: ture 如果被选举是否可以是主的
       node.master: false 不参与选举
       node.data: true 可不可以存储数据
       index.number_of_shards:5 每一个索引默认的shards数量
       index.number_of_replicas:1 每一个shard的默认的副本
       transport.tcp.port: 9300 参与集群时选举的端口
       http.port: 9200 elasticsearch自身工作端口,接受用户查询请求端口

  • 启动ES
    ~]# systemctl daemon-reload
    ~]# systemctl enable elasticsearch.service 
    ~]# systemctl start elasticsearch.service 
    ~]# systemctl status elasticsearch.service
    按照以上方法依次启动其它两个节点,即可构成ES集群(三个节点构成ES的集群)
    可抓包看报文传输状态  tcpdump -i ens33 -nn -p tcp port 9300
    浏览器访问  http://172.10.10.103:9200/

  • Elasticsearch访问接口

监听于 9200/tcp,使用curl命令进行交互,所有的api访问都是以'下划线访问'
curl -X<verb> '<protocol>://host:port/<path>?<query_string>' -d '<body>'
 verb:http协议的请求方法 get,put,delete...
 protocol:http协议 http,https
 query_string:查询的字符串,例如:?pretty表示用易读的JSON格式输出
 body:请求的主体信息


  • 确定集群工作是否正常,可通过API查看
    • 四种 Restful 风格的 API:
      (1) 检查集群、节点、索引等健康与否和获取其相应状态
      (2) 管理集群、节点、索引及元数据
      (3) 执行CRUD操作(增、删、查、改)
      (4) 执行高级操作,如:paging,filtering等

  • 给出一些示例供参考
    • 查看elasticsearch 工作是否正常
      ~]# curl -X get 'http://localhost:9200/?preey'
      {
      "status" : 200,
      "name" : "node3",
      "cluster_name" : "myes",
      "version" : {
      "number" : "1.7.2",
      "build_hash" : "e43676b1385b8125d647f593f7202acbd816e8ec",
      "build_timestamp" : "2015-09-14T09:49:53Z",
      "build_snapshot" : false,
      "lucene_version" : "4.10.4"
      },
      "tagline" : "You Know, for Search"
      }
    • 查看elasticsearch 集群工作状态(需要通过cluster接口查询),也可使用_cat查看
      ~]# curl -X get 'http://localhost:9200/_cat/nodes?v'
      host                  ip        heap.percent ram.percent load node.role master name
      localhost.localdomain 127.0.0.1            4          36 0.10 d         *      node3 
      host:表示主机名 
      ip:表示主机ip
      heap.percent:堆内存占用内存量
      ram.percent:ram内存使用量
      load:平均负载
      node.role:节点的角色(d表示数据节点)
      master:*号表示主节点
      name:表示节点名称
    • 获取帮助及其它
      curl -X get 'http://localhost:9200/_cat/nodes?help' 获取帮助
      curl -X get 'http://localhost:9200/_cat/nodes?h=name,ip,port...' 自定义字段
      curl -X get 'http://localhost:9200/_cat/nodes' 显示集群中节点
      curl -X get 'http://localhost:9200/_cat/nodes?V' 显示详细格式


ES 插件Plugins

插件可扩展ES功能,并且用户可根据自己需要开发扩展功能,比如可添加自定义的映射类型、自定义分析器、本地脚本、自定义发现方式等;

  • ES 的插件安装方式有两种(互联网安装、本地安装)
    • 本地安装:
      直接将下载后插件包(一般zip格式)的文件解压出来放置于plugins目录下即可
      ~]# tar xf marvel-latest.zip && mv mar* /usr/share/elasticsearch/plugins
      也可将下载下来的zip插件包使用plugin脚本进行本地安装
      ~]# /usr/share/elasticsearch/bin/plugin -i marvel -u file:///root/marvel-latest.zip
    • 互联网安装:
      ~]# /usr/share/elasticsearch/bin/plugin -i marvel -u ftp://172.16.0.1/pub/elk/plugins/marvel-latest.zip
      ~]# /usr/share/elasticsearch/bin/plugin -i lukas-vlcek/bigdesk
  • 站点程序的访问可通过_plugin接口访问
    http://localhost:9200/_plugin/marvel
    curl -x get 'http://localhost:9200/_cat/indicies' 

ES_CRUD操作相关API(增、删、改、查)

针对数据库的增、删、改、查、操作 官方文档路径 Document APIs

  • 创建文档(PUT):
curl -XPUT 'http://172.10.10.101:9200/students/class1/1?pretty' -d '
{
"first_name": "Jing",
"last_name": "Guo",
"gender": "Male",
"age": 24,
}'
获取文档的时候,直接给出文档而非关键字
curl -XGET 'http://172.10.10.101:9200/students/class1/1?pretty'  
  • 删除文档(DELETE)
    • curl -XDELETE 'localhost:9200/students/class1/1'
    • curl -XGET 'localhost:9200/students/class1/1?pretty'
    • 删除索引(不可逆,只能重建)
      curl -XGET 'localhost:9200/_cat/indices?v'
      curl -XDELETE 'localhost:9200/movies'
  • 更新文档(PUT 或 UPDATE)
    • 注意:直接put会覆盖原有文档,使用update api
    • 做表单提交的方式利用update api修改文档内年龄24改为23
      [[email protected]_node1 ~]# curl -XPOST 'localhost:9200/students/class1/1/_update?pretty' -d '
      {
      "doc": { "age": 23 }
      }'
      curl -XGET 'localhost:9200/students/class1/1?pretty'

查询数据(Query API)

Query Domain Search Language JSON based language for building complex queries
用于实现诸多类型的查询操作如:simple term query,phrase,range boolean,fuzzy......

  • ES的查询操作执行分为多个阶段:
     分散阶段:把整个查询操作分散到shards所在的整个节点上去;
     合并阶段:将所有shard的返回结果合并起来并返回给查询者;
  • ES的查询方式:
    • 目标向ES发起的查询请求方式有两种
      (1) Query String 通过Restful request API查询;
      (2) Filter DSL 通过发送REST request body 进行查询;
  • 全量查询
    • curl -XGET 'localhost:9200/students/_search?pretty'
  • Body方式查询
    • curl -XGET 'localhost:9200/students/_search?pretty' -d '
  • 多索引多类型查询
    /_search:所有索引查询
    /INDEX_NAME/_search 单索引查询
    /INDEX1,INDEX2/_search 多索引查询
    /s*,t*/_search:
    /students/class1/_search 单类型
    /students/class1,class2/_search 多类型
  • Mapping和Analysis(映射与分析)

    ES对每一个文档会取得其所有域的所有值,生成一个名为"_all"的域。如果在query_string未指定查询的域时则在_all域上执行查询操作;

  • 在一个文档的所有域中搜索
    • GET /_serarch?q='Xianglong'
    • GET /_serarch?q='Xianglong%20Shiba%20Zhang'
  • 在一个文档内指定域的位置做精确搜索
    • GET /_serarch?q=courses:'Xianglong'
    • GET /_serarch?q=courses:'Xianglong%20Shiba%20Zhang'
    • GET /_search?q=name:'Guo%20Jing'
    • curl -XGET 'localhost:9200/students/_mapping/class1?pretty'
  • 数据类型:string,numbes,boolean,dates
    • 在ES中搜索数据有两种类型,可理解为
       type:exact:精确搜索
      精确值:未经加工的原始值,在搜索时进行精确匹配;
       full-text:全文搜索
      用于引用文本中数据,判断文档在多个程序上匹配查询请求,即评估文档与用户请求查询的相关度;
    • note1:为了完成full-text全文搜索,ES必须首先分析文本,并创建出倒排索引并且索引中将数据正规化;
    • note2:分词+正规化操作即是分析,分析需要使用分析器来完成 analyzer;
  • ES 内置分析器
    • 分析器的组成三部分:字符过滤器,分词器,分词过滤器
    • 分析器可以在创建索引时用到,并且在构建查询时也会用到
    • 内置1 Standard analyzer:标准分析器(默认),根据unicode标准分析
    • 内置2 Simple analyzer:简单分析器,根据所有非字符进行分词
    • 内置3 Whitespace analyzer:空白文本分析器,把空白字符去了每个都是一个单词
    • 内置4 Languageanalyzer:适用于多种不同语言分析器
    • 注意:在构建创建索引与查询索引必须使用相同分析器,即构建查询要么Standard analyzer,要么Simple analyzer;

Query DSL

内容和知识点太多,不废话直接给出官方站点地址 Query DSL
Elasticsearch提供了一个基于JSON的完整Query DSL来定义查询 (Query dsl,Filter dsl)
Query DSL 在执行full-text查询时,基于相关度来评判其匹配结果,查询执行过程复杂且结果不缓存
Filter DSL 在执行exact查询时,基于其结果为yes或no进行评判。速度快,且结果缓存

  • 合并filter和query
    • 一般可以把filter用于query上进行过滤,很少把query用在filter上,较麻烦;
      {
      "filterd":{
      query: { "match": { "gender": "Female" } }
      filter: { "term": { "age": 25 } }
      }
      }
  • 查询语句语法检查(valid返回true或false)
    GET /INDEX/_validate/query?pretty
    {
    ...
    }
    GET /INDEX/_validate/query?explain&pretty

ES 的另外两个组件(查询接口组件)

L:logstash
(日志收集工具)可实现向产生日志的服务器上部署一个agent收集日志并通过一个统一管道给集中存储在elasticsearch组件中;
K:kibina
(nodejs开发)非常美观的搜索界面,能够把用户搜索的语句发送给elasticsearch由elasticsearch完成搜索并且把结果返回;
es+logstash+kibina同属一个组织elastic


  • Logstash介绍(JRuby研发 JVM)

    • 官方帮助文档站点地址 Doc 文档帮助页
    • 支持索引构建、日志收集:整合型框架支持日志收集、分析、存储,自有索引组件与elasticsearch不是一个量级,只用日志收集;
    • 支持多种数据获取机制:比如通过TCP/UDP协议、文件、syslog、windows Eventlogs及STDIN等,获取到数据后支持对数据过滤修改等操作;
  • Logstash工作模式(agent/server)
    • 在每个产生日志的节点上部署个agent,通常叫运输器;
    • 各运输器负责收集日志并且发送给server端;
    • 在agent及server两者之间部署消息队列来处理多节点的数据发送接收请求(redis、msq),一般叫broker一手托两家;
    • server端负责在队列中每次取出一条数据,在本地做过滤修改并发送给elasticsearch集群再发送给logstash集群;
  • Logstash插件
    • 知识点太多,还是官方直接看比较妥 Input plugins、Output plugins、Filter plugins、Codec plugins
  • Logstash 安装

    input {...},filter {...},output {...},codec {...}
    • 导出环境变量
       vim /etc/profile.d/logstash.sh
       export PATH=/opt/logstash/bin:$PATH
       source /etc/profile.d/logstash.sh
    • 语法检查
        logstash -f /etc/logstash/conf.d/sample.conf --configtest
    • 启动:logstash -f /etc/logstash/conf.d/sample.conf
  • logstash工作流程:input | filter | output,无需对数据进行额外处理,filter可省略;
  • es和logstash知识点太多,一定要多看官方文档

Kibina安装


建议各组件启动方式

  • elasticsearch 使用systemd启动
  • logstash 使用脚本启动 /etc/rc.d/init.d/logstash
  • Kibana 使用&启动在后台运行,日志可/dev/null

猜你喜欢

转载自blog.51cto.com/51eat/2327295
0条评论
添加一条新回复