1. 常用容器操作
常用到的进入容器命令行和开启服务的命令
# 开启docker
docker container exec -it anyq-faq /bin/bash
# 切换到服务脚本目录
cd /home/AnyQ-master/build/
# 如果使用了容器,那么容器stop 再start的时候,要重新source一下,不然还是找不到java
source ~/.bash_profile
# 执行solr服务
sh solr_script/anyq_solr.sh solr_script/sample_docs
# 执行faq服务
./run_server
# 浏览器输入
http://XXXX:8886/anyq?question=使用什么账号?
# solr查看,浏览器输入:
http://XXX:8900/solr/
"""
8886映射自8889,是anyq的接口
8900映射自8900,是solr的接口
# 如果报错java找不到
cd /home
export PATH=`pwd`/jdk1.8.0_171/bin:$PATH
java -version
# 上面只是暂时生效的配置,重新进入容器就又会丢掉,可以直接在bash中配置
cd ~
[root@567b3aed2b1c ~]$ ls -a # 查看隐藏文件
. .bash_logout .cshrc .tcshrc
.. .bash_profile .gitconfig
anaconda-ks.cfg .bashrc .oracle_jre_usage
.bash_history .cmake .pki
# 在bash_profile文件中配置java_home
vi ~/.bash_profile
# 在最后一行添加
export JAVA_HOME=/home/jdk1.8.0_171/
export PATH=$PATH:$JAVA_HOME/bin
# 或者只添加下面一行(直接写自己对应的jdk的bin路径就可以)
export PATH=/home/jdk1.8.0_171/bin:$PATH
# 需要手动执行,不然不会生效
source ~/.bash_profile
# 验证是否生效
echo $PATH # 观察是否包含jdk的bin目录
echo $JAVA_HOME #是否和上面写的一样
"""
2. (尝试 较混乱)添加一个solrcore
参考:Solr04 - 在Jetty和Tomcat上部署Solr单机服务
(1) Solr工程对外通过SorlCore提供服务, 一个SolrCore相当于数据库中的一张表, 需要注意的是, 这个功能就相当于一个数据库中存在多张表;
(2) 将索引数据分SolrCore存储,方便对索引数据管理维护;
2.1 通过solr的管理UI界面添加solrcore
报错了,放弃
但是这个报错导致后续界面刷新后一直出错,参考:SolrCore Initialization Failures
在高版本的solr中,通过界面新建core的问题似乎已经解决了,但是在老版本中,不建议通过这种方式进行。
最好的方式就是重启solr
2.2 重启AnyQ中的solr
关键命令
cd /home/AnyQ-master/build/
# sh solr_deply.sh stop solr_home solr_port
sh solr_script/solr_deply.sh stop ./solr-4.10.3-anyq 8900
# 关了之后再启动,就是重启
sh solr_script/solr_deply.sh start ./solr-4.10.3-anyq 8900
# 包含处理collection1的数据的启动
sh solr_script/anyq_solr.sh solr_script/sample_docs
成功的尝试
不过默认的solr是使用Djetty启动的,在solr_script/anyq_solr.sh
脚本中,其实还涉及到一个脚本
SOLR_HOME=./solr-4.10.3-anyq
SOLR_SERVER=${SCRIPT_PATH}/solr_deply.sh
SOLR_PORT=8900
#start
/bin/bash ${SOLR_SERVER} start ${SOLR_HOME} ${SOLR_PORT}
/solr_deply.sh
这个脚本,其内容:
function help() {
echo "usage: sh solr_deply.sh start solr_home solr_port"
echo " sh solr_deply.sh stop solr_home solr_port"
}
参考刚刚看到的当使用重启命令,必须传入当初启动时的所有参数。Solr重启之前将被关闭。如果没有节点正在运行,restart将跳过关闭,直接启动Solr。
,个人理解就是关闭就是完全杀掉,杀了之后启动,就是重启。。和电脑关机开机=重启,一个道理。试一下。
关闭solr
由于上面这个脚本文件使用的时候已经从tools
文件夹复制到了build/solr_script
文件夹中,所以直接
cd build/solr_script
# sh solr_deply.sh stop solr_home solr_port
sh solr_deply.sh stop ./solr-4.10.3-anyq 8900
然后报错了。。。我都是root用户了,没法使用sudo,后来想到应该是路径有问题。
应该是
cd build
# sh solr_deply.sh stop solr_home solr_port
sh solr_script/solr_deply.sh stop ./solr-4.10.3-anyq 8900
然后就成功了,这时候再去访问http://XXXX:8900/solr/#/collection1
就什么都没有了。之前就算关了run_server
也有,所以run_server
和solr其实是两套服务。
启动solr
还是在关闭命令执行的那个目录下,命令差不多,stop改成start就好了。
sh solr_script/solr_deply.sh start ./solr-4.10.3-anyq 8900
> nohup: appending output to ‘nohup.out’
solr[8900] start success!
启动时提示的内容和当初直接sh solr_script/anyq_solr.sh solr_script/sample_docs
的内容差不多,不过报错了,但是不是之前找不到配置文件的错误了。
参考:Caused by: org.apache.solr.common.SolrException: Index locked for write for core 正解✅
找到./build/solr-4.10.3-anyq/example/solr/mask_core/data/index
,其中有一个write.data
文件,删除,然后重启Solr即可。重启之后正确,而且可以看到新创建的mask_core
这个solrcore
了。
因为是直接复制的collection1这个文件夹,所以数据是一模一样的
部分正确,部分错误的解决
尝试直接执行包含数据读取的启动脚本,无效。后发现是因为该脚本中写死了参数:
ENGINE_NAME=collection1
SOLR_CONF=$SOLR_HOME/example/solr/collection1/conf
所以如果要构建多个solrCore,比如我的第二个solrcore叫mask_core
(是一个和口罩相关的faq集合)。那么就需要把这个脚本文件复制一份,改掉里面的部分内容。 或者不执行这个脚本
💢无效!尝试解决
cd build
# 先关闭
sh solr_script/solr_deply.sh stop ./solr-4.10.3-anyq 8900
# 然后不执行启动,而是直接执行
sh solr_script/anyq_solr.sh solr_script/sample_docs
> faq-file trans done
nohup: appending output to ‘nohup.out’
solr[8900] start success!
[{'indexed': True, 'stored': True, 'type': 'text_multi_lang', 'name': 'question'}, {'indexed': False, 'stored': True, 'type': 'string', 'name': 'answer'}]
{
"responseHeader":{
"status":0,
"QTime":104}}
{"responseHeader":{"status":0,"QTime":73}}
{"responseHeader":{"status":0,"QTime":133}}
upload file success
无效,那就应该是别的原因造成的锁定。
💢失败的尝试
在anyq的构建中,有以下代码:
# 获取anyq定制solr,anyq示例配置
cp ../tools/anyq_deps.sh .
sh anyq_deps.sh #下载solr-4.10.2-anqy的下载包并解压
# 启动solr, 依赖python-json, jdk>=1.8
cp ../tools/solr -rp solr_script
sh solr_script/anyq_solr.sh solr_script/sample_docs
所以重启就重新运行以下这个脚本就好了,但是重新运行的时候显示java又找不到了。。
cd /home
export PATH=`pwd`/jdk1.8.0_171/bin:$PATH
java -version
但是其实那个脚本里是启动命令,而不是重启命令
SOLR_HOME=./solr-4.10.3-anyq
SOLR_SERVER=${SCRIPT_PATH}/solr_deply.sh
SOLR_PORT=8900
#start
/bin/bash ${SOLR_SERVER} start ${SOLR_HOME} ${SOLR_PORT}
没有找到很正确的重启方式,那就去创建这个丢失的文件好了,参考1.2.4,然后失败,继续回来,还是要重启
重新考虑重启,参考:solr 常用命令
bin/solr restart -help
当使用重启命令,必须传入当初启动时的所有参数。Solr重启之前将被关闭。如果没有节点正在运行,restart将跳过关闭,直接启动Solr。
去自己安装的solr的bin目录下看一下好了,输入上面的帮助命令,确实显示了一些信息:
Usage: solr restart [-f] [-c] [-h hostname] [-p port] [-d directory] [-z zkHost] [-m memory] [-e example] [-s solr.solr.home] [-a "additional-options"] [-V]
-f Start Solr in foreground; default starts Solr in the background
and sends stdout / stderr to solr-PORT-console.log
-c or -cloud Start Solr in SolrCloud mode; if -z not supplied, an embedded ZooKeeper
instance is started on Solr port+1000, such as 9983 if Solr is bound to 8983
-h <host> Specify the hostname for this Solr instance
但是这里有个问题,直接在前台启动solr。
2.3 直接复制collection1文件夹,然后再配置
第一步,复制整个文件夹
# 迭代复制,会把这个文件夹中所有内容都复制过去的,
# 目标文件夹不存在会自动创建的
cp -r ./collection1 ./mask_core
第二步,修改mask_core
文件夹下core.properties
中
name=collection1
# 改为
name=mask_core
💢第三步,重启包含solr的服务,也就是重启solr,参考:AnyQ如何配置solr动态读取数据库——AnyQ系列之二,根据下面博主回答的评论,感觉可以尝试一下。这个重启方式错误,反正还是要重启
3. 正确路径
3.1 总结2(正确方式)
第一步,复制/home/Anyq-master/build/solr-4.10.3-anyq/example/solr
中的整个collection1
文件夹,比如新起的solrcore名称为mask_core,则就复制到同级目录
# 迭代复制,会把这个文件夹中所有内容都复制过去的,
# 目标文件夹不存在会自动创建的
cp -r ./collection1 ./mask_core
第二步,修改mask_core
文件夹下core.properties
中
name=collection1
# 改为
name=mask_core
第三步,重启
cd /home/AnyQ-master/build/
# sh solr_deply.sh stop solr_home solr_port
sh solr_script/solr_deply.sh stop ./solr-4.10.3-anyq 8900
# 关了之后再启动,就是重启
sh solr_script/solr_deply.sh start ./solr-4.10.3-anyq 8900
# 包含处理collection1的数据的启动(一般不建议使用)
sh solr_script/anyq_solr.sh solr_script/sample_docs
第四步,如果第三步执行后,启动solr界面报错SolrException: Index locked for write for core
,类似下面:
那么可以参考:Caused by: org.apache.solr.common.SolrException: Index locked for write for core 正解✅
找到./build/solr-4.10.3-anyq/example/solr/mask_core/data/index
,其中有一个write.data
文件,删除,然后重启Solr即可。重启之后就可以看到新创建的mask_core
这个solrcore
了。
碎碎念
一条一条加进去,如果有问题的话,直接搜索solr数据全量更新和增量更新。(虽然我现在也不理解,为什么17年的时候,AnyQ团队要选solr而不是ES,github的issue上也有人问能不能换成ES,🤐🤐)
- AnyQ如何配置solr动态读取数据库——AnyQ系列之二
- Solr的基本使用
- AnyQ solr一键启动
- https://github.com/baidu/AnyQ/blob/master/tools/solr/sample_docs
- solr系列3——solr数据同步(全量、增量)
- Solr 16 - Solr中添加、更新、删除数据的几种方式 (在URL上或Web页面中操作)
- solr 的全量更新与增量更新
3.2 按照anyq的方式初始化时批量加入自己的数据
3.2.1 anyq使用faq数据集的方式
打开这个anys_solr.sh
脚本文件,可以看到:
# 前面定义了下面的这些
#start
/bin/bash ${SOLR_SERVER} start ${SOLR_HOME} ${SOLR_PORT}
# set schema
python ${SOLR_API} set_schema ${ENGINE_HOST} ${ENGINE_NAME} ${SCHEMA_FILE} ${SOLR_PORT}
# clear docs
python ${SOLR_API} clear_doc ${ENGINE_HOST} ${ENGINE_NAME} ${SOLR_PORT}
# upload docs
python ${SOLR_API} upload_doc ${ENGINE_HOST} ${ENGINE_NAME} ${SOLR_PORT} ${FAQ_JSON}
其中,关于默认示例中的faq数据集,其实在这个脚本文件中有:
mkdir -p faq
SCHEMA_FILE=`pwd`/faq/schema_format
FAQ_JSON=`pwd`/faq/faq_json
python ${SCRIPT_PATH}/make_json.py $FAQ_FILE $SCHEMA_FILE $FAQ_JSON
其中,这个sh脚本是在./build
目录中运行的,所以pwd
指的就是build
目录,所以要找到那个faq_json
文件,其完整目录是/home/AnyQ-master/build/faq/faq_json
。文件内容形式如下:
(就是这个顺序。。答案,然后问题,然后序号。。)
{
"answer": "您需要拥有一个百度账号,用来登录百度云,可以点击此处注册百度账户。如您以前拥有百度推广账户,同样可以登录百度云。",
"question": "需要使用什么账号登录?",
"id": "1"
}
{
"answer": "由于欠费停机、存储信息已满、信号网络延迟等原因没有及时收到验证码,这时请检查您的手机及话费余额,保证手机可正常接收短信后,请尝试重新获取验证码。",
"question": "注册百度账户时收不到验证码怎么办?",
"id": "2"
}
所以不难得出整个逻辑:
mkdir -p faq
在当前执行目录,即build/
文件夹下创建faq
目录- 定义两个变量
SCHEMA_FILE=`pwd`/faq/schema_format FAQ_JSON=`pwd`/faq/faq_json
- 执行将doc文档转换为faq_json的脚本,
python ${SCRIPT_PATH}/make_json.py $FAQ_FILE $SCHEMA_FILE $FAQ_JSON
- 主要就是
AnyQ-master\tools\solr
文件夹中的make_json.py
脚本,其会接收调用时参数,然后读取对应的文件,并将其转换为一定的格式SCRIPT_PATH=$(dirname $0) FAQ_FILE=$1 # 就是sh执行时候传入的第一个参数,就是这里的 solr_script/sample_docs SCHEMA_FILE=`pwd`/faq/schema_format FAQ_JSON=`pwd`/faq/faq_json # 最后保存的名称 python ${SCRIPT_PATH}/make_json.py $FAQ_FILE $SCHEMA_FILE $FAQ_JSON
sh solr_script/anyq_solr.sh solr_script/sample_docs
- 所以如果要换自己的数据集,就重新指定一下sample_docs,或者直接替换掉其中的内容。
如果要将新上传的数据切换到mask_core而不是默认的collection1中,还需要注意:anyq_solr.sh
这个脚本中写死了参数:
ENGINE_NAME=collection1
SOLR_CONF=$SOLR_HOME/example/solr/collection1/conf
所以如果要构建多个solrCore,比如我的第二个solrcore叫mask_core
(是一个和口罩相关的faq集合)。那么就需要把这个脚本文件复制一份,改掉里面的部分内容。
3.2.2 删除solrcore中的数据
如果想要完全更新mask_core的数据,首先需要清空目前mask_core中从collection1中复制过来的数据。
<!-- 删除全部, 慎用 -->
<delete>
<query>:</query>
</delete>
<commit/>
3.3 修改脚本以自己的数据作为solr启动时
3.3.1 整理数据格式
要保证自己的数据形式与AnyQ-master/tools/solr/sample_docs
中数据格式一致,其格式其实是以tab
分割的csv文件。
得到了一个关于口罩的问答数据集,有100个问答对。
注意:
- question或者answer内容中都不要有换行符,
make_json.py
文件写的比较简单。如下:
有换行符的话,读行的时候,就会读错,所以如果有换行符的话,要提前处理掉。- 注意,如果在windows上,默认open用的是GBK编码,但是如果是linux上,则是utf-8,保存的时候需要保证是utf-8的格式
- windows下处理的文件,最后一行会是一个换行符,要手动删除,不然也会报错
line error
def run(faq_file_str, format_file_str, json_file_str):
"""
convert text file to json file, save schema file
"""
idx = 0
header = 0
field_cnt = 0
auto_id = False
faq_file = open(faq_file_str, "r")
for line in faq_file:
arr = line.strip().split('\t')
if header == 0:
header = 1
field_names = arr
field_cnt = len(field_names)
if 'question' not in field_names or 'answer' not in field_names:
print >> sys.stderr, "need question and answer"
sys.exit(6)
if 'id' not in field_names:
auto_id = True
write_format_file(field_names, format_file_str)
json_file = open(json_file_str, "w")
continue
if len(arr) != field_cnt:
print >> sys.stderr, "line error"
continue
idx += 1
data = dict([field_names[i], arr[i]] for i in range(field_cnt))
if auto_id:
data['id'] = str(idx)
json_file.write(json.dumps(data, ensure_ascii=False))
json_file.write("\n")
json_file.close()
faq_file.close()
3.3.2 上传文件
- 为了防止出错,之前的容器被破坏,所以新开了一个容器。anyq-trace
- 如果docker没有映射本地文件,那么可以直接
vi mask_docs
,然后把刚刚的内容复制上去
注意,复制过去的时候,前四个字符都会丢失,也就是
question
会显示为tion
。。。需要手动调整一下。
3.3.3 不修改solrcore,只是修改上传的文件**
- 注意之前的
sample_docs
是没有格式后缀的,所以这里也删除后缀,上传到镜像和sample_docs
同级目录中。 - 接下来执行:
cp ../tools/solr -rp solr_script # 所以之前tools/solr中的脚本文件已经被复制到了build/solr_script中了 sh solr_script/anyq_solr.sh solr_script/mask_docs
- 执行成功,则提示:
- 可以访问solr界面,查看一下当前collection1中的数据,可以看到:不是16个了,而是100个,所以重新执行其实是清空了collection的数据,再新加入。
- 同时,查看
schema Browser
,可以看到,关于question
,已经变成了当前这个FAQ数据集相关的内容。
- 然后访问faq服务,问问题,观察返回的内容。可以看到,后台打印出的log
- 所以直接替换自己的FAQ集是完全没问题的
3.3.4 上传数据到另一个solr_core中
上面已经验证了替换FAQ数据的可行性,这次上传数据到新的solr_core中,尝试一下结果。
进行以下操作:
1.还是新建一个mask_docs
,把处理好的faq数据复制进去的
2. 复制anyq_solr.sh
文件得到anyq_solr_mask
,并修改
cp anyq_solr.sh ./anyq_solr_mask.sh
# 将文件中所有的collection1改为mask_core
ENGINE_NAME=collection1
SOLR_CONF=$SOLR_HOME/example/solr/collection1/conf
注意观察,自己的solr-4.10.3-anyq/example/solr
文件夹中,除了collection1之外,是否已经新建过sorlcore了,比如,我这里新建的就是mask_core
3. 启动solr服务并读入mask_docs
数据
sh solr_script/anyq_solr_mask.sh solr_script/mask_docs
提示:
生成的中间文件faq_json
就位于build/faq/faq_json
中,除非把脚本中保存文件的名称改掉。
(注意,这个一旦上传成功,solr中就会一直保存着,因为已经在对应的solr_core存储成了data,所以后续可以直接启动solr服务,不用再读入数据了)
4. 打开solr的UI界面,刷新,可以看到,确实上传到了mask_core中,同时schema browser
中查看question
字段,显示也和1.5.3中相同
5. 启动faq服务,
失败,所以还是需要去看AnyQ中关于FAQ部分的实现逻辑,应该是哪里指定了collection1这个solrcore。
3.3.5 解决1.5.4的问题
根据百度AnyQ之五——FAQ部分逻辑理解中2. 执行时打印的log信息
的第六步和第七步,可知,需要进行配置才能够在粗排阶段(即solr的关键词检索阶段,使用mask_core,而不是collection1)
将build/example/conf/retrieval.conf
文件中的engine_name
从collection1
改为mask_core
。
retrieval_plugin {
name : "term_recall_1"
type : "TermRetrievalPlugin"
search_host : "127.0.0.1"
search_port : 8900
engine_name : "collection1"
在上面已经向mask_core中加入数据的基础上,直接执行./run_server
进行测试。可以看到,已经修改成功了
结果也还不错,OK
4. 和mysql连接 💢(放弃)
参考:
- Solr 07 - Solr从MySQL数据库中导入数据 (Solr DIH的使用示例)
- Solr Linux 导入Mysql数据
- linux下MySQL数据库的安装和solr配置
- linux下mysql的安装与使用
网上大部分都会用到tomcat,不过我并不希望使用tomcat,所以主要参考上面第二个进行操作。
4.1 安装mysql
# 1.检测系统自带Mysql,并卸载
$ rpm -qa | grep mysql
mysql-libs-5.1.66-2.el6_3.x86_64
[root@hadoop eclipse]# rpm -e mysql-libs-5.1.66-2.el6_3.x86_64 --nodeps
# 2.通过网络安装MySQL (yum)
$ yum -y install mysql mysql-devel mysql-server
# 3.启动服务
# service mysqld start
开机自启动
# chkconfig mysqld on
# 4.设置用户和密码
#/usr/bin/mysqladmin -uroot password 'root'
# 5.进入
mysql -uroot -p123456
# 6.查看mysql用户
select host,user,password from mysql.user;
# 7.修改远程访问权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
# 8.重载授权表:
FLUSH PRIVILEGES;
后来考虑了一下,数据库配置似乎略显麻烦,如果可以直接使用solr本身的data做暂存,其实没必要再引入数据库,多一部分,维护就多一个麻烦。减少引入的组件,挺好的。
5. github上一些相关的issue
从代码里可以看道http接口方法
/anyq => anyq,"
“/solr/v1/delete => solr_delete,”
“/solr/v1/insert => solr_insert,”
“/solr/v1/update => solr_update,”
“/solr/v1/clear => solr_clear”
这些表情可能包含某些需要转义的字符,可自行转义,加入src/common/utils.cpp中的escape。