ElasticSearch已经配置好ik分词和mmseg分词(转)

ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎。设计用于云计算中,可以达到实时搜索,稳定,可靠,快速,安装使用方便。支持经过HTTP使用JSON进行数据索引。 
 
官方站点:http://www.elasticsearch.com/ 
中文站点:http://es-cn.medcl.net/  
 
 1.安装 
 
必须先安装Java环境,并设置 JAVA_HOME => C:\Program Files\Java\jdk1.6.0_18 
 
elasticsearch-rtf 中文入门集成包 https://github.com/medcl/elasticsearch-rtf 
使用git签出,下载到本地。windows下,执行bin下面的elasticsearch.bat。linux下,执行bin下面或者service下面elasticsearch。  
 
 
 2.角色关系对照 
 
elasticsearch 跟 MySQL 中定义资料格式的角色关系对照表以下 
 
MySQL             elasticsearch 
database                 index 
table                         type 
 
table schema mapping 
row                          document 
field                         field  
 
 
 
 选用缘由 
 
    主要缘由有:实时性能优越;安装配置简单;RESTful API 和 JSON 格式的文档型数据,下降开发调试的难度。 另外,Tire 这个 Gem 能够简单方便的与 ActiveRecord 整合。 测试中发现:ES 自带了中文分词,支持中文搜索,可是,能够换用更高效精确的分词插件。
    业界资讯:GitHub searches 20TB of data using Elasticsearch, including 1.3 billion files and 130 billion lines of code. 
 
简单介绍 
 
    ElasticSearch 是开源搜索平台领域的一个新成员。 ElasticSearch(简称 ES) 是一个基于 Lucene 构建的开源,分布式,RESTful 搜索引擎。 设计用于云计算中,可以达到搜索实时、稳定、可靠和快速,而且安装使用方便。 支持经过 HTTP 请求,使用 JSON 进行数据索引。 
 
 
 
 特色优点 
 
    (1)Open Source(开源) 
    (2)Apache Lucene(基于 Lucene) 
    (3)Schema Free(模式自由) 
    (4)Document Oriented(面向文档型的设计) 
    (5)Real Time Data & Analytics(实时索引数据) 
    (6)Distributed(分布式) 
    (7)High Availability(高可靠性) 
    (8)其余特性:RESTful API;JSON format;multi-tenancy;full text search;conflict management;per-operation persistence 
 
 
================================================ 
分布式搜索elasticsearch 中文分词集成 
 
对于索引可能最关系的就是分词了 通常对于es 来讲默认的smartcn  但效果不是很好  
 
一个是ik的,一个是mmseg的,下面分别介绍下二者的用法,其实都差很少的,先安装插件,命令行: 
 
下载ik相关配置词典文件到config目录: 
    cd config 
 
    wget http://github.com/downloads/medcl/elasticsearch-analysis-ik/ik.zip --no-check-certificate 
 
    unzip ik.zip 
 
    rm ik.zip 
 
分词配置 
ik分词配置,在elasticsearch.yml文件中加上 
    index: 
      analysis:                    
        analyzer:       
          ik: 
          alias: [ik_analyzer] 
          type: org.elasticsearch.index.analysis.IkAnalyzerProvider 
或 
    index.analysis.analyzer.ik.type : “ik” 
 
安装mmseg插件: 
    bin/plugin -install medcl/elasticsearch-analysis-mmseg/1.1.0 
下载相关配置词典文件到config目录 
    cd config 
 
    wget http://github.com/downloads/medcl/elasticsearch-analysis-mmseg/mmseg.zip --no-check-certificate 
 
    unzip mmseg.zip 
 
    rm mmseg.zip 
mmseg分词配置,也是在在elasticsearch.yml文件中 
    index: 
      analysis: 
        analyzer: 
          mmseg: 
          alias: [news_analyzer, mmseg_analyzer] 
          type: org.elasticsearch.index.analysis.MMsegAnalyzerProvider 
          
 
mmseg分词还有些更加个性化的参数设置以下 
    index: 
      analysis: 
        tokenizer: 
          mmseg_maxword: 
          type: mmseg 
          seg_type: "max_word" 
          mmseg_complex: 
          type: mmseg 
          seg_type: "complex" 
          mmseg_simple: 
          type: mmseg 
          seg_type: "simple" 
 
这样配置完后插件安装完成,启动es就会加载插件。 
 
定义mapping 
 
在添加索引的mapping时就能够这样定义分词器 
 

   "page":{ 
      "properties":{ 
         "title":{ 
            "type":"string", 
            "indexAnalyzer":"ik", 
            "searchAnalyzer":"ik" 
         }, 
         "content":{ 
            "type":"string", 
            "indexAnalyzer":"ik", 
            "searchAnalyzer":"ik" 
         } 
      } 
   } 

 
 
indexAnalyzer为索引时使用的分词器,searchAnalyzer为搜索时使用的分词器。 
 
java mapping代码以下: 
 
XContentBuilder content = XContentFactory.jsonBuilder().startObject() 
        .startObject("page") 
          .startObject("properties")        
            .startObject("title") 
              .field("type", "string")            
              .field("indexAnalyzer", "ik") 
              .field("searchAnalyzer", "ik") 
            .endObject()  
            .startObject("code") 
              .field("type", "string")          
              .field("indexAnalyzer", "ik") 
              .field("searchAnalyzer", "ik") 
            .endObject()      
          .endObject() 
         .endObject() 
       .endObject() 
 
 
测试分词可用调用下面api,注意indexname为索引名,随便指定一个索引就好了 
 
http://localhost:9200/indexname/_analyze?analyzer=ik&text=测试elasticsearch分词器 
 
附: 
 
ik分词插件项目地址:https://github.com/medcl/elasticsearch-analysis-ik 
 
