大数据实战之环境搭建(七)

简介:

本节我给大家测试一下Linux环境的Solr,通过增删改查的实例demo看看Solr环境是否已经OK。记得有哥们留言,问到只看见Solr和Cassandra的单独环境搭建,却不见它们的协同。我想说这两个没有什么必然的联系,在Cassandra的DSE版本,在Cassandra的内部继承了一套Solr的环境,只需要开启开关,就可以自动往Solr同步数据。但是这个嵌入的版本性能太差,无法使用。那么它们之间要怎么样联系呢?因为cassandra的二级索引查询速度不尽如人意,而且查询的语法有限,所以我们引入Solr,用Solr查询出主键,再去Cassandra根据主键查询出想要的速度,总结来说就是Solr中存储一些用于查询的字段,而Cassandra中存储所有要用到的数据,Solr负责查询,Cassandra集群负责数据。


这两天在使用Solr的时候碰到一个问题,由于我的Schema定义如下

143002638.png

当时我少定义了一个uniqueKey,结果报错,但是我加上后重启Tomcat,还是报这个错误,后来一直没解决掉。第二天,我发现居然自己好了,于是看了一下Tomcat的bin目录,没有shutdown.sh,只有startup.sh。我想着是不是因为没有shutdown的原因,我就采用kill进程的方式,关闭了一下tomcat,然后重启,发现就是因为没有关闭tomcat的原因。

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@bogon ~] # ps -ef |grep tomcat
root      5079     1  3 23:02 ?        00:00:20  /usr/java/jdk1 .7.0_21 /bin/java  -Djava.util.logging.config. file = /usr/apache-tomcat-7 .0.40 /conf/logging .properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed. dirs = /usr/apache-tomcat-7 .0.40 /endorsed  -classpath  /usr/apache-tomcat-7 .0.40 /bin/bootstrap .jar: /usr/apache-tomcat-7 .0.40 /bin/tomcat-juli .jar -Dcatalina.base= /usr/apache-tomcat-7 .0.40 -Dcatalina.home= /usr/apache-tomcat-7 .0.40 -Djava.io.tmpdir= /usr/apache-tomcat-7 .0.40 /temp  org.apache.catalina.startup.Bootstrap start
root      6128  6093  0 23:12 pts /0     00:00:00  grep  tomcat
[root@bogon ~] # kill -9 5079
[root@bogon ~] # cd /usr
[root@bogon usr] # cd apache-tomcat-7.0.40
[root@bogon apache-tomcat-7.0.40] # cd bin
[root@bogon bin] # sh startup.sh
Using CATALINA_BASE:    /usr/apache-tomcat-7 .0.40
Using CATALINA_HOME:    /usr/apache-tomcat-7 .0.40
Using CATALINA_TMPDIR:  /usr/apache-tomcat-7 .0.40 /temp
Using JRE_HOME:         /usr/java/jdk1 .7.0_21
Using CLASSPATH:        /usr/apache-tomcat-7 .0.40 /bin/bootstrap .jar: /usr/apache-tomcat-7 .0.40 /bin/tomcat-juli .jar

OK,既然没有问题,我们进入正题,修改Sol实例目录下的SolrConfig.xml文件中的内容

1
2
3
< cores  adminPath = "/admin/cores"  defaultCoreName = "MyTest.UserInfo"  host = "${host:}"  hostPort = "${jetty.port:8080}"  hostContext = "${hostContext:solr}"  zkClientTimeout = "${zkClientTimeout:15000}" >
< core  name = "MyTest.UserInfo"  instanceDir = "Test"  />
</ cores >

Core Name设置为MyTest.UserInfo。

OK,重新启动Solr,我们打开浏览器,如下

143908511.png

我们实例名称已经成为刚才设置的名称(MyTest.UserInfo)。


接下来我们要看的是我们的程序

144234522.png

