## 選擇正確的directory實現類——存儲模塊
<div style="text-indent:2em;">
<p>在配置集群時,數據存儲模塊是眾多模塊中不需要過多關注的一個模塊,但是卻是非常重要的一個模塊。它允許用戶控制索引數據的存儲方式:持久化存儲(在硬盤上)或者臨時存儲(在內存中)。ElasticSearch中絕大部分的存儲方式都會映射到合適的Apache Lucene Directory類(http://lucene.apache.org/core/4_5_0/core/org/apache/lucene/store/Directory.html )。directory模塊用來存取所有索引文件,因此合理配置就顯得變尤為重要了。 </p>
<h4>存儲類型</h4>
<p>ElasticSearch給用戶提供了4種存儲類型,下面看看它們提供了什么特性以及用戶該如何使用用這些特性。</p>
<h4>簡單的文件系統存儲</h4>
<p>directory類對外最簡單的實現基于文件的隨機讀寫(Java RandomAccessFile: http://docs.oracle.com/javase/7/docs/api/java/io/RandomAccessFile.html )映射到Apache Lucene的SimpleFSDirectory(http://lucene.apache.org/core/4\_5\_0/core/org/apache/lucene/store/SimpleFSDirectory.html )。對于簡單的應用來說,這種實現方式足夠了。它主要的瓶頸是在文件的多線程存取時性能很差。在ElasticSearch中,通常建議使用基于新IO的系統存儲來替代簡單的文件系統存儲。只是如果用戶希望使用簡單的文件系統存儲,可以設置index.store.type屬性值為simplefs。</p>
<h4>新IO文件系統存儲</h4>
<p>這種存儲類型使用的directory類是基于java.nio包中的FileChannel類(http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html )實現的,該類映射到Apache Lucene的NIOFSDirectory類(http://lucene.apache.org/core/4\_5\_0/core/org/apache/lucene/store/NIOFSDirectory.html ). 這種實現方式使得多個線程同時讀寫文件時不會出現性能下降的問題。通過設置index.store.type屬性值為niofs使用該存儲類型。</p>
<!--note structure -->
<div style="height:50px;width:650px;text-indent:0em;">
<div style="float:left;width:13px;height:100%; background:black;">
<img src="../lm.png" height="40px" width="13px" style="margin-top:5px;"/>
</div>
<div style="float:left;width:50px;height:100%;position:relative;">
<img src="../note.png" style="position:absolute; top:30%; "/>
</div>
<div style="float:left; width:550px;height:100%;">
<p style="font-size:13px;margin-top:5px;">需要記住的是由于Microsoft Windows操作上的JVM虛擬機有一些bug,新IO文件系統存儲代碼運行在Windows上時很有可能會出現一些性能問題。bug相關的信息可以參考(http://bugs.sun.com/bugdatabase/view\_bug.do?bug\_id=6265734. )</p>
</div>
<div style="float:left;width:13px;height:100%;background:black;">
<img src="../rm.png" height="40px" width="13px" style="margin-top:5px;"/>
</div>
</div> <!-- end of note structure -->
<h4>MMap文件系統存儲</h4>
<p>這種存儲類型使用Apache Lucene MMapDirectory實現類(http://lucene.apache.org/core/4\_5\_0/core/org/apache/lucene/store/MMapDirectory.html )。它使用mmap系統調用((http://en.wikipedia.org/wiki/Mmap )來讀取和隨機方式完成寫文件操作。在進程中,它將文件映射到相同尺寸的虛擬內存地址空間中。由于沒有任何的鎖操作,多線程存取索引文件時就程序就具有可伸縮性了(可伸縮性是指當增加計算資源時,程序的吞吐量或者處理能力相應的增加)。當我們使用mmap讀取索引文件,在操作系統看來,該文件已經被緩存(文件會被映射到虛擬內存中)。基于這個原因,從Lucene索引中讀取一個文件時,文件不必加載到操作系統的緩存中,讀取速度就會快一些。這基本上就是允許Lucene,也就是ElasticSearch直接操作I/O緩存,索引文件的存取當然會快很多。值得一提的事,MMap文件系統存儲最好應用在64-位操作系統環境中,如果要用在32-位的操作系統環境中,必須確保索引足夠小,而且虛擬內存空間足夠。用戶可以通過設置index.store.type屬性值為mmapfs來使用該存儲類型。 </p>
<h4>內存存儲</h4>
<p>這種存儲類型是幾種類型中唯一不基于Apache Lucene directory實現的(當然也可以用Lucene的RAMDirectory類來實現)。內存存儲類型允許用戶直接把索引數據存儲到內存中,所以硬盤上不會存儲索引數據。記住這一點至關重要,因為這意味著數據并沒有持久化:只要整個集群重啟,數據就會丟失。然而,如果你的應用需要一個微型的、存取快速的,能有多個片分和分片副本的而且重建過程很快的索引,內存存儲類型可能是你需要的。把index.store.type屬性值設置為memeory即可使用該存儲類型。</p>
<!--note structure -->
<div style="height:50px;width:650px;text-indent:0em;">
<div style="float:left;width:13px;height:100%; background:black;">
<img src="../lm.png" height="40px" width="13px" style="margin-top:5px;"/>
</div>
<div style="float:left;width:50px;height:100%;position:relative;">
<img src="../note.png" style="position:absolute; top:30%; "/>
</div>
<div style="float:left; width:550px;height:100%;">
<p style="font-size:13px;margin-top:5px;">存儲在內存中的索引數據,與其它存儲類型相似,也會在允許存數據的節點上保留分片副本。</p>
</div>
<div style="float:left;width:13px;height:100%;background:black;">
<img src="../rm.png" height="40px" width="13px" style="margin-top:5px;"/>
</div>
</div> <!-- end of note structure -->
<h4>其它的屬性</h4>
<p>一旦使用內存存儲類型,我們還對緩存有一定程度的控制,這些屬性非常重要。請記住每個節點都需要設置如下的屬性:
<ul>
<li>cache.memory.direct:該屬性的默認值為true。如果想要把內存的存儲空間分配在JVM堆內存之外,就需要設定該值。一般來說,保留其默認值是個不錯的選擇,這樣能避免堆內存出現過載情況。</li>
<li>cache.memory.small\_buffer\_size: 該屬性的默認值為1KB,內部存儲結構用來存儲索引段信息和刪除文檔的相關信息.</li>
<li>cache.memory.large\_buffer\_size:該屬性的默認值為1MB,內部存儲結構用來存儲除段信息和刪除文檔信息之外的其它信息。 </li>
<li> cache.memory.small\_cache\_size:內部內存結構用來緩存索引段信息和刪除文檔信息,默認值是10MB。 </li>
<li>cache.memory.large\_cache\_size:內部內存結構用來緩存除索引段信息和刪除文檔信息之外的其它信息,默認值是500MB。 </li>
</ul>
</p>
<h4>默認存儲類型</h4>
<p>默認情況下,ElasticSearch會使用基于文件系統的存儲。盡管不同的存儲類型用于不同的操作系統,被選定的存儲類型依然基于文件系統。比如,simplefs類用于32-位的windows操作系統;mmapfs用于Solaris操作系統和64-位的windows操作系統,niofs用于其它的操作系統。</p>
<!--note structure -->
<div style="height:70px;width:650px;text-indent:0em;">
<div style="float:left;width:13px;height:100%; background:black;">
<img src="../lm.png" height="60px" width="13px" style="margin-top:5px;"/>
</div>
<div style="float:left;width:50px;height:100%;position:relative;">
<img src="../note.png" style="position:absolute; top:30%; "/>
</div>
<div style="float:left; width:550px;height:100%;">
<p style="font-size:13px;margin-top:5px;">如果希望尋找來自專家對directory 實現方式使用場景的看法,請參考:Uwe Schindler寫的http://blog.thetaphi.de/2012/07/use-lucenes-mmapdirectory-on-64bit.html和J?rg Prante寫的http://jprante.github.io/applications/2012/07/26/Mmap-with-Lucene.html </p>
</div>
<div style="float:left;width:13px;height:100%;background:black;">
<img src="../rm.png" height="60px" width="13px" style="margin-top:5px;"/>
</div>
</div> <!-- end of note structure -->
<p>通常情況下,我們都會選擇默認的存儲類型。然而當內存容量比較大,索引也比較大的時候,考慮使用MMap文件系統存儲類型是個不錯的選擇。這是因為使用mmap存取索引文件時,會導致索引文件緩存到操作系統的緩存中,能同時被Apache Lucene和操作系統重復使用。</p>
</div>
- 前言
- 第1章 認識Elasticsearch
- 認識Apache Lucene
- 熟悉Lucene
- 總體架構
- 分析你的文本
- Lucene查詢語言
- 認識 ElasticSearch
- 基本概念
- ElasticSearch背后的核心理念
- ElasticSearch的工作原理
- 本章小結
- 第2章 強大的用戶查詢語言DSL
- Lucene默認打分算法
- 查詢重寫機制
- 重排序
- 批處理
- 查詢結果的排序
- Update API
- 使用filters優化查詢
- filters和scope在ElasticSearch Faceting模塊的應用
- 本章小結
- 第3章 索引底層控制
- 第4章 探究分布式索引架構
- 選擇恰當的分片數量和分片副本數量
- 路由功能淺談
- 調整集群的分片分配
- 改變分片的默認分配方式
- 查詢的execution preference
- 學以致用
- 本章小結
- 第5章 管理Elasticsearch
- 選擇正確的directory實現類——存儲模塊
- Discovery模塊的配置
- 索引段數據統計
- 理解ElasticSearch的緩存
- 本章小結
- 第6章 應對突發事件
- 第7章 優化用戶體驗
- 第8章 ElasticSearch Java API
- 第9章 開發ElasticSearch插件