Lucene 搜索性能优化
搜索优化:
1、设置boost
有些时候在搜索时某个字段的权重需要大一些,例如你可能认为标题中出现关键词的文章比正文中出现关键词的文章更有价值,你可以把标题的boost设置的更大,那么搜索结果会优先显示标题中出现关键词的文章(没有使用排序的前题下)。使用方法:
Field. setBoost(float boost);默认值是1.0,也就是说要增加权重的需要设置得比1大。
2、将不需要使用范围查询的数字字段设置precisionstep为Intger.max,这样数字写入倒排仅存一个term,能极大降低term数量。
复制代码
1 public final class CustomFieldType {
2 public static final FieldType INT_TYPE_NOT_STORED_NO_TIRE = new FieldType();
3 static {
4 INT_TYPE_NOT_STORED_NO_TIRE.setIndexed(true);
5 INT_TYPE_NOT_STORED_NO_TIRE.setTokenized(true);
6 INT_TYPE_NOT_STORED_NO_TIRE.setOmitNorms(true);
7 INT_TYPE_NOT_STORED_NO_TIRE.setIndexOptions(FieldInfo.IndexOptions.DOCS_ONLY);
8 INT_TYPE_NOT_STORED_NO_TIRE.setNumericType(FieldType.NumericType.INT);
9 INT_TYPE_NOT_STORED_NO_TIRE.setNumericPrecisionStep(Integer.MAX_VALUE);
10 INT_TYPE_NOT_STORED_NO_TIRE.freeze();
11 }
12 }
复制代码
1
doc.add(new IntField("price", price, CustomFieldType.INT_TYPE_NOT_STORED_NO_TIRE));//人均消费
3、优化方法是只存储id等必须的字段,对于大部分字段我们只索引而不存储,通过这种方法,索引压缩文件降低了10%左右。
1 doc.add(new StringField("price", each, Field.Store.NO));
4、索引更新:indexWriter.updateDocument(new Term("id", "1"), doc);
5、lucene 3.5后删除了optimize(),将IndexWriter.optimize重命名为forceMerge,以便去阻止使用这种方法,因为它的使用代价较高,且也不需要使用
6、新版本的Lucene通常性能都会有些改善
7、使用更快的硬件,例如,改善IO系统性能
8、在建立索引过程中,使用单例的 Writer(注:应该是有有助于避免锁)
9、使用内存索引:
// 打开索引目录
File indexDir = new File(idxDir);
Directory directory = FSDirectory.open(indexDir);
Directory ramDir = new RAMDirectory(directory);
// 获取访问索引的接口,进行搜索
IndexReader indexReader = IndexReader.open(ramDir);
10、// TopDocs 提前返回搜索结果
TopDocs topDocs = indexSearcher.search(query, 100);// 只返回前100条记录
11、不需要highlight则可以将term vector关掉
12、业务能不能拆分, 比如之前音乐图书视频资讯和app一起做搜索, 可以考虑将他们分开
13、调整内存Xms和Xmx,采用多线程gc
14、在频繁更新索引的情况下,使用两个索引,一个大的优化好的历史索引,一个小的实时添加的索引
15、使用FieldSelector仔细的选择哪些字段需要获取,如何获取
Lucene-与索引库的交互 - 球球之家 - 博客频道 - CSDN.NET
内存索引库:数据是临时的、访问速度比文件索引库要快、索引库中的数据不能存放太多、内存索引库和文件索引库能结合在一起
两个或者两个以上的索引库的合并:
如果是内存索引库,直接调用构造函数进行合并就可以了 内存索引库中。也可以调用addIndexesNoOptimize进行合并
如果是文件索引库,调用addIndexesNoOptimize进行合并,该方法可以接受多个索引库
- /**
- * 文件索引库和内存索引库的结合
- */
- @Test
- public void testRamAndFile() throws Exception{
- /**
- * 1、当应用程序启动的时候,把文件索引库的内容复制到内存库中
- * 2、让内存索引库和应用程序交互
- * 3、把内存索引库的内容同步到文件索引库
- */
- Directory fileDirectory = FSDirectory.open(new File("./indexDir"));
- Directory ramDirectory = new RAMDirectory(fileDirectory);
- IndexWriter ramIndexWriter = new IndexWriter(ramDirectory,LuceneUtils.analyzer,MaxFieldLength.LIMITED);
- IndexWriter fileIndexWriter = new IndexWriter(fileDirectory,LuceneUtils.analyzer,true,MaxFieldLength.LIMITED);
- /**
- * 在内存索引库中根据关键词查询
- */
- this.showData(ramDirectory);
- System.out.println("上面的是从内存索引库中查询出来的");
- /**
- * 把一条信息插入到内存索引库
- */
- Article article = new Article();
- article.setId(1L);
- article.setTitle("lucene可以做搜索引擎");
- article.setContent("baidu,google都是很好的搜索引擎");
- ramIndexWriter.addDocument(DocumentUtils.article2Document(article));
- ramIndexWriter.close();
- /*
- * 把内存索引库中的内容同步到文件索引库中
- */
- fileIndexWriter.addIndexesNoOptimize(ramDirectory);
- fileIndexWriter.close();
- this.showData(fileDirectory);
- System.out.println("上面的是从文件索引库中查询出来的");
记录Presto数据查询引擎的配置过程 - 夜丶帝 - 博客园
配置准备:
1、centos6.4系统的虚拟机4个(master、secondary、node1、node2)
2、准备安装包
hadoop-cdh4.4.0、hive-cdh4.4.0、presto、discovery-server、hbase、JDK7.0+64bit、pythin2.4+、postgresql
注:Ssh 权限配置问题:
用户目录权限为 755 或者 700就是不能是77x
.ssh目录权限必须为755
rsa_id.pub 及authorized_keys权限必须为644
rsa_id权限必须为600
最后,在master中测试:ssh master date、ssh secondary date、ssh node1 date、ssh node2 date 不需要密码,则成功。
如果ssh secondary 、ssh node1、ssh node2 连接速度慢,需要更改/etc/ssh/ssh_config 为GSSAPIAuthentication no
修改root的ssh权限,/etc/ssh/sshd_config,将PermitRootLogin no 改为yes
重启sshd服务:/etc/init.d/sshd restrat
5、配置环境变量
[root@master~]# gedit .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
export JAVA_HOME=/usr/java/jdk1.7.0_45
export JRE_HOME=$JAVA_HOME/jre
export CLASS_PATH=./:$JAVA_HOME/lib:$JRE_HOME/lib:$JRE_HOME/lib/tools.jar:/usr/presto/server/lib:/usr/discovery-server/lib
export HADOOP_HOME=/usr/hadoop
export HIVE_HOME=/usr/hive
export HBASE_HOME=/usr/hbase
export HADOOP_MAPRED_HOME=${HADOOP_HOME}
export HADOOP_COMMON_HOME=${HADOOP_HOME}
export HADOOP_HDFS_HOME=${HADOOP_HOME}
export YARN_HOME=${HADOOP_HOME}
export HADOOP_YARN_HOME=${HADOOP_HOME}
export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop
export HDFS_CONF_DIR=${HADOOP_HOME}/etc/hadoop
export YARN_CONF_DIR=${HADOOP_HOME}/etc/hadoop
export PATH=$PATH:$HOME/bin:$JAVA_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin:$HBASE_HOME/bin
master环境变量配置好后,secondary、node1和node2同样配置,可以使用scp命令同步到secondary、node1和node2中
6、配置hadoop
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!--fs.default.name for MRV1 ,fs.defaultFS for MRV2(yarn) --> <property> <name>fs.defaultFS</name> <value>hdfs://master:8020</value> </property> <property> <name>fs.trash.interval</name> <value>10080</value> </property> <property> <name>fs.trash.checkpoint.interval</name> <value>10080</value> </property> </configuration>
c、hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>dfs.replication</name> <value>3</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/opt/data/hadoop-${user.name}</value> </property> <property> <name>dfs.namenode.http-address</name> <value>master:50070</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>secondary:50090</value> </property> <property> <name>dfs.webhdfs.enabled</name> <value>true</value> </property> </configuration>
d、masters(没有则创建该文件)
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>master:19888</value> </property> </configuration>
g、yarn-site.xml
<?xml version="1.0"?> <configuration> <property> <name>yarn.resourcemanager.resource-tracker.address</name> <value>master:8031</value> </property> <property> <name>yarn.resourcemanager.address</name> <value>master:8032</value> </property> <property> <name>yarn.resourcemanager.scheduler.address</name> <value>master:8030</value> </property> <property> <name>yarn.resourcemanager.admin.address</name> <value>master:8033</value> </property> <property> <name>yarn.resourcemanager.webapp.address</name> <value>master:8088</value> </property> <property> <description>Classpath for typical applications.</description> <name>yarn.application.classpath</name> <value>$HADOOP_CONF_DIR,$HADOOP_COMMON_HOME/share/hadoop/common/*, $HADOOP_COMMON_HOME/share/hadoop/common/lib/*, $HADOOP_HDFS_HOME/share/hadoop/hdfs/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*, $YARN_HOME/share/hadoop/yarn/*,$YARN_HOME/share/hadoop/yarn/lib/*, $YARN_HOME/share/hadoop/mapreduce/*,$YARN_HOME/share/hadoop/mapreduce/lib/*</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce.shuffle</value> </property> <property> <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name> <value>org.apache.hadoop.mapred.ShuffleHandler</value> </property> <property> <name>yarn.nodemanager.local-dirs</name> <value>/opt/data/yarn/local</value> </property> <property> <name>yarn.nodemanager.log-dirs</name> <value>/opt/data/yarn/logs</value> </property> <property> <description>Where to aggregate logs</description> <name>yarn.nodemanager.remote-app-log-dir</name> <value>/opt/data/yarn/logs</value> </property> <property> <name>yarn.app.mapreduce.am.staging-dir</name> <value>/user</value> </property> </configuration>
h、复制hadoop到secondary、node1和node2
i、hadoop第一次运行需要先格式化,命令如下:[root@tamaster hadoop]hadoop namenode -format
j、关闭hadoop安全模式,命令如下:hdfs dfsadmin -safemode leave
k、运行hadoop,命令: [root@tamaster:~]start-all.sh
master
secondary
node1
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>hbase.rootdir</name> <value>hdfs://master/hbase-${user.name}</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.tmp.dir</name> <value>/opt/data/hbase-${user.name}</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>master,secondary,node1,node2</value> </property> </configuration>
d、将hbase同步到secondary、node1、node2中
e、启动hbase,命令如下:
[root@master:~]# start-hbase.sh
8、安装hive
a、下载hive压缩包,并将其解压到/usr,即:/usr/hive
b、hive-site.xml
<?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:postgresql://master/testdb</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>org.postgresql.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hiveuser</value> <description>username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>redhat</value> <description>password to use against metastore database</description> </property> <property> <name>mapred.job.tracker</name> <value>master:8031</value> </property> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>hive.aux.jars.path</name> <value>file:///usr/hive/lib/zookeeper-3.4.5-cdh4.4.0.jar, file:///usr/hive/lib/hive-hbase-handler-0.10.0-cdh4.4.0.jar, file:///usr/hive/lib/hbase-0.94.2-cdh4.4.0.jar, file:///usr/hive/lib/guava-11.0.2.jar</value> </property> <property> <name>hive.metastore.warehouse.dir</name> <value>/opt/data/warehouse-${user.name}</value> <description>location of default database for the warehouse</description> </property> <property> <name>hive.exec.scratchdir</name> <value>/opt/data/hive-${user.name}</value> <description>Scratch space for Hive jobs</description> </property> <property> <name>hive.querylog.location</name> <value>/opt/data/querylog-${user.name}</value> <description> Location of Hive run time structured log file </description> </property> <property> <name>hive.support.concurrency</name> <description>Enable Hive's Table Lock Manager Service</description> <value>true</value> </property> <property> <name>hive.zookeeper.quorum</name> <description>Zookeeper quorum used by Hive's Table Lock Manager</description> <value>node1</value> </property> <property> <name>hive.hwi.listen.host</name> <value>desktop1</value> <description>This is the host address the Hive Web Interface will listen on</description> </property> <property> <name>hive.hwi.listen.port</name> <value>9999</value> <description>This is the port the Hive Web Interface will listen on</description> </property> <property> <name>hive.hwi.war.file</name> <value>lib/hive-hwi-0.10.0-cdh4.2.0.war</value> <description>This is the WAR file with the jsp content for Hive Web Interface</description> </property> </configuration>
9、安装postgresql(用postgresql作为元数据库)
a、下载postgresql,并安装
b、使用pgadmin创建用户sa
c、使用pgadmin创建数据库testdb,并指定所属角色为sa
d、配置pg_hba.conf的访问地址,允许主机访问
e、配置postgresql.conf
standard_conforming_strings = off
f、复制postgres 的jdbc驱动 到 /usr/hive-cdh4.4.0/lib
1)node.properties
node.environment=production
node.id=F25B16CB-5D5B-50FD-A30D-B2221D71C882
node.data-dir=/var/presto/data
注意每台服务器node.id必须是唯一的
2)jvm.config
-server
-Xmx16G
-XX:+UseConcMarkSweepGC
-XX:+ExplicitGCInvokesConcurrent
-XX:+CMSClassUnloadingEnabled
-XX:+AggressiveOpts
-XX:+HeapDumpOnOutOfMemoryError
-XX:OnOutOfMemoryError=kill -9 %p
-XX:PermSize=150M
-XX:MaxPermSize=150M
-XX:ReservedCodeCacheSize=150M
-Xbootclasspath/p:/var/presto/installation/lib/floatingdecimal-0.1.jar
下载floatingdecimal-0.1.jar包放在/var/presto/installation/lib/目录下
3)config.properties
coordinator=true
datasources=jmx
http-server.http.port=8080
presto-metastore.db.type=h2
presto-metastore.db.filename=var/db/MetaStore
task.max-memory=1GB
discovery-server.enabled=true
discovery.uri=http://master:8411
以上为master的配置,secondary、node1和node2中需将coordinator=true值改为false,将discovery-server.enabled=true删除掉
4)log.properties
com.facebook.presto=DEBUG
5)在/usr/presto/etc中创建catalog文件夹,并创建以下配置文件
jmx.properties
connector.name=jmx
hive.propertes
connector.name=hive-cdh4
hive.metastore.uri=thrift://master:9083
1)node.properties
node.environment=production
node.id=D28C24CF-78A1-CD09-C693-7BDE66A51EFD
node.data-dir=/var/discovery/data
2)jvm.config
-server
-Xmx1G
-XX:+UseConcMarkSweepGC
-XX:+ExplicitGCInvokesConcurrent
-XX:+AggressiveOpts
-XX:+HeapDumpOnOutOfMemoryError
-XX:OnOutOfMemoryError=kill -9 %p
3)config.properties
http-server.http.port=8411
运行:
master机器上运行命令如下:
start-all.sh(启动每台机器上的hadoop)
start-hbase.sh(启动每台机器上的hbase)
转入usr/disdiscovery-server/bin中启动disdiscovery-server,命令如下
1、启动hadoop命令:
hadoop namenode -format
hadoop datanode -format
start-all.sh
hadoop dfsadmin -safemode leave
hdfs dfsadmin -safemode leave
2、hive启动命令:
./hive
./hive --service hiveserver -p 9083 //thrift模式
3、hbase 命令
./start-hbase.sh
4、discovery-server命令:
laucher start //启动
laucher run //运行
lancher stop //停止
5、presto命令
laucher start //启动
laucher run //运行
lancher stop //停止
6、presto 客户端启动
./presto --server localhost:8080 --catalog hive --schema default
4 nodes select Count(*) from mytable; 10s
4 nodes select Count(*),num from mytable group by num; 10s
4 nodes select num from mytable group by num having count(*)>1000; 10s
4 nodes select min(num) from mytable group by num; 9s
4 nodes select min(num) from mytable; 9s
4 nodes select max(num) from mytable; 9s
4 nodes select min(num) from mytable group by num; 9s
4 nodes select row_number() over(partition by name order by num) as row_index from mytable; 16s