相信做过一两个项目的人都会遇到上级要求做一个类似百度或者谷歌的站内搜索功能。传统的sql查询只能使用like 或者FIND_IN_SET来实现、后者性能稍微好点但是必须要逗号分隔才可以实现匹配、甚至多条件的话还可能用到OR这是极影响系统性能的。
最近公司项目需要、主要是系统查询缓慢、并且查询精度不敢恭维。一开始想到的是Lucene 毕竟是一个开放源代码的全文检索引擎工具包 并且官方还在持续更新中。当时闲暇时间大概搞了将近一个星期的时间、索引的增删查改以及中文分词IKAnalyzer。但是数据量大了问题就来了、Lucene是不支持集群的。谷歌了半天找到一个叫solr的东西、它是基于Lucene的全文搜索服务器并且支持集群。然后就是各种搭环境配置中文分词、搭建zookeeper服务器、搭建solr服务器、然后是服务器之间的各种整合。期间出现的问题可谓是数不胜数、只能用2个字来形容”繁琐”。说了那么多顺便说说solr的安全性问题、SolrJ没有提供访问控制接口,也就是说只要知道solr服务器信息,任何人都可以连接solr服务器来进行索引增加、修改、删除操作。虽然有多种方式可以限制、但总觉得心里不踏实、但是阿里云的Opensearch就不一样了(见后面代码)。
趁着阿里云搞活动、也是公司业务需要于是申请了Opensearch内侧资格。
一:创建应用
1、创建应用名以及描述。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_2dee5a54b9b4e55.jpg?141)
2、选择结构类型、因为是测试所以选择自定义结构。输入表明以及字段点击继续即可。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_02a30407f673ba8.jpg?214)
3、继续后会看到一个静态展示的表结构这时点击下一步即可。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_f378e4748fe68e0.png?44)
4、因为没有购买阿里云的OSS和ODPS所以这里选择手动上传。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_fef42296a73e2a3.png?43)
5、应用结构展示。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_96edddfca2050ae.jpg?179)
6、创建后还要激活应用。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_205f1bb8f699dd2.png?26)
7、这里你可以自定义配额、以后也可以自行修改(很人性化的功能)。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_dc91652763b8377.png?29)
8、同第四步没有OSS和ODPS这里直接选择完成即可、至此整个应用配置完毕。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_18adcf9056daabd.jpg?66)
9、因为本人是做javaWeb开发的所以这里选择java的SDK下载。
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_8ed7c3228b677f3.png?309)
二:创建demo
1插入数据
本地测试插入1000条数据、push以后花费时间为4565ms
本地测试插入10000条数据、push以前花费时间106ms、push半天报错
复制代码
- 十月 10, 2014 8:43:48 上午 org.apache.http.impl.client.DefaultRequestDirector tryExecute
- 信息: I/O exception (java.net.SocketException) caught when processing request: Connection reset by peer: socket write error
- 十月 10, 2014 8:43:48 上午 org.apache.http.impl.client.DefaultRequestDirector tryExecute
- 信息: Retrying request
感觉应该是阿里云服务端做了限制、一次性push 10000条记录就会中断、选择每1000条数据push一次、测试插入10000条数据:71940ms。
本地测试插入五万条数据一次push 1000条数据花费时间:210267ms
本地测试插入十万条数据一次push 1000条数据到6万的时候中断、不清楚是否阿里云服务端限制、如果后台定时任务一次性构建百万或者千万条数据是否还有影响。
具体一次性push多少数据、我没有详细的测试、应该是越多越好、以上是测试数据仅供参考、并不是十分准确。
至此一共插入124147条数据也算是10万级别的了。
2、查询数据
![点击查看原图](http://aliyunbbs.oss.aliyuncs.com/attachment/thumb/Fid_229/229_1427985705731853_c2d4ea211190a07.png?57)
以上为查询关键词VPS分页查询10条数据查询时间为0.009275秒几乎可以忽略不计了。
三:系统测试
1、目前系统测试
系统为单核非集群、服务器为tomcat、数据库数据为5000条。
页面数据包括基础查询条件以及表数据展示、单表字段为47个。
并发100人,页面搜索反应时间为0.73秒
应用服务器:30%<CPU<50%左右,内存使用较小
数据库服务器:CPU<10%,内存使用较小
并发120人,页面搜索反应时间为1.18秒
应用服务器:30%<CPU<50%左右,内存使用较小
数据库服务器:CPU<10%,内存使用较小
并发150人,页面搜索反应时间为5.08秒
应用服务器:CPU<50%左右,内存使用较小
数据库服务器:CPU<10%,内存使用较小
根据以上12万数据的查询大体可以得出结论并发150应该会控制到ms级别。
最后附上测试代码:
package openSearch;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.client.ClientProtocolException;
import org.json.JSONException;
import org.junit.Before;
import org.junit.Test;
import com.opensearch.javasdk.CloudsearchClient;
import com.opensearch.javasdk.CloudsearchDoc;
import com.opensearch.javasdk.CloudsearchSearch;
import com.opensearch.javasdk.object.KeyTypeEnum;
public class OpenSearch {
/**
* 阿里云OpenSearch采用Access Key 连接方式、相比solr安全系数不止提高了一个档次。
*/
private static final String ACCESSKEY = "xxx";
private static final String SECRET = "xxx";
private static final String INDEXNAME = "52itstyle";
private static final String URL = "http://opensearch.aliyuncs.com";
private CloudsearchClient client;
@Before
public void init() {
Map<String, Object> opts = new HashMap<String, Object>();
opts.put("host", URL);
client = new CloudsearchClient(ACCESSKEY, SECRET , opts,KeyTypeEnum.ALIYUN);
}
@Test
/**
* 测试数据插入
* @throws JSONException
* @throws ClientProtocolException
* @throws IOException
*/
public void addTest() throws JSONException, ClientProtocolException, IOException{
CloudsearchDoc doc = new CloudsearchDoc(INDEXNAME, client);
Map<String, Object> ques = new HashMap<String, Object>();
//开始时间
Long beginDate = System.currentTimeMillis();
//插入50000条数据测试
for(int i=0;i<=50000;i++){
ques.put("id", "200003"+i);//ID主键
ques.put("title", "搞网站运营已有6年时间了)");
ques.put("content", "搞网站运营已有6年时间了,期间运营过大大小的网站10多个,空间、VPS国内国外都使用过。国内最普遍的环境就是不稳定,隔三差五不是被攻击就是线路调整。一直困惑不已。 ");
doc.add(ques);
//每加入1000条数据结束之后push一下
if(i%1000==0){
doc.push("article");
}
}
//结束时间
Long endDate = System.currentTimeMillis();
System.out.print("插入50000条数据:"+(endDate-beginDate));
}
}
评测总结:
优点:
1: 省去了配置以及维护solr运营成本、数据直接扔给opensearch、用户不用再去关心宕机、集群的问题。
2:阿里后台有清晰的应用结构、错误日志、基本信息、配额管理以及数据统计、界面化管理一目了然。
3:应用自定义结构、相比于solr的配置schema.xml要耐看的多。
4:支持复杂查询、排序表达式、可聚合、可过滤以及多次查询等特点、基本满足了项目的需求。
5:还有很多自己摸索、、、、
缺点:
1:推送数据、每秒推送次数5次 每个包大小 编码前2M、这些限制肯定有它的道理、服务开销或者技术瓶颈什么的、按说阿里不会有神马技术瓶颈吧。问题是如果数据丢失或者重构索引我应该一次push多少在表结构不是很确定的情况下。
2:查看API 搜索返回的格式 有xml, json和protobuf 这三种、是否可以像solr一样导入@FILE 直接转化为试题类的API、这样其实包括add或者search 都会变得相对简单一些吧。
3:是否能做的像CNZZ统计一样就更高达上了。 $Lj ]NtO
4:貌似后台索引只能单个删除、能否一键删除或者个性化删除。虽然这些功能API都可以做到、但是还是希望阿里能搞定它。
5:价格问题 你懂我懂大家都懂。
如果感觉该评测对您有所帮助, 欢迎投票给本文:
投票标题: 阿里云产品公测】大数据下精确快速搜索OpenSearch;作者:小柒2012
投票地址: http://bbs.aliyun.com/read/178799.html