Dağıtılmış bir ortamda master - shard uygulamasında arama yaparken uzun arama süreleriyle (10 saniyelik sipariş) karşılaşıyorum. Ancak Luke ile aynı sorgu, milisaniye cinsinden döner.Dağınık bir ortamda Lucene performansını nasıl iyileştirirsiniz?
Uygulama dağıtılmış bir sistemdir. Tüm düğümler, dizinlerin bulunduğu ortak bir NFS bağını paylaşır. Basitlik için, iki düğüm Node1
ve Node2
'u düşünelim. /etc/fstab
girişleri aşağıdaki gibidir.
nfs:/vol/indexes /opt/indexes nfs rw,suid,nodev,rsize=32768,wsize=32768,soft,intr,tcp 0 0
sistemini vurmak ve düğüm başına besleme ve her Yem için bir usta her biri için bir shard orada birden beslemeleri (Feed1
ve Feed2
diyelim) vardır. indeksleri
Feed1-master
Feed1-shard-Node1.com
Feed1-shard-Node1.com0
Feed1-shard-Node1.com1
gibi arama şöyle FeedIndexManager olan
FeedIndexManager fim = getManager(feedCode);
searcher = fim.getSearcher();
TopDocs docs = searcher.search(q, filter, start + max, sort);
private FeedIndexManager getManager(String feedCode) throws IOException {
if (!_managers.containsKey(feedCode)) {
synchronized(_managers) {
if (!_managers.containsKey(feedCode)) {
File shard = getShardIndexFile(feedCode);
File master = getMasterIndexFile(feedCode);
_managers.put(feedCode, new FeedIndexManager(shard, master));
}
}
}
return _managers.get(feedCode);
}
olduğunu yapan kodlar bak.
public class FeedIndexManager implements Closeable {
private static final Analyzer WRITE_ANALYZER = makeWriterAnalyzer();
private final Directory _master;
private SearcherManager _searcherManager;
private final IndexPair _pair;
private int _numFailedMerges = 0;
private DateTime _lastMergeTime = new DateTime();
public FeedIndexManager(File shard, File master) throws IOException {
_master = NIOFSDirectory.open(master, new SimpleFSLockFactory(master));
IndexWriter writer = null;
try {
writer = new IndexWriter(_master,
WRITE_ANALYZER,
MaxFieldLength.LIMITED);
} finally {
if (null != writer) {
writer.close();
}
writer = null;
}
_searcherManager = new SearcherManager(_master);
_pair = new IndexPair(_master,
shard,
new IndexWriterBuilder(WRITE_ANALYZER));
}
public IndexPair getIndexWriter() {
return _pair;
}
public IndexSearcher getSearcher() {
try {
return _searcherManager.get();
}
catch (IOException ioe) {
throw new DatastoreRuntimeException(
"When trying to get an IndexSearcher for " + _master, ioe);
}
}
public void releaseSearcher(IndexSearcher searcher) {
try {
_searcherManager.release(searcher);
}
catch (IOException ioe) {
throw new DatastoreRuntimeException(
"When trying to release the IndexSearcher " + searcher
+ " for " + _master, ioe);
}
}
/**
* Merges the changes from the shard into the master.
*/
public boolean tryFlush() throws IOException {
LOG.debug("Trying to flush index manager at " + _master
+ " after " + _numFailedMerges + " failed merges.");
if (_pair.tryFlush()) {
LOG.debug("I succesfully flushed " + _master);
_numFailedMerges = 0;
_lastMergeTime = new DateTime();
return true;
}
LOG.warn("I couldn't flush " + _master + " after " + _numFailedMerges
+ " failed merges.");
_numFailedMerges++;
return false;
}
public long getMillisSinceMerge() {
return new DateTime().getMillis() - _lastMergeTime.getMillis();
}
public long getNumFailedMerges() {
return _numFailedMerges;
}
public void close() throws IOException {
_pair.close();
}
/**
* Return the Analyzer used for writing to indexes.
*/
private static Analyzer makeWriterAnalyzer() {
PerFieldAnalyzerWrapper analyzer =
new PerFieldAnalyzerWrapper(new LowerCaseAnalyzer());
analyzer.addAnalyzer(SingleFieldTag.ID.toString(), new KeywordAnalyzer());
// we want tokenizing on the CITY_STATE field
analyzer.addAnalyzer(AddressFieldTag.CITY_STATE.toString(),
new StandardAnalyzer(Version.LUCENE_CURRENT));
return analyzer;
}
}
gecikme yaklaşık 95-98% tüketir katil, bu çağrıdır endeksi Luke ile açıldığında eğer milisaniye cinsinden ise bu bir arama için yaklaşık 20 saniye sürer.
TopDocs docs = searcher.search(q, filter, start + max, sort);
Ben ettik Aşağıdaki sorular
o yem başına birden ustaları var ya ben sadece bir usta azaltacaktır aklı başında mı? Endekste yer alan eleman sayısı 50 milyon civarındadır. birimi sayısını milyon (alt ikinci tepki) daha az olduğu
gecikme beslemeler üzerinde düşüktür. Varlıkların 2 milyonun üzerinde olduğu feed'ler yaklaşık 20 saniye sürüyor. Her bir düğümde her bir düğüm başına 1 Shard'e karşı sadece 1 Shard tutmalı mıyım?
usta Shard adlı den birleştirme her 15 saniyede bir çalışılır. Bu parametre değiştirilmeli mi?
Şu anda Lucene 3.1.0 ve JDK 1.6 kullanıyorum. Kutular, 8 GB RAM'lik iki 64 bit çekirdektir. Şu anda JVM, 4 GB max ile çalışır.
performansını artırmak için herhangi bir öneri
çok değerlidir. Genelde Lucene tarafından reçete edilen tüm standart performans ayarlamalarını gerçekleştirdim. Bu uzun mesajı okumak için çok teşekkürler.
Burada neyin dağıtıldığını anlamıyorum. "Tüm düğümler, dizinlerin bulunduğu ortak bir NFS bağını paylaşır" diyorsunuz. Yani tüm parçalar aynı fiziksel sistemde mi? Muhtemelen NFS performansa zarar veriyor, bu durumda. –