Entity下面是我们定义的Solr实体,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
namespace  SolrCURDDemo
{
using  SolrNet;
using  SolrNet.Attributes;
public  class  UserInfoEntity
{
public  UserInfoEntity() { }
[SolrUniqueKey( "UserNO" )]
public  string  UserNO {  get set ; }
[SolrField( "Name" )]
public  string  Name {  get set ; }
[SolrField( "Age" )]
public  int ? Age {  get set ; }
[SolrField( "IsMarried" )]
public  bool ? IsMarried {  get set ; }
}
}

和我们刚才定义的Solr Schema一致。然后Reference下面是我们要引用的dll,SolrNet.dll和Microsoft.Practises.ServiceLocation.dl。我下载的SolrNet是0.4.0.2002,大家在网上自己去下。

接下来是我们的SolrConfig配置文件,这个是我自定义的一个xml文件

1
2
3
4
5
6
7
8
9
<? xml  version = "1.0"  encoding = "utf-8"  ?>
< SolrConfigCollection >
< SolrConfigs  baseAddress = "Http://192.168.192.128:8080/MyTest." >
< Schema  name = "UserInfo"  entityName = "SolrCURDDemo.UserInfoEntity" ></ Schema >
</ SolrConfigs >
<!--<SolrConfigs baseAddress="Http://192.168.192.128:8080/MyOtherTest.">
<Schema name="UserInfo"></Schema>
</SolrConfigs>-->
</ SolrConfigCollection >

什么意思呢?在这里我的意思是 一个地址可以有多个Schema,或者多个地址,假如我有这样的一个需求,一个Solr服务负责学生的基信息,一个Solr服务负责学生的成绩信息,那么我们就配置两个SolrConfigs。