mmseg分词插件项目地址:https://github.com/medcl/elasticsearch-analysis-mmseg 
 
配置好的es版本,地址以下:https://github.com/medcl/elasticsearch-rtf 
 
================================================ 
 
cluster 
 
  表明一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是能够经过选举产生的,主从节点是对于集群内部来讲的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来讲的,由于从外部来看es集群,在逻辑上是个总体,你与任何一个节点的通讯和与整个es集群通讯是等价的。 
 
 
shards 
 
  表明索引分片,es能够把一个完整的索引分红多个分片,这样的好处是能够把一个大的索引拆分红多个,分布到不一样的节点上。构成分布式搜索。分片的数量只能在索引建立前指定,而且索引建立后不能更改。 
 
 
replicas 
 
  表明索引副本,es能够设置多个索引的副本,副本的做用一是提升系统的容错性,当个某个节点某个分片损坏或丢失时能够从副本中恢复。二是提升es的查询效率,es会自动对搜索请求进行负载均衡。 
 
 
recovery 
 
  表明数据恢复或叫数据从新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行从新分配,挂掉的节点从新启动时也会进行数据恢复。 
 
 
river 
 
  表明es的一个数据源,也是其它存储方式(如:数据库)同步数据到es的一个方法。它是以插件方式存在的一个es服务,经过读取river中的数据并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia的。 
 
 
gateway 
 
  表明es索引快照的存储方式,es默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘。gateway对索引快照进行存储,当这个es集群关闭再从新启动时就会从gateway中读取索引备份数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和amazon的s3云存储服务。 
 
 
discovery.zen 
 
  表明es的自动发现节点机制,es是一个基于p2p的系统,它先经过广播寻找存在的节点,再经过多播协议来进行节点之间的通讯,同时也支持点对点的交互。 
 
 
Transport 
 
  表明es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(经过插件方式集成)。 
 
------------------------------------------------ 
 
云计算平台(检索篇)-Elasticsearch-配置篇 
 
ElasticSearch安装好后咱们须要对ElasticSearch的Config进行一系列配置,具体以下: 
 
  
 
cluster.name: rmscloud 
 
集群名称 
 
  
 
node.name: "rcnode21" 
 
节点名称 
 
  
 
node.tag: "tag21" 
 
节点标签 
 
  
 
node.data: true 
 
节点是否存储数据 
 
  
 
index.number_of_shards: 5 
 
索引分片数 
 
  
 
index.number_of_replicas: 1 
 
索引副本数 
 
  
 
path.data: /data/elasticsearch/data 
 
数据目录存放位置 
 
  
 
path.logs: /data/elasticsearch/log 
 
日志数据存放位置 
 
bootstrap.mlockall: true 
 
内存 
 
  
 
index.cache.field.max_size: 500000 
 
索引缓存 
 
  
 
index.cache.field.expire: 5m 
 
索引缓引过时时间 
 
  
 
其它配置基本上不用调,具体可参考附录。另外须要的调配置是分词具体例子以下: 
 
index: 
 
  analysis: 
 
    tokenizer: 
 
      my_pinyin: 
 
          type: pinyin 
 
          first_letter: "prefix" 
 
          padding_char: "" 
 
      pinyin_first_letter: 
 
          type: pinyin 
 
          first_letter: "only" 
 
      mmseg_maxword: 
 
          type: mmseg 
 
          seg_type: "max_word" 
 
      mmseg_complex: 
 
          type: mmseg 
 
          seg_type: "complex" 
 
      mmseg_simple: 
 
          type: mmseg 
 
          seg_type: "simple" 
 
      semicolon_spliter: 
 
          type: pattern 
 
          pattern: ";" 
 
      pct_spliter: 
 
          type: "pattern" 
 
          pattern: "[%]+" 
 
  
 
    filter: 
 
      ngram_min_2: 
 
          max_gram: 10 
 
          min_gram: 2 
 
          type: nGram 
 
      ngram_min_1: 
 
          max_gram: 10 
 
          min_gram: 1 
 
          type: nGram 
 
      min2_length: 
 
          min:  2 
 
          max:  4 
 
          type: length 
 
  
 
    analyzer: 
 
      lowercase_keyword: 
 
          type: custom 
 
          filter: [standard,lowercase] 
 
          tokenizer: standard 
 
      lowercase_keyword_ngram_min_size1: 
 
          type: custom 
 
          filter: [ngram_min_1,standard,lowercase] 
 
          tokenizer: nGram 
 
      lowercase_keyword_ngram_min_size2: 
 
          type: custom 
 
          filter: [ngram_min_2,standard,lowercase,min2_length,stop] 
 
          tokenizer: nGram 
 
      lowercase_keyword_ngram: 
 
          type: custom 
 
          filter: [ngram_min_1,standard,lowercase] 
 
          tokenizer: nGram 
 
      lowercase_keyword_without_standard: 
 
          type: custom 
 
          filter: [lowercase] 
 
          tokenizer: keyword 
 
      lowercase_whitespace: 
 
          type: custom 
 
          filter: [lowercase] 
 
          tokenizer: whitespace 
 
      ik: 
 
          alias: [ik_analyzer] 
 
          type: org.elasticsearch.index.analysis.IkAnalyzerProvider 
 
      ike: 
 
          alias: [ike_analyzer] 
 
          type: org.elastichsearch.ik.index.IkAnalyzerProvider 
 
          usermode: true 
 
      mmseg: 
 
          alias: [mmseg_analyzer] 
 
          type: org.elasticsearch.index.analysis.MMsegAnalyzerProvider 
 
      comma_spliter: 
 
          type: "pattern" 
 
          pattern: "[,|\\s]+" 
 
      pct_spliter: 
 
          type: "pattern" 
 
          pattern: "[%]+" 
 
      custom_snowball_analyzer: 
 
          type: "snowball" 
 
          language: "English" 
 
      simple_english_analyzer: 
 
          type: "custome" 
 
          tokenizer: whitespace 
 
          filter: [standard,lowercase,snowball] 
 
      edge_ngram: 
 
          type: custom 
 
          tokenizer: edgeNGram 
 
          filter: [lowercase] 
 
      pinyin_ngram_analyzer: 
 
          type: custom 
 
          tokenizer: my_pinyin 
 
          filter: [standard,lowercase,nGram] 
 
      pinyin_first_letter_analyzer: 
 
          type: custom 
 
          tokenizer: pinyin_first_letter 
 
          filter: [standard,lowercase] 
 
      custom_auth_en_analyzer: 
 
          type: custom 
 
          tokenizer: semicolon_spliter 
 
          filter: [standard,snowball,lowercase,trim] 
 
  
 
