* Elasticsearch
** Elasticsearch 與 Lucene 之間的關係
Lucene 搜索引擎組件,使用java編寫的,爲了方便使用的搜索組件,主要的功能就
是創建索引而後進行搜索.自己不能直接使用,須要集成到應用中提供搜索服務.或
者說是完成搜索功能.下面介紹下Lucene的基本概念和創建索引與搜索索引基本
流程.java
Lucene 的邏輯概念包括: index,segemnts,documents,field,term等.其關聯關
系能夠簡要描述以下:index 表示索引,由一個或多個段組成;segments 表示段,
由一個或多個文檔組成;documents 表示文檔,由一個或多個域組成;fields 表示
域,由一個或多個詞組成,能夠理解爲文檔的屬性;terms 表示詞,原始字符串由分
詞器進行分詞後獲得.
index -> segments -> documents -> fields -> terms
Lucene 創建索引流程:對於一個對象須要創建索引時,首先肯定哪些屬性須要建
立索引並進行預處理,而後使用分詞器進行分詞.根據分詞結果創建索引,將數據
寫入到指定索引目錄.node
Lucene 搜索基本流程:在搜索時,須要肯定要搜索的描述(哪一個屬性,值是什麼),
而後使用建立索引時相同的預處理和分詞器.最後去索引目錄中進行搜索操做.linux
Lucene 搜索過程當中,基本都是按照fields進行搜索,所謂的全文搜索,是通過特殊
處理,將所有field按照特定的格式寫入到特定的字段上,搜索這個字段來完成全
文搜索.web
Elasticsearch 封裝Lucene組件,開箱即用的可拓展的搜索引擎.能夠經過tcp鏈
接和http(restful)等方式提供搜索服務,拓展性極強.bootstrap
Elasticsearch 爲了提供可拓展的搜索服務,提出了不少分佈式概念.下面結合
Lucene的已有概念,進行簡要描述.Elasticsearch 涉及到的具備表明性的概念包
括:cluster, node, indices, shard, doc, mapping, field, term,分別進行簡
單描述:api
closter 表示集羣 一組Elasticsearch實例(node)所組成的集羣.能夠方便的進
行橫向拓展.提供創建索引和搜索索引的能力. node表示集羣中的工做節點,提供
服務相關操做.這些都是邏輯上的概念,條件運行一臺物理機器上能夠啓動多個
node.node 的角色有兩個,master和data.master 節點須要參與主master的選舉,
而且負責參與集羣外部請求的響應與分發和結果的聚集與聚合等操做. data 節
點只負責數據的存儲與搜索等操做.一個集羣當中能夠有多個master和data.一個
node能夠便是master同時也是data.同時一個節點既能夠不是master同時也不是
data. 這樣的節點做爲一個搜索的負載均衡器.indices 邏輯上的索引結構,有自
己的索引結構定義(mapping),由一個或多個shard組成. shard 索引的具體結構,
對應lucene的index概念.存儲創建索引的數據.並提供基本搜索能力.doc表示
documents 與lucene的文檔概念相同. mapping 邏輯上表示indices所處理的文
檔類型.用於說明doc的屬性特徵.同一個mapping中能夠有多個類型. field 對應
lucene的field的概念,與其基本相同.term 對應lucene的term的概念,與其基本
相同.緩存
Elasticsearch 的創建索引流程與搜索基本流程與lucene相比較,增長了master
節點對請求的處理以及分發到data節點和彙總各個節點請求的過程,其餘基本類
似.
** 主節點選舉策略
** 分片策略
** 路由規則
** 請求分發規則
** Elasticsearch 性能調優
*** gc策略調優
分配內存高達30或40G,超過CMS gc 設計的最大值,gc效果不是很理想。所以升
級jdk到1.8,採用g1策略。並在此基礎上,結合驗證服務器運行狀況進行驗證。
獲得一系列gc調優的參數。減小日常簡單查詢觸發full gc的次數,保證通常情
況下可以正常響應。
基本的調優參數以下:(針對64核心,128g機器) 通常的機器建議採用默認方式.
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC"
JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=500"
JAVA_OPTS="$JAVA_OPTS -XX:InitiatingHeapOccupancyPercent=30"
JAVA_OPTS="$JAVA_OPTS -XX:NewRatio=10"
JAVA_OPTS="$JAVA_OPTS -XX:G1ReservePercent=20"
JAVA_OPTS="$JAVA_OPTS -XX:SurvivorRatio=8"
JAVA_OPTS="$JAVA_OPTS -XX:ConcGCThreads=4"
JAVA_OPTS="$JAVA_OPTS -XX:G1HeapRegionSize=32"bash
*** elasticsearch 參數調優
在elasticsearch.yml中,修改其配置。
一、指定數據目錄,方便磁盤空間的拓展。
path.data: /mnt/extra/hd/esdata服務器
二、指定緩存策略,在必定程度上提升簡單查詢效率。
indices.cache.filter.size: 20%
indices.cache.query.size: 3%
indices.fielddata.cache.size: 20%
indices.breaker.fielddata.limit: 80%restful
三、修改段合併策略,保證其段合併不會佔用大量資源。
indices.store.throttle.max_bytes_per_sec: 40m
index.merge.policy.max_merged_segment: 15gb
index.merge.scheduler.max_thread_count: 1
四、修改索引觸發寫磁盤的時間間隔,減小此過程當中所產生段的數量。
index.translog.flush_threshold_ops: 100000
index.translog.flush_threshold_size: 512m
五、node 節點意外下線, 間隔多長時間從新分配分片.
index.unassigned.node_left.delayed_timeout: 5m
六、線程池大小設定修改
線程池默認設置爲200,如今根據機器cpu核心數量進行適當調整,
threadpool:
index:
type: fixed
size: 4
threadpool:
search:
type: fixed
size: 4
threadpool:
bulk:
type: fixed
size: 4
*** 系統配置修改
改系統限制,對elasticsearch 建立單獨的用戶,對用戶所佔用的系統資源進行
修改。去掉沒必要要的限制(例如:虛擬內存大小等)。禁用這個用戶使用 swap
空間。
在配置文件中添加
bootstrap.mlockall: true
修改配置linux 相關係統配置.
一、elasticsearch 用戶禁用swap。
須要修改/etc/security/limits.conf的相關內容,使用elasticsearch用戶來啓動,
添加
elasticsearch - nofile 65000
elasticsearch - memlock unlimited
接下來修改/etc/pam.d/common-session文件,添加以下內容:
session required pam_limits.so
還須要從新登陸。
二、取消其餘限制
~/.bashrc
添加
ulimit -v unlimited
ulimit -m unlimited
而後 執行source ~/.bashrc
3 修改下系統參數vm.max_map_count的設置爲262144
具體作法是在/etc/sysctl.conf中加入
vm.max_map_count = 262144
從新登陸生效。
*** 索引方面的優化
精簡索引結構,從新設計,提升可用性與可維護性.精簡組件, web與hadoop方面直
接使用elasticsearch api,去掉anydrill.使得es能夠得到更多的資源.
*** hadoop 中關於elasticsearch 方面的修改
修改其刪除策略,原來的刪除策略是使用anydrill,調用elasticsearch 的
delete by query api。並在刪除結束後,直接調用flush api,觸發段合併,這
樣會消耗大量服務器資源,引起服務卡死。同時,delete by query api 在其後
續版本中存在內存溢出問題,進行修改,直接使用elasticsearch 來完成刪除操
做,使用scroll api +bulk api 實現。優化業務邏輯,減小es數據執行天任務時
修要修改的數據量,提升任務執行效率.
*** 集羣
嘗試設置一個master node。兩個data node,設置兩個balancer。嘗試三千萬數
據全排,而後取最後面幾條,data node內存使用變化不大,master node 內存
使用變化不大,排序所須要的內存,都在balancer中。這樣能夠保證集羣較爲穩
定,當出現排序操做時,balancer的內容會大幅增加,可是因爲jvm容器的隔離,
即便balancer掛掉,其餘組件也不會出現問題,這樣會提升系統穩定性。
** Elasticsearch 批量請求使用技巧 elasticsearch api 相關說明很是多,這裏只針對批量請求處理的api進行簡單說 明.涉及到的api包括scroll api 和bulk api. // 建立scroll request,並獲取結果 SearchResponse scrollResp = client.prepareSearch(this.indiceName) .setSearchType(SearchType.SCAN) .setScroll(new TimeValue( ElasticsearchConstValue.CLIENT_SCROLL_TIME_OUT)) .setQuery(query) .setSize(ElasticsearchConstValue.CLIENT_BULK_SIZE) .addField("_id").execute().actionGet(); // 建立bulkRequest BulkRequestBuilder bulkRequest = client.prepareBulk(); BulkResponse bulkResponse = null; // 循環處理scroll請求的結果. while (true) { for (SearchHit hit : scrollResp.getHits().getHits()) { // 構造批量請求. bulkRequest.add(client.prepareDelete(this.indiceName, this.indiceType, hit.getId())); } if (scrollResp.getHits().getHits().length != 0) { // 統一獲取批量請求結果並,從新構造請求. bulkResponse = bulkRequest.execute().actionGet(); if (bulkResponse != null) { if (bulkResponse.hasFailures()) { LOG.error("bulk has error: " + bulkResponse.buildFailureMessage()); } } bulkRequest = client.prepareBulk(); } scrollResp = client .prepareSearchScroll(scrollResp.getScrollId()) .setScroll(new TimeValue( ElasticsearchConstValue.CLIENT_SCROLL_TIME_OUT)) .execute().actionGet(); if (scrollResp.getHits().getHits().length == 0) { break; } } // 釋放elasticsearch 服務器資源 client.prepareClearScroll().addScrollId(scrollResp.getScrollId()) .execute().actionGet(); ** 常見問題 *** Elasticsearch 卡死 在執行大量搜索請求時,發現Elasticsearch卡死, 能夠考慮將段合併的資源限制 下,而後將線程池的大小限制下. 這樣能夠保證es不會卡死. *** Elasticsearch 報直接內存溢出錯誤 Elasticsearch 若是報 oom direct memory,則須要注意,Elasticsearch 中集成 的netty模塊產生的這個問題,這個問題產生的緣由是netty的客戶端與服務端通 信過程當中,若是某一端的處理能力有限,另外一端的數據產生量很是大時,在數據產 生端,會爆出oom direct memory錯誤. 這個問題是能夠重現的,並且在 elasticsearch的 1.7.5 如下的版本中都會出現.建議檢查數據接收端是什麼原 因致使處理能力慢.是不是數據接收端有性能瓶頸.