我最近从Postgres切换到了Solr,在查询中加速了~50倍.我们运行的查询涉及多个范围,我们的数据是车辆清单.例如:"查找里程<50,000,$ 5,000 <价格<$ 10,000,make = Mazda ......"的所有车辆
我在Postgres的所有相关专栏上创建了索引,所以它应该是一个相当公平的比较.看看Postgres中的查询计划虽然它仍然只是使用单个索引然后扫描(我假设因为它无法使用所有不同的索引).
据我了解,Postgres和Solr使用模糊相似的数据结构(B树),它们都将数据缓存在内存中.所以我想知道这么大的性能差异来自哪里.
架构有什么不同可以解释这一点?
是否有任何关于Lucene/Solr在大型数据集上的性能基准的链接/资源.数据集高于500GB~5TB的范围
谢谢
我正在使用Java 7中的转义分析进行一些测试,以便更好地了解哪些对象有资格进行堆栈分配.
这是我编写的用于测试堆栈分配的代码:
import java.util.ArrayList;
import java.util.Iterator;
public class EscapeAnalysis {
private static final long TIME_TO_TEST = 10L * 1000L; // 10s
static class Timestamp {
private long millis;
public Timestamp(long millis) {
this.millis = millis;
}
public long getTime() {
return millis;
}
public void setTime(long time) {
millis = time;
}
}
public static void main(String[] args) {
long r = 0;
System.out.println("test1");
r += test1();
System.out.println("test2");
r += test2();
System.out.println("test3");
r += test3();
System.out.println("test4");
r …Run Code Online (Sandbox Code Playgroud) 我们在Windows 2008 R2上运行的Solr 3.4实例与Oracle Java 6 Hotspot JDK一起变得没有响应.当我们查看机器时,我们注意到可用的物理内存为零.
Tomcat7.exe进程使用~70Gigs(私有工作集),但工作集(内存)正在使用系统上的所有内存.Tomcat/Solr日志中没有错误.我们使用VMMap来识别内存是否用于映射Solr segement文件的内存.
重启Tomcat会暂时解决问题,但最终还是回来了.
然后我们尝试减小JVM大小以为内存映射文件提供更多空间,但随后Solr最终对100%的旧代没有响应.再次重置修复了问题,但在重置之前它没有抛出内存不足异常.
目前我们的蜘蛛侠意识告诉我们,当存在内存压力时,缓存不会缩小,并且可能存在太多MappedByteBuffers,因此操作系统无法从内存映射文件中释放内存.
一些主要的JVM类(例如String或List实现)通过返回与方法相关的? 31^n * field_n.hashCode()每个类field_n来实现equals equals.此外,Joshua Bloch在Effective Java(第9项)中推荐了这种方法.
但是,其他类(如Map.Entry实现)遵循不同的规则.例如,Map.Entry文档指出a的哈希码Map.Entry应该是
(e.getKey()==null ? 0 : e.getKey().hashCode()) ^
(e.getValue()==null ? 0 : e.getValue().hashCode())
Run Code Online (Sandbox Code Playgroud)
这有时在哈希表中使用是不切实际的,因为:
为什么Java选择Map.EntryhashCode的实现规范而不是,例如,31 * (e.getKey()==null ? 0 : e.getKey().hashCode()) + (e.getValue()==null ? 0 : e.getValue().hashCode())?
编辑1:
为了帮助解决问题,下面是一个有用代码的示例,如果许多条目具有相同的键和值,则由于散列冲突导致结果的性能非常差.
此方法计算不同地图条目的频率(使用Guava的Multiset).
public static <K, V> Multiset<Map.Entry<K, V>> computeEntryCounts(
Iterable<Map<K, V>> maps) {
ImmutableMultiset.Builder<Map.Entry<K, V>> result = ImmutableMultiset.builder();
for (Map<K, V> map …Run Code Online (Sandbox Code Playgroud) solr ×3
java ×2
jvm ×2
lucene ×2
benchmarking ×1
hashcode ×1
java-7 ×1
memory-leaks ×1
mmap ×1
performance ×1
postgresql ×1
rdbms ×1