index.analysis.analyzer.default.type : "keyword" 
 
  
 
  
 
进行完Config的配置后还须要对bin目录下面的elastichsearch进行配置,此处主要是控制JVM的一些参数 
 
ES_MIN_MEM=27G 
 
ES_MAX_MEM=27G 
 
调整JVM的最大内存和最小内存就能够了,其它JVM参数见附录。 
 
 
------------------------------------------------ 
 
云计算平台(检索篇)-Elasticsearch-Linux优化篇 
 
 Elasticsearch在Linux系统环境中运行,须要对Linux系统进行一系列调优,这样能够提升ElasticSearch的检索效率。主要的须要调优的参数以下: 
 
  
 
    1.       Linux调整文件数 
 
/etc/security/limits.conf 
 
在文件中增长 
 
* soft nofile 8192 
 
* hard nofile 20480 
 
* - memlock unlimited 
 
  
 
在登录中添加下面命令行 
 
/etc/pam.d/login 
 
session  required  /lib64/security/pam_limits.so(在不一样系统中文件位置不一样) 
 
  
 
    2.       关闭文件的更新时间 
 
/etc/fstab 
 
在文件中添加一行 
 
/dev/sda7               /data/elasticsearch     ext4    noatime,nodiratime 0 0 
 
(此处的/dev/sda7 能够经过df –h查看目录所在分区) 
 
    3.       修改防火墙设置 
 
为方便调适暂时关闭 
 
/etc/init.d/iptables stop 
 
 
 
------------------------------------------------ 
云计算平台(检索篇)-Elasticsearch-索引篇 
 
Es索引的咱们能够理解为数据入库的一个过程。咱们知道Es是基于Lucene框架的一个分布式检索平台。索引的一样也是基于Lucene建立的,只不过在其上层作了一些封闭。 
 
         Es的索引过程比较通用的大致上有两种方式,其一是得用自身Rvier从数据库中拉数据,固然如今已经有了不少相关插件,Mysql、MDB等数据库。这种方式能够作到近时实索引,由于River是定时从数据库拉数据与索引数据进行比对。这种方式经较适合数据有周期的更新。 
 
         下面以Mysql-River  plugins为例: 
 
一、    安装Mysql-River 插件 
 
bin/plugin -install /path/to/plugin/river-mysql.zip 
 
二、    当安装好Mysql-River plugin 后,通常能够立刻使用,但创建从新加载Es集群。查看log中是否正确的加载了Mysql-River Plugin(在后面咱们讲到如何开发相关Plugin)。 
 
三、    配置Es索引与Mysql 数据之间的对应关系。 
 
创建索引(相关Mapping 信息以下:) 
 
curl -XPUT 127.0.0.1:9200/elasticsearchindexname/elasticsearchtypename/_mapping -d 
 
