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