接下来是我们Utility,主要是SolrHelper和SolrCollection类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
namespace  SolrCURDDemo
{
using  SolrNet;
using  Microsoft.Practices.ServiceLocation;
using  System.Reflection;
using  SolrNet.Commands.Parameters;
using  System.Configuration;
public  class  SolrHelper
{
private  static  bool  isRegister;
private  static  SolrHelper solrHelper =  new  SolrHelper();
private  SolrHelper()
{ }
private  static  int  MaxQueryCount
{
get
{
return  int .Parse(ConfigurationManager.AppSettings[ "MaxQueryCount" ].ToString());
}
}
public  static  SolrHelper GetInstance()
{
if  (!isRegister)
{
RegisterSolrInstance();
isRegister =  true ;
}
return  solrHelper;
}
private  static  void  RegisterSolrInstance()
{
string  path = AppDomain.CurrentDomain.BaseDirectory +  @"\SolrConfig\SolrConfig.xml" ;
SolrCollection solrCollection = Deserialize<SolrCollection>(path);
Type startUpType =  typeof (Startup);
foreach  (SolrConfigs solrConfig  in  solrCollection.SolrConfigs)
{
foreach  (SchemaInfo schema  in  solrConfig.Schemas)
{
MethodInfo method = startUpType.GetMethod( "Init" new  Type[] {  typeof ( string ) })
.MakeGenericMethod(Type.GetType(schema.EntityType));
method.Invoke( null new  object [] { solrConfig.BaseAddress + schema.ServiceName });
}
}
}
private  static  T Deserialize<T>( string  path)  where  T :  class , new ()
{
XmlReader xmlReader = XmlReader.Create(path);
XmlSerializer xmlSer =  new  XmlSerializer( typeof (SolrCollection));
object  deSerializeObj = xmlSer.Deserialize(xmlReader);
xmlReader.Close();
return  deSerializeObj  as  T;
}
private  ISolrOperations<T> GetSolrOperation<T>()
{
return  ServiceLocator.Current.GetInstance<ISolrOperations<T>>();
}
#region solr operations
#region query
public  List<T> QueryByFilter<T>( string  filter)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
SolrQueryResults<T> result = solrOperation.Query(filter);
return  result.ToList();
}
catch  (Exception ex)
{
throw  ex;
}
}
public  List<T> QueryByFilter<T>(ISolrQuery solrQuery)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
SolrQueryResults<T> result = solrOperation.Query(solrQuery);
return  result.ToList();
}
catch  (Exception ex)
{
throw  ex;
}
}
public  List<T> QueryByFilter<T>( string  filter, Dictionary< string string > sortDictionary)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
List<SortOrder> sortOrderList =  new  List<SortOrder>();
foreach  (KeyValuePair< string string > sortPair  in  sortDictionary)
{
SortOrder sortOrder =  new  SortOrder(sortPair.Key, (Order)Enum.Parse( typeof (Order), sortPair.Value));
sortOrderList.Add(sortOrder);
}
SolrQueryResults<T> result = solrOperation.Query(filter, sortOrderList);
return  result.ToList();
}
catch  (Exception ex)
{
throw  ex;
}
}
public  List<T> QueryByFilter<T>(ISolrQuery solrQuery, Dictionary< string string > sortDictionary)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
List<SortOrder> sortOrderList =  new  List<SortOrder>();
foreach  (KeyValuePair< string string > sortPair  in  sortDictionary)
{
SortOrder sortOrder =  new  SortOrder(sortPair.Key, (Order)Enum.Parse( typeof (Order), sortPair.Value));
sortOrderList.Add(sortOrder);
}
SolrQueryResults<T> result = solrOperation.Query(solrQuery, sortOrderList);
return  result.ToList();
}
catch  (Exception ex)
{
throw  ex;
}
}
public  List<T> QueryByFilter<T>( string  filter,  int  pageIndex,  int  pageSize)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
QueryOptions queryOptions =  new  QueryOptions();
queryOptions.Start = pageIndex;
queryOptions.Rows = pageSize;
if  (pageSize > MaxQueryCount)
{
queryOptions.Rows = MaxQueryCount;
}
SolrQueryResults<T> result = solrOperation.Query(filter, queryOptions);
return  result.ToList();
}
catch  (Exception ex)
{
throw  ex;
}
}
public  List<T> QueryByFilter<T>(ISolrQuery solrQuery,  int  pageIndex,  int  pageSize)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
QueryOptions queryOptions =  new  QueryOptions();
queryOptions.Start = pageIndex;
queryOptions.Rows = pageSize;
if  (pageSize > MaxQueryCount)
{
queryOptions.Rows = MaxQueryCount;
}
SolrQueryResults<T> result = solrOperation.Query(solrQuery, queryOptions);
return  result.ToList();
}
catch  (Exception ex)
{
throw  ex;
}
}
#endregion
#region add
public  int  AddEntity<T>(T entity)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.Add(entity);
solrOperation.Commit();
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
public  int  AddEntityList<T>(List<T> entityList)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.AddRange(entityList);
solrOperation.Commit();
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
#endregion
#region delete
public  int  DeleteByEntity<T>(T entity)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.Delete(entity);
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
public  int  DeleteByKey<T>( string  key)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.Delete(key);
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
public  int  DeleteByEntityList<T>(List<T> entityList)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.Delete(entityList);
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
public  int  DeleteByKeyList<T>(List< string > keyList)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.Delete(keyList);
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
public  int  DeleteByFilter<T>(ISolrQuery query)
{
try
{
ISolrOperations<T> solrOperation = GetSolrOperation<T>();
solrOperation.Delete(query);
return  1;
}
catch  (Exception ex)
{
throw  ex;
}
}
#endregion
#endregion
}
}