"elasticsearchtypename" : { 
 
                   "_timestamp":{ 
 
                            "enabled":true 
 
                   } 
 

 
                   将River索引的配置也提交到Es集群中: 
 
                   curl -XPUT 127.0.0.1:9200/_river/river-mysql/_meta –d 
 
                   { 
 
             "type":"mysql", 
 
                "mysql":{ 
 
        "index":"elasticsearchindexname",(索引名称) 
 
        "type":"elasticsearchtypename",(类型) 
 
        "hostname":"127.0.0.1:3306",(服务器) 
 
        "database":"ESDATA",(数据库名称) 
 
        "username":"root",(用户名) 
 
        "password":"",(密码) 
 
        "uniqueIdField":"_ID",(标识) 
 
        "query":"select RID,PNAME FROM wf_mds_chn_biaozhun",(SQL语句) 
 
        "deleteOldEntries":"false", 
 
        "interval":"60000"(更新周期) 
 
    } 
 

 
同时你会在Es看到你的索引中开始导数据了,固然些时也会出现一个对应的保存配置的索引,如今不少River都只能索引字段与数据库的字段一一对应。若是须要个性化定制,能够到Github上下载相关代码进行修改。咱们能够看到只要继续River(接口)和AbstractRiverComponent(类)即可以进行相关开发了。 
 
public class MysqlRiver extends AbstractRiverComponent implements River 
 
  
 
         另一种索引方式固然就是咱们把数据Put到Es中去了,最简单的咱们能够用下面命令就完成: 
 
$ curl -XPUT 'http://localhost:9200/twitter/tweet/1' -d '{ 
 
    "user" : "kimchy", 
 
    "post_date" : "2009-11-15T14:12:12", 
 
    "message" : "trying out Elastic Search" 
 
}' 
 
对上面的命令解释一下: 
 
Twitter:索引名称 
 
Tweet:类型名称 
 
1:ID值 
 
具体我会在下篇中讲解索引名称和类型的关系,固然-d 后面的就是值了。这是单条Put数据的方式虽然简单,可是若是说数据量很大的状况下仍是不建议用这种方式,能够改用批量导入的方式也就是传说中的Bluk了,Bluk原量很简单,咱们把数据放到缓存中,一次Put多条数据到Es集群中去,Bluk固然要用代码实现了,给出一个例子以下: 
 
public static void Index() throws ElasticSearchException, IOException, NumberFormatException, SQLException { 
 
                   // TODO Auto-generated method stub 
 
                   // Node node = nodeBuilder().client(true).node(); 
 
                   Settings settings = ImmutableSettings.settingsBuilder() 
 
                                     .put("cluster.name", "elasticsearch_wf").build(); 
 
                   Client client = new TransportClient(settings) 
 
                                     .addTransportAddress(new InetSocketTransportAddress( 
 
                                                        "168.160.200.250", 9300)); 
 
                   
 
                   ////������е��ܼ�¼��ֳ�5000��һ�����ѯ 
 
                   int countRe=100000000; //MySqlClass.getCount("select count(*) from test"); 
 
                   if(countRe>0) 
 
                   { 
 
                            int readercount=1; 
 
                            if(countRe>5000) 
 
                            { 
 
                                     readercount=countRe%5000==0?countRe/5000:countRe/5000+1; 
 
                            } 
 
                            
 
                            ////ÿ�ζ�ȡ5000���¼ 
 
                            for(int j=0;j<readercount;j++) 
 
                            { 
 
                                     ResultSet rs = MySqlClass.executeQuery("select * from test"); 
 
                                     BulkRequestBuilder bulkRequest = client.prepareBulk(); 
 
                                     try { 
 
  
 
                                               if (rs != null) { 
 
                                                        int i = 1; 
 
                                                        while (rs.next()) { 
 
                                                                 bulkRequest.add(client.prepareIndex("qtest", String.valueOf(i++)).setSource( 
 
                                                                                    jsonBuilder().startObject() 
 
                                                                                                       .field("id", rs.getInt("id")) 
 
                                                                                                       .field("�й�", rs.getString("title")) 
 
                                                                                                       .field("AB_EN", rs.getString("descript")) 
 
                                                                                                       .field("AF_CN",rs.getString("text")) 
 
                                                                                                       .endObject())); 
 
                                                        } 
 
                                                        BulkResponse bulkResponse = bulkRequest.execute().actionGet(); 
 
                                                        if (bulkResponse.hasFailures()) { 
 
                                                                 /* has Failures handler Error */ 
 
                                                        } 
 
                                               } 
 
                                     } catch (Exception e) { 
 
                                               e.printStackTrace(); 
 
                                     } 
 
                            } 
 
                   } 
 
                   client.close(); 
 
         } 
 
上面只是一个简单的例子,大量能够考虑用从线程方式,另外Client连接数其实仍是比较占资源的,你们能够考虑将出封闭到一个连接池中,提供效率。 
 
         整个建索引的过程Es在Lucene的基础上仍是作了不少的优化,但主体上咱们对应到Lucene里面基实就是以下代码: 
 
         public class Index { 
 
         private IndexWriter writer = null; 
 
         private static Analyzer ANALYZER = new IKAnalyzer(); 
 
         private String FilePath = null; 
 
  
 
         public Index(String FilePath, String IndexPath) { 
 
                   try { 
 
                            IndexWriterConfig writerConfig = new IndexWriterConfig( 
 
                                               Version.LUCENE_36, ANALYZER); 
 
                            this.writer = new IndexWriter( 
 
                                               FSDirectory.open(new File(IndexPath)), writerConfig); 
 
                            this.FilePath = FilePath; 
 
                   } catch (Exception e) { 
 
                            e.printStackTrace(); 
 
                   } 
 
         } 
 
  
 
         /* 
 
          * Init Create Index 
 
          */ 
 
         public void Init() { 
 
                   try { 
 
                            if (FilePath.length() > 0) { 
 
                                     // 读目录中txt文件 
 
                                     File file = new File(FilePath); 
 
                                     List<File> files = new ArrayList<File>(); 
 
                                     this.ListAllFile(file, files); 
 
  
 
                                     // //将File转换为 Document对象 
 
                                     for (File sfs : files) { 
 
                                               this.writer.addDocument(this.getDocument(sfs)); 
 
                                     } 
 
                            } 
 
                   } catch (Exception e) { 
 
                            e.printStackTrace(); 
 
                   } 
 
         } 
 
  
 
         /* 
 
          * Close Index 
 
          */ 
 
         public void Close() { 
 
                   try { 
 
                            this.writer.commit(); 
 
                            this.writer.close(); 
 
                   } catch (Exception e) { 
 
                            e.printStackTrace(); 
 
                   } 
 
         } 
 
  
 
         /* 
 
          * 获取全部txt文件 
 
          */ 
 
         private List<File> ListAllFile(File fileOrDir, List<File> files) 
 
                            throws Exception { 
 
                   if (fileOrDir != null && files != null) { 
 
                            if (fileOrDir.isDirectory()) { 
 
                                     File[] fs = fileOrDir.listFiles(); 
 
                                     for (File sfs : fs) { 
 
                                               if (sfs.isDirectory()) 
 
                                                        this.ListAllFile(sfs, files); 
 
                                               else files.add(sfs); 
 
                                     } 
 
                            } else { 
 
                                     files.add(fileOrDir); 
 
                            } 
 
                   } 
 
                   return null; 
 
         } 
 
  
 
         /* 
 
          * Get Document 
 
          */ 
 
         private Document getDocument(File f) throws Exception { 
 
                   Document doc = new Document(); 
 
                   FileInputStream  is = new FileInputStream(f); 
 
                   byte[] buf = new byte[is.available()]; 
 
                   is.read(buf); 
 
                   String contentStr = new String(buf,"GBK"); 
 
                   Field content = new Field("content", contentStr, Field.Store.YES, 
 
                                     Field.Index.ANALYZED); 
 
                   doc.add(content); 
 
                   Field path = new Field("path", f.getAbsolutePath(), Field.Store.YES, 
 
                                     Field.Index.ANALYZED); 
 
                   Field size=new Field("size",String.valueOf(f.getTotalSpace()),Field.Store.YES,Field.Index.NOT_ANALYZED); 
 
                   doc.add(size); 
 
                   Random rm=new Random(); 
 
                   int year=rm.nextInt(20); 
 
                   Field time=new Field("time",String.valueOf(1990+year),Field.Store.YES,Field.Index.NOT_ANALYZED); 
 
                  doc.add(time); 
 
                   doc.add(path); 
 
                   is.close(); 
 
                   return doc; 
 
         } 
 

 
------------------------------------------------ 
云计算平台(检索篇)-Elasticsearch-Mapping篇 
 
         Es Mapping篇主要是讲解Mapping的一些相关配置与须要注意的地方,说到Mapping你们可能以为有些不解,其实我大致上能够将Es 理解为一个数据管理平台,那么index 固然就是库了,type能够理解为表,mapping能够理解为表的结构和相关设置的信息(固然mapping有更大范围的意思)。Mapping的做用域也是从cluster、node、index、type。 
 
curl -XPOST localhost:9200/wf_mds_org(索引名称) -d '{ 
 
    "settings": { 
 
        "number_of_shards": 1, 
 
        "number_of_replicas": 0, 
 
        "index.refresh_interval": "-1", 
 
        "index.translog.flush_threshold_ops": "100000" 
 
    }, 
 
    "mappings": { 
 
        "org": {   //(类型) 
 
            "_all": { 
 
                "analyzer": "ike" 
 
            }, 
 
            "_source": { 
 
                "compress": true 
 
            }, 
 
            "properties": { 
 
                "_ID": { 
 
                    "type": "string", 
 
                    "include_in_all": true, 
 
                    "analyzer": "keyword" 
 
                }, 
 
                                     "NAME": { 
 
                    "type": "multi_field", 
 
                    "fields": { 
 
                        "NAME": { 
 
                            "type": "string", 
 
                            "analyzer": "keyword" 
 
                        }, 
 
                        "IKO": { 
 
                            "type": "string", 
 
                            "analyzer": "ike" 
 
                        } 
 
                    } 
 
                }, 
 
                                     "SHORTNAME": { 
 
                    "type": "string", 
 
                    "index_analyzer": "pct_spliter", 
 
                    "search_analyzer": "keyword", 
 
                    "store": "no" 
 
                }, 
 
                                     "OLDNAME": { 
 
                    "type": "multi_field", 
 
                    "fields": { 
 
                        "OLDNAME": { 
 
                            "type": "string", 
 
                            "analyzer": "keyword" 
 
                        }, 
 
                        "IKO": { 
 
                            "type": "string", 
 
                            "analyzer": "ike" 
 
                        } 
 
                    } 
 
                }, 
 
                                     "TNAME": { 
 
                    "type": "string", 
 
                    "analyzer":"custom_snowball_analyzer", 
 
                    "store": "no" 
 
                }, 
 
                                     "TSNAME": { 
 
                    "type": "string", 
 
                    "index": "no", 
 
                    "store": "no" 
 
                }, 
 
                                     "TONAME": { 
 
                    "type": "string", 
 
                    "index": "no", 
 
                    "store": "no" 
 
                } 
 
            } 
 
        } 
 
    } 
 
}' 
 
上面给出了一个完整Mapping,咱们可将Mapping信息大体分红settings和mappings两个部分,settings主要是做用于index的一些相关配置信息,如分片数、副本数等(分片和副本在es简介中讲过,更加详细的东西会在索引优化篇中讲)、tranlog同步条件、refresh条条等。Mappings部分主是要结果构的一些说明,mappings 咱们能够看到主体上大体又分红_all、_source、properites这三个部分。 
 
一、_all:主要指的是All Field字段,咱们能够将一个或都多个包含进不,在进行检索时无需指定字段的状况下检索多个字段。前提是你得开启All Field字段 
 
"_all" : {"enabled" : true} 
 
二、_source:主要指的是Source Field字段Source能够理解为Es除了将数据保存在索引文件中,另外还有一分源数据。_source字段我在们进行检索时至关重要,若是在{"enabled" : false}状况下默认检索只会返回ID,你需经过Fields字段去倒索索引中去取数据,固然效率不是很高。若是以为enabale:true时,索引的膨涨率比较大的状况下能够经过下面一些辅助设置进行优化: 
 
Compress:是否进行压缩,建议通常状况下将其设为true 
 
"includes" : ["author", "name"], 
 
"excludes" : ["sex"] 
 
上面的includes和 excludes主要是针对默认状况下面_source通常是保存所有Bulk过去的数据,咱们能够经过include,excludes在字段级别上作出一些限索。 
 
三、properites部分是最重要的部分主要是针对索引结构和字段级别上面的一些设置 
 
"NAME": { //字段项名称对应lucene里面FiledName 
 
        "type": "string",//type为字段项类型 
 
        "analyzer": "keyword"//字段项分词的设置对应Lucene里面的Analyzer 
 
        }, 
 
在Es中字段项的 type是一个很重要的概念,在Es中在Lucene的基础上提供了比较多的类型,而这些类型对应这一些相关的检索特性如 Date型 我可使用 [2001 TO 2012]的方式进行范围检索等,Es 的类型有以下一些: 
 
简单类型: 
 
String:字符型最经常使用的 
 
Integer:整型 
 
Long:长整型 
 
Float:浮点型 
 
Double:双字节型 
 
Boolean:布尔型 
 
复杂类型: 
 
Array:数组型 
 
“lists”:{{“name”:”…”},{“name”:”…”}} 
 
Object:对象类型 
 
“author”:{“type”:”object”,”perperites”:{“name”:{“type”:”string”}}} 
 
说到Array和Object有一个性能上的问题,Es中提供了Facet检索,据Es的做者提供的消息,在作Facet时object类型相比与array的内存要占用的少,但我本人通过测试效果不是很明显有兴趣的能够测试一下。 
 
Multi_field:多分词字段,针对一个字段提供多种分词方式 
 
Nested: 嵌入类型用的仍是比较多的 
 
         类型经常使用的也就这些了,还有一些类型你们能够参考官网,另一个比较重的方面的就是分词了(analyzer),无论在目前任何检索系统是分词决定这检索的查全与查准及索引的膨涨率等。在Es中analyzer的做用域也是从cluster、index、filed这三个做用域。Cluster的配置在配置中讲过,下面以Field为主(另外具体的分词一些相关东西会在分词篇中讲) 
 
Analyzer,在Lucene中是一个分词器的概念,咱们知道Es是创建在Lucene之上的,因此这里的Analzyer一样的也适用,Mapping 中的Analyzer主在是指定字段采用什么分词器,具体的程序和配置分词在插件和配置都有过一些说明。 
 
Analyzer在Es中分为index_analyzer和search_analyzer 
 
Index_analzyer:指的是索引过程当中采用的分词器 
 
Search_analyzer:指的是检索过程当中采用的分词器 
 
咱们知道index和search是两个过程,可是尽可能保证这两个过程和分词方式一致这样能够保证查全和查准,不然再牛B的分词,index和search采用的不相同也是无用功。 
 
         与analyzer与之相关的就是别外一项index项 
 
"HC":{ "type":"string", "index":"no", "store":"no"} 
 
         Index表示该字段是否索引,若是index为no那个analyzer设为啥也没用。 
 
最后是”store”项了store项表示该项是否存储到倒索索引中去,并非_source,当项mapping中还有不少能够设置和优化的地方,会面在慢慢讨论。在mapping中index和store若是你们有时候以为有点和source搞不清楚,你们能够参考lucene中的Field.Store.YES,Field.Index.NOT_ANALYZED,Field.Index等相关设置就比较明白了。 
 
----------------------------------------------- 
云计算平台(检索篇)-Elasticsearch-索引优化篇 
 
         ES索引优化篇主要从两个方面解决问题,一是索引数据过程;二是检索过程。 
 
索引数据过程我在上面几篇文章中有提到怎么建立索引和导入数据,可是你们可能会遇到索引数据比较慢的过程。其实明白索引的原理就能够有针对性的进行优化。ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用tranlog进行各节点之间的数据平衡。因此从上我能够经过索引的settings进行第一优化: 
 
         "index.translog.flush_threshold_ops": "100000" 
 
         "index.refresh_interval": "-1", 
 
         这两个参数第一是到tranlog数据达到多少条进行平衡,默认为5000,而这个过程相对而言是比较浪费时间和资源的。因此咱们能够将这个值调大一些仍是设为-1关闭,进而手动进行tranlog平衡。第二参数是刷新频率,默认为120s是指索引在生命周期内定时刷新,一但有数据进来能refresh像lucene里面commit,咱们知道当数据addDoucment会,还不能检索到要commit以后才能行数据的检索因此能够将其关闭,在最初索引完后手动refresh一之,而后将索引setting里面的index.refresh_interval参数按需求进行修改,从而能够提升索引过程效率。 
 
         另外的知道ES索引过程当中若是有副本存在,数据也会立刻同步到副本中去。我我的建议在索引过程当中将副本数设为0,待索引完成后将副本数按需量改回来,这样也能够提升索引效率。 
 
         "number_of_replicas": 0 
 
         上面聊了一次索引过程的优化以后,咱们再来聊一下检索速度比较慢的问题,其实检索速度快度与索引质量有很大的关系。而索引质量的好坏与不少因素有关。 
 
1、分片数 
 
分片数,与检索速度很是相关的的指标,若是分片数过少或过多都会致使检索比较慢。分片数过多会致使检索时打开比较多的文件别外也会致使多台服务器之间通信。而分片数过少为导至单个分片索引过大,因此检索速度慢。 
 
在肯定分片数以前须要进行单服务单索引单分片的测试。好比我以前在IBM-3650的机器上,建立一个索引,该索引只有一个分片,分别在不一样数据量的状况下进行检索速度测试。最后测出单个分片的内容为20G。 
 
因此索引分片数=数据总量/单分片数 
 
目前,咱们数据量为4亿多条,索引大小为近1.5T左右。由于是文档数据因此单数据都中8K之前。如今检索速度保证在100ms 如下。特别状况在500ms如下,作200,400,800,1000,1000+用户长时间并发测试时最坏在750ms如下. 
 
2、副本数 
 
副本数与索引的稳定性有比较大的关系,怎么说,若是ES在非正常挂了,常常会致使分片丢失,为了保证这些数据的完整性,能够经过副原本解决这个问题。建议在建完索引后在执行Optimize后,立刻将副本数调整过来。 
 
你们常常有一个误去副本越多,检索越快,这是不对的,副本对于检索速度其它是减无增的我曾作过实现,随副本数的增长检索速度会有微量的降低,因此你们在设置副本数时,须要找一个平衡值。另外设置副本后,你们有可能会出现两次相同检索,出现出现不一样值的状况,这里多是因为tranlog没有平衡、或是分片路由的问题,能够经过?preference=_primary 让检索在主片分上进行。 
 
3、分词 
 
其实分词对于索引的影响可大可小,看本身把握。你们越许认为词库的越多,分词效果越好,索引质量越好,其实否则。分词有不少算法,大部分基于词表进行分词。也就是说词表的大小决定索引大小。因此分词与索引膨涨率有直接连接。词表不该不少,而对文档相关特征性较强的便可。好比论文的数据进行建索引,分词的词表与论文的特征越类似,词表数量越小,在保证查全查准的状况下,索引的大小能够减小不少。索引大小减小了,那么检索速度也就提升了。 
 
4、索引段 
 
索引段即lucene中的segments概念,咱们知道ES索引过程当中会refresh和tranlog也就是说咱们在索引过程当中segments number不至一个。而segments number与检索是有直接联系的,segments number越多检索越慢,而将segments numbers 有可能的状况下保证为1这将能够提到将近一半的检索速度。 
 
$ curl -XPOST 'http://localhost:9200/twitter/_optimize? max_num_segments =1' 
 
5、删除文档 
 
删除文档在Lucene中删除文档,数据不会立刻进行硬盘上除去,而进在lucene索引中产生一个.del的文件,而在检索过程当中这部分数据也会参与检索,lucene在检索过程会判断是否删除了,若是删除了在过滤掉。这样也会下降检索效率。因此能够执行清除删除文档。 
 
$ curl -XPOST 'http://localhost:9200/twitter/_optimize? only_expunge_deletes =true' 
 
----------------------------------------------- 
ES JVM 设置 
 
JVM参数 
     
 
ES默认值 
     
 
环境变量名 
 
-Xms 
     
 
256m 
     
 
  
 
-Xmx 
     
 
1g 
     
 
  
 
-Xms   and –Xmx 
     
 
  
     
 
  
 
-Xmn 
     
 
  
     
 
  
 
-XX:MaxDirectMemorySize 
     
 
  
     
 
  
 
-Xss 
     
 
256k 
     
 
  
 
-XX:UseParNewGC 
     
 

     
 
  
 
-XX:UseConcMarkSweepGC 
     
 

     
 
  
              
    
 
-XX:CMSInitiatingOccupancyFraction 
           
 
75 
    
 
  
     
 
75 
     
 
  
 
-XX:UseCMSInitiatingOccupancyOnly 
     
 
  
     
 
  
 
-XX:UseCondCardMark 
     
 
  
     
 
  咱们能够注意到ES JVM Heap内存设置为在256M在1GB之间. 
 
         这个设置是为在开发和示范环境中使用的,开发人员能够经过简单地安装ES就可使用了,可是这样的内存设置在不少状况下都是不够用的,我在须要设置更大的值。 
 
 
 
ES_MIN_MEM/ES_MAX_MEM 用于控制jvm的堆内存,另外还有ES_HEAP_SEIZ,这样我能够设置更多的堆内存用于ES,另外建议不在启动内存堆平衡,由于这样会浪费很大的性能。 
 
 ES_HEAP_NEWSIZE这个参数用于控制堆内存的子集,即新生代堆控制 
 
 ES_DIRECT_SIZE,咱们能够对应到Direct Memory Size这个参数,在JVM管理数据中使用的是NIO,本机内存能够映射到虚拟地址空间,在X64的架构上更有效,在ES中没有选择进行设置,可是有一个问题,本机直接内存的分配不会受到Java堆大小的限制,可是即然是内存那确定仍是要受到本机物理内存(包括SWAP区或者Windows虚拟内存)的限制的,通常服务器管理员配置JVM参数时,会根据实际内存设置-Xmx等参数信息,但常常忽略掉直接内存,使得各个内存区域总和大于物理内存限制(包括物理的和操做系统级的限制),而致使动态扩展时出现OutOfMemoryError异常。 
 
 
 下面例出一些JVM参数设置 
 
JVM parameter    Garbage collector 
 
-XX:+UseSerialGC    serial collector 
 
-XX:+UseParallelGC    parallel collector 
 
-XX:+UseParallelOldGC    Parallel compacting collector 
 
-XX:+UseConcMarkSweepGC    Concurrent-Mark-Sweep ( CMS ) collector 
 
-XX:+UseG1GC         Garbage-First    collector (G1) 
 
 
UseParNewGC和UseConcMarkSweepGC是结并并行和行发性的垃圾回收机制,在JAVA6中将默认为UserParNewGC和UseGoncMarkSweepGC并禁用串行收集器. 
 
UseCondCardMark  将在在高度并发的状况下,将些值注释掉 
 
总结: 
 
       一、修改MAX 和MIN Heap大小设置。 
 
         二、设置垃圾回收百分比 
 
         三、若是在JAVA7中禁用默认的G1垃圾回收机制。 
 
 
JVM内存分为以下几段: 
 
         JVM CODE用于内部代码存放 
 
         Noe-heap memory用于加载类 
 
         Stack memory 用于存放本地变量和线程操做数 
 
         Heap memory 存放引用类型对象 
 
         Direct Buffer,缓冲输入,输出数据    
 
         Heap memory大小设置是很是重要的,由于java的运行取决于一个合理的heap的大小,若是设置过小,在许多垃圾回收或是高性能的状况下就会出现OutOfMemory异常。若是堆太大,垃圾回收将须要更大的数据,该算法将要面对更高数量的存活堆,这样操做系统也会面对较大的压力。 
 
         Non-heap内存分配是由java应用程序自动设置的,没有办法控制这个参数,由于它是由JAVA应用程序代码决定的。 
 
 
垃圾回收与Lucene段 
 
        在ES中的垃圾回收器是集用的CMS垃圾回收,这种回收器不是提升敢回收的效率但是下降了回收的次数,可是面对比较大的数据集合时,这种回收可能须要的时间更长。 
 
         而这种大的数据集合主要是在Lucene的索引中,因些能够将索引的段进行一行调优工做,提升GC的效率。 
 
index.merge.policy.segments_per_tier 
 
 
减小分页 
 
         在大堆内存的状况下,若是内存不足时会与操做系统的SWAP空间进行分页数据的交换,可是这种交换是很是慢的,这种会下降总体性能。 
 
垃圾回收器的选择 
 
JAVA 7中的默认是G1垃圾回收器,这种回收器和CMS回收相对,他在于处理吞吐量,可是若是在大堆的状况下CMS回收器在性能上将超过G1. 
 
性能调优策略 
 
一、  收集日志 
 
二、  对日志进行分析 
 
三、  选择你要优化的目标 
 
四、  计划优化 
 
五、  应用新有设置 
 
六、  监控程序在新设置后的运行状况 
 
七、  反复试尝 
 
ES 垃圾回收日志格式 
 
将日志等级调用警告在垃圾回收时你能看到以下信息: 
 
 
LogFile 
     
 
说明 
 
Gc 
     
 
垃圾回收运行 
 
ParNew 
     
 
新生代垃圾回收器 
 
duration 2.6m 
     
 
垃圾回收花费时间 
 
collections [1]/[2.7m] 
     
 
一个收集器运行花费2.7M 
 
memory [2.4gb] 
     
 
预设2.4GB 
 
[2.3gb]/[3.8gb] 
     
 
如今使用2.3GB/总共3.8GB 
 
Code Cache [13.7mb]->[13.7mb]/[48mb] 
     
 
代码缓存 
 
Par Eden Space [109.6mb]->[15.4mb]/[1gb] 
     
 
Par   Eden Space使用空间 
 
Par Survivor Space[136.5mb]->[0b]/[136.5mb] 
     
 
Par   Survivor Space 
 
CMS Old Gen [2.1gb]->[2.3gb]/[2.6gb] 
     
 
CMS Old Gen 
 
CMS Perm Gen [35.1mb]->[34.9mb]/[82mb] 
     
 
CMS Perm Gen 
 
  
 
建议: 
 
一、ES不要运行在6U22以前因之多版本的JDK存在许多的bug,尽可能使用Sun/Oracle比较最出的JDK6-7由于里面修复不少bug. 
 
         若是在JAVA7正式发布的状况下最好使用JDK7(不过要到2013了) 
 
二、考虑到ES是一个比较新的软件,利用最早的技术来获取性能,尽可能从JVM中来挤压性能,另外检索您的操做系统是不是最新版的,尽可能使用最新版的操做系统。 
 
三、作好随时更新JAVA版本和ES的版本的状况,由于每季度或是每一年都会有新的版本出来。因此在作好版本更新的准备 
 
四、测试从小到大,由于ES的强在多个节点的部署,一个节点是不足以测试出其性能,一个生产系统至少在三个节点以上。 
 
五、测试JVM 
 
六、若是索引有更新请记住对索引段的操做(index.merge.policy.segments_per_tier) 
 
七、在性能调优以前,请先肯定系统的最大性能和最大吞吐量 
 
八、启用日志记录对JAVA垃圾回怍机制,有助于更好的诊断,以致于来调整你的系统 
 
九、提升CMS垃圾收集器,您能够添加一个合理的- xx:CMSWaitDuration参数 
 
十、若是堆大小趣过6-8GB,请选择使用CMS 
 
 
 
 
 
----------------------------------------------- 
ElasticSearch教程(3)——ElasticSearch的插件 
更多 0 
插件 ElasticSearch 教程 
 
插件做为一种广泛使用的,用来加强原系统核心功能的机制,获得了普遍的使用,elasticsearch也不例外。 
1. 安装elasticsearch插件 
 
从0.90.2安装其实很简单,有三种方式, 
 
1.1 在确保你网络顺畅的状况下,执行以下格式的命令便可: 
 
plugin --install <org>/<user/component>/<version> 
 
 具体的<org>/<user/component>/<version>可参加各插件的使用说明。 
 
1.2  若是网络不太顺畅,能够下载好插件的压缩包后以以下方式安装: 
 
bin/plugin --url file://path/to/plugin --install plugin-name 
 
1.3 你也能够直接将插件的相关文件拷贝到plugins目录下面,须要注意的是,这种方式须要特别留意插件的种类。 
2. 如何查看当前已经加载的插件 
 
curl -XGET 'http://localhost:9200/_nodes/plugin' 
 
 或者能够指定某个实例 
 
curl -XGET 'http://localhost:9200/_nodes/10.0.0.1/plugin' 
 
3. 我的强力推荐的插件 
 
要想知道整个插件的列表,请访问http://www.elasticsearch.org/guide/reference/modules/plugins/ 插件仍是不少的,我的认为比较值得关注的有如下几个,其余的看你需求,好比你要导入数据固然就得关注river了。 
 
3.1 BigDesk 
 
该插件能够查看集群的jvm信息,磁盘IO,索引建立删除信息等,适合查找系统瓶颈,监控集群状态等,能够执行以下命令进行安装,或者访问项目地址:https://github.com/lukas-vlcek/bigdesk 
 
bin/plugin -install lukas-vlcek/bigdesk 
 
 说明:ElasticSearch HQ功能跟这个插件也很强大。 
 
3.2 Head 
 
能够查看索引状况,搜索索引,查看集群状态和分片分布等,能够执行以下命令进行安装,或者访问项目地址:https://github.com/mobz/elasticsearch-head 
 
bin/plugin -install mobz/elasticsearch-head 
 
 3.3 elasticsearch中文分词插件 
 
官方的中文分词插件:Smart Chinese Analysis Plugin 
 
Medcl开发的中午分词插件: IK Analysis Plugin  以及 Pinyin Analysis Plugin 
 
3.4 ZooKeeper Discovery Plugin 
 
elasticsearch 默认是使用Zen做为集群发现和存活管理的,ZooKeeper做为一个分布式高可用性的协调性系统,在这方面有着自然的优点,若是你比较信任zookeeper,那么你可使用这个插件来替代Zen。 
 
总结:本文主要介绍了elasticsearch的插件安装方法,如何查看当前加载的插件的方法,以及我的认为比较值得关注的一些插件。java

相关文章
相关标签/搜索