这里面主要是Solr的增删改查方法,需要说的下面的这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private  static  void  RegisterSolrInstance()
{
string path = AppDomain.CurrentDomain.BaseDirectory + @ "\SolrConfig\SolrConfig.xml" ;
SolrCollection solrCollection = Deserialize<SolrCollection>(path);
Type startUpType =  typeof (Startup);
foreach (SolrConfigs solrConfig  in  solrCollection.SolrConfigs)
{
foreach (SchemaInfo schema  in  solrConfig.Schemas)
{
MethodInfo method = startUpType.GetMethod( "Init" new  Type[] {  typeof (string) })
.MakeGenericMethod(Type.GetType(schema.EntityType));
method.Invoke( null new  object[] { solrConfig.BaseAddress + schema.ServiceName });
}
}
}

就是我们第一次使用SolrHelper的时候,将配置文件中所有的Solr实例都进行注册,用的时候我们只需要通过下面的代码获取即可

1
2
3
4
private  ISolrOperations<T> GetSolrOperation<T>()
{
return  ServiceLocator.Current.GetInstance<ISolrOperations<T>>();
}

接下来看我们的SolrCollection类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Text;
using  System.Xml.Serialization;
namespace  SolrCURDDemo
{
[XmlRoot( "SolrConfigCollection" )]
public  class  SolrCollection
{
[XmlElement( "SolrConfigs" )]
public  SolrConfigs[] SolrConfigs;
}
public  class  SolrConfigs
{
[XmlElement( "Schema" )]
public  SchemaInfo[] Schemas;
[XmlAttribute( "baseAddress" )]
public  string  BaseAddress;
}
public  class  SchemaInfo
{
[XmlAttribute( "name" )]
public  string  ServiceName;
[XmlAttribute( "entityName" )]
public  string  EntityType;
}
}

对应于我们的SolrConfig.xml文件,用于反序列化,结合SolrHelper中的Desrialize方法就能明白了。

OK,我们的窗体如下

152304700.png

OK,我们看一下保存代码很简单,如下

1
2
3
4
5
6
UserInfoEntity userInfoEntity =  new  UserInfoEntity();
            userInfoEntity.UserNo = userNo;
            userInfoEntity.Name = name;
            userInfoEntity.Age = age;
            userInfoEntity.IsMarried = isMarried;
            int  suc = SolrHelper.GetInstance().AddEntity<UserInfoEntity>(userInfoEntity);

保存成功后,我们先在Solr中查询,结果如下

180853300.png

接着我们在Demo中查询,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string  filter =  this .txtFilter.Text.Trim();
             if  (filter ==  string .Empty)
             {
                 CommonMessage.ShowMessage(Resources.Msg_Input_Filter);
                 return ;
             }
             try
             {
                 List<UserInfoEntity> userInfoList = SolrHelper.GetInstance().QueryByFilter<UserInfoEntity>(filter);
                 this .dgvSearchResult.DataSource = userInfoList;
                 this .BuildRowNumber();
             }
             catch  (Exception ex)
             {
                 CommonMessage.ShowMessage(ex.Message);
             }

可以查询出结果

181300660.png

在得到这样的结果我不得不说,我上面的SolrConfig配置文件的内容应该是这样的

1
2
3
4
5
6
7
8
9
<? xml  version = "1.0"  encoding = "utf-8"  ?>
< SolrConfigCollection >
   < SolrConfigs  baseAddress = "Http://192.168.192.128:8080/solr/MyTest." >
       < Schema  name = "UserInfo"  entityName = "SolrCURDDemo.UserInfoEntity" ></ Schema >
   </ SolrConfigs >
   <!--<SolrConfigs baseAddress="Http://192.168.192.128:8080/solr/MyOtherTest.">
       <Schema name="UserInfo"></Schema>
   </SolrConfigs>-->
</ SolrConfigCollection >

但是不知道怎么回事,我想改上面的地址,因为我少了/solr。但是51cto这个编辑器在chrome和IE9下没办法修改,甚至是我想整个删除都不行,郁闷了,再给大家贴一次。

我们再看看删除的代码

1
2
3
4
5
6
7
string  userNo = txtUserNo.Text.Trim();
           if  (userNo ==  string .Empty)
           {
               CommonMessage.ShowMessage(Resources.Msg_InputUserNo);
               return ;
           }
           int  suc = SolrHelper.GetInstance().DeleteByKey<UserInfoEntity>(userNo);

OK,这个删除是根据主键删除,还有根据实体删除,查询条件删除。看看SolrHelper类中的方法你就清楚了。在这里给大家推荐几个网站

http://en.wikipedia.org/wiki/Apache_Solr

http://wiki.apache.org/solr/

大家去学吧!

最后我想说的是大家下载solrNet的时候不要去官网下载,不知道怎么回事,官网的SolrNet-0.4.0.xx版本有问题,提交保存数据之后会报400错误,但是数据能保存进去,需要重启tomcat才能看到。所以建议大家去GitHub下载。GitHub链接地址:https://github.com/mausch/SolrNet

官网地址:http://code.google.com/p/solrnet/



本文转自 BruceAndLee 51CTO博客,原文链接:http://blog.51cto.com/leelei/1227895,如需转载请自行联系原作者


相关实践学习
简单用户画像分析
本场景主要介绍基于海量日志数据进行简单用户画像分析为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
相关文章
|
4月前
|
SQL 分布式计算 数据可视化
滴滴出行大数据数仓实战
滴滴出行大数据数仓实战
117 0
滴滴出行大数据数仓实战
|
4月前
|
SQL 分布式计算 大数据
【大数据技术Spark】DStream编程操作讲解实战(图文解释 附源码)
【大数据技术Spark】DStream编程操作讲解实战(图文解释 附源码)
39 0
|
4月前
|
安全 大数据 API
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
elasticsearch|大数据|elasticsearch的api部分实战操作以及用户和密码的管理
63 0
|
12天前
|
机器学习/深度学习 人工智能 安全
Azure Databricks实战:在云上轻松进行大数据分析与AI开发
【4月更文挑战第8天】Databricks在大数据分析和AI开发中表现出色,简化流程并提高效率。文中列举了三个应用场景:数据湖分析、实时流处理和AI机器学习,并阐述了Databricks的一体化平台、云原生弹性及企业级安全优势。博主认为,Databricks提升了研发效能,无缝集成Azure生态,并具有持续创新潜力,是应对大数据挑战和加速AI创新的理想工具。
36 0
|
2月前
|
分布式计算 大数据 Java
Spark 大数据实战:基于 RDD 的大数据处理分析
Spark 大数据实战:基于 RDD 的大数据处理分析
121 0
|
4月前
|
SQL 存储 大数据
手把手教你大数据离线综合实战 ETL+Hive+Mysql+Spark
手把手教你大数据离线综合实战 ETL+Hive+Mysql+Spark
93 0
|
4月前
|
机器学习/深度学习 分布式计算 搜索推荐
【大数据技术】Spark MLlib机器学习协同过滤电影推荐实战(附源码和数据集)
【大数据技术】Spark MLlib机器学习协同过滤电影推荐实战(附源码和数据集)
78 0
|
4月前
|
机器学习/深度学习 分布式计算 前端开发
【大数据技术】Spark MLlib机器学习线性回归、逻辑回归预测胃癌是否转移实战(附源码和数据集)
【大数据技术】Spark MLlib机器学习线性回归、逻辑回归预测胃癌是否转移实战(附源码和数据集)
35 0
|
4月前
|
机器学习/深度学习 分布式计算 大数据
【大数据技术】Spark MLlib机器学习特征抽取 TF-IDF统计词频实战(附源码和数据集)
【大数据技术】Spark MLlib机器学习特征抽取 TF-IDF统计词频实战(附源码和数据集)
27 0
|
4月前
|
消息中间件 分布式计算 大数据
【大数据技术】Spark+Flume+Kafka实现商品实时交易数据统计分析实战(附源码)
【大数据技术】Spark+Flume+Kafka实现商品实时交易数据统计分析实战(附源码)
69 0