热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

全文检索引擎Solr部署与基本原理

全文检索引擎Solr部署与基本原理搜索引擎Solr环境搭建实例关于solr,schema.xml的配置说明全文检索引擎Solr系列—–全文检索基本原理一、搜索引擎Solr环境搭建

 全文检索引擎 Solr 部署与基本原理

 

 

  •  搜索引擎Solr环境搭建实例

  • 关于 solr , schema.xml 的配置说明

  • 全文检索引擎Solr系列—–全文检索基本原理

 

一、搜索引擎Solr环境搭建实例

Solr服务器采用java5开发的,是基于Lucene全文搜索的。要想搭建Solr,首先进行java环境的配置,安装对应的jdk以及tomcat,在此就不多讲。

以下是在jdk1.7和tomcat1.7的环境下搭建最新版本的solr4.10.3。

具体步骤如下:

1.到官网http://lucene.apache.org/solr/mirrors-solr-latest-redir.html下载.

2.建目录/webapps/mysolr/solr

3.解压压缩包solr-4.10.3,找到example下的webapps中的solr.war包,并将其解压。

4.将解压完的war包(solr文件夹)拷贝到第2步建的目录:/webapps/mysolr下

5.拷贝两个地方的jar包到/webapps/mysolr/solr/WEB-INF/lib下

(1)example下lib包的所有jar包

(2)example下lib包下的ext包中的所有jar包

6.拷贝example/resource下的log4j.properties文件到/webapps/mysolr/solr/classpath 下

7.solrhome的配置:

先创建一个solrhome目录:/webapps/mysolr/solrhome,然后将example/solr下的所有文件拷贝到/webapps/mysolr/solrhome下

然后修改配置文件/webapps/mysolr/solr/WEB-INF/web.xml,将solr/home的注解放开并配置如下:

<env-entry> 
<env-entry-name>solr/homeenv-entry-name>
<env-entry-value>/webapps/mysolr/solrhomeenv-entry-value>
<env-entry-type>java.lang.Stringenv-entry-type>
env-entry>

 

8.把/webapps/mysolr/solr部署到tomcat下,并启动tomcat。

以上就完成了solr环境的基本搭建,访问http://loclhost:8080/solr  可看到如下界面:

 

 

Solr3.6.1 在Tomcat6下的环境搭建 http://www.cnblogs.com/chinway/p/6187260.html

基于Tomcat的Solr3.5集群部署 http://www.cnblogs.com/chinway/p/6187271.html

在Linux上使用Nginx为Solr集群做负载均衡 http://www.cnblogs.com/chinway/p/6187292.html

Linux下安装使用Solr http://www.cnblogs.com/chinway/p/6187322.html

Solr实现Low Level查询解析(QParser) http://www.cnblogs.com/chinway/p/6187332.html

Solr 4.0 部署实例教程 http://www.cnblogs.com/chinway/p/6187382.html

 

二、 关于 solr , schema.xml 的配置说明

schema.xml位于solr/conf/目录下,类似于数据表配置文件,

定义了加入索引的数据的数据类型,主要包括type、fields和其他的一些缺省设置。

 

1、先来看下type节点,这里面定义FieldType子节点,包括name,class,positionIncrementGap等一些参数。

  • name:就是这个FieldType的名称。
  • class:指向org.apache.solr.analysis包里面对应的class名称,用来定义这个类型的行为。
 1 < schema name = "example" version = "1.2" >
2 < types >
3 < fieldType name = "string" class = "solr.StrField" sortMissingLast = "true" omitNorms = "true" />
4 < fieldType name = "boolean" class = "solr.BoolField" sortMissingLast = "true" omitNorms = "true" />
5 < fieldtype name = "binary" class = "solr.BinaryField" />
6 < fieldType name = "int" class = "solr.TrieIntField" precisionStep = "0" omitNorms = "true"
7 positionIncrementGap = "0" />
8 < fieldType name = "float" class = "solr.TrieFloatField" precisionStep = "0" omitNorms = "true"
9 positionIncrementGap = "0" />
10 < fieldType name = "long" class = "solr.TrieLongField" precisionStep = "0" omitNorms = "true"
11 positionIncrementGap = "0" />
12 < fieldType name = "double" class = "solr.TrieDoubleField" precisionStep = "0" omitNorms = "true"
13 positionIncrementGap = "0" />
14 ...
15 types >
16 ...
17 schema >

必要的时候fieldType还需要自己定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤,如下:

 1 < fieldType name = "text_ws" class = "solr.TextField" positionIncrementGap = "100" >
2 < analyzer >
3 < tokenizer class = "solr.WhitespaceTokenizerFactory" />
4 analyzer >
5 fieldType >
6 < fieldType name = "text" class = "solr.TextField" positionIncrementGap = "100" >
7 < analyzer type = "index" >
8
12 < tokenizer class = "solr.WhitespaceTokenizerFactory" />
13
17
21 < filter class = "solr.StopFilterFactory"
22 ignoreCase = "true"
23 words = "stopwords.txt"
24 enablePositionIncrements = "true"
25 />
26 < filter class = "solr.WordDelimiterFilterFactory" generateWordParts = "1"
27 generateNumberParts = "1" catenateWords = "1" catenateNumbers = "1"
28 catenateAll = "0" splitOnCaseChange = "1" />
29 < filter class = "solr.LowerCaseFilterFactory" />
30 < filter class = "solr.SnowballPorterFilterFactory" language = "English"
31 protected = "protwords.txt" />
32 analyzer >
33 < analyzer type = "query" >
34 < tokenizer class = "solr.WhitespaceTokenizerFactory" />
35 < filter class = "solr.SynonymFilterFactory" synonyms = "synonyms.txt" ignoreCase = "true"
36 expand = "true" />
37 < filter class = "solr.StopFilterFactory"
38 ignoreCase = "true"
39 words = "stopwords.txt"
40 enablePositionIncrements = "true"
41 />
42 < filter class = "solr.WordDelimiterFilterFactory" generateWordParts = "1"
43 generateNumberParts = "1" catenateWords = "0" catenateNumbers = "0"
44 catenateAll = "0" splitOnCaseChange = "1" />
45 < filter class = "solr.LowerCaseFilterFactory" />
46 < filter class = "solr.SnowballPorterFilterFactory" language = "English"
47 protected = "protwords.txt" />
48 analyzer >
49 fieldType >

2、再来看下fields节点内定义具体的字段(类似数据库的字段),含有以下属性:

  • name:字段名
  • type:之前定义过的各种FieldType
  • indexed:是否被索引
  • stored:是否被存储(如果不需要存储相应字段值,尽量设为false)
  • multiValued:是否有多个值(对可能存在多值的字段尽量设置为true,避免建索引时抛出错误)
 1 < fields >
2 < field name = "id" type = "integer" indexed = "true" stored = "true" required = "true" />
3 < field name = "name" type = "text" indexed = "true" stored = "true" />
4 < field name = "summary" type = "text" indexed = "true" stored = "true" />
5 < field name = "author" type = "string" indexed = "true" stored = "true" />
6 < field name = "date" type = "date" indexed = "false" stored = "true" />
7 < field name = "content" type = "text" indexed = "true" stored = "false" />
8 < field name = "keywords" type = "keyword_text" indexed = "true" stored = "false" multiValued = "true" />
9
10 < field name = "all" type = "text" indexed = "true" stored = "false" multiValued = "true" />
11 fields >

3、建议建立一个拷贝字段,将所有的 全文本 字段复制到一个字段中,以便进行统一的检索:

以下是拷贝设置:

1 < copyField source = "name" dest = "all" />
2 < copyField source = "summary" dest = "all" />

4、动态字段,没有具体名称的字段,用dynamicField字段

如:name为*_i,定义它的type为int,那么在使用这个字段的时候,任务以_i结果的字段都被认为符合这个定义。如name_i, school_i

1 < dynamicField name = "*_i" type = "int" indexed = "true" stored = "true" />
2 < dynamicField name = "*_s" type = "string" indexed = "true" stored = "true" />
3 < dynamicField name = "*_l" type = "long" indexed = "true" stored = "true" />
4 < dynamicField name = "*_t" type = "text" indexed = "true" stored = "true" />
5 < dynamicField name = "*_b" type = "boolean" indexed = "true" stored = "true" />
6 < dynamicField name = "*_f" type = "float" indexed = "true" stored = "true" />
7 < dynamicField name = "*_d" type = "double" indexed = "true" stored = "true" />
8 < dynamicField name = "*_dt" type = "date" indexed = "true" stored = "true" />

schema.xml文档注释中的信息:

 1、为了改进性能,可以采取以下几种措施:

  • 将所有只用于搜索的,而不需要作为结果的field(特别是一些比较大的field)的stored设置为false
  • 将不需要被用于搜索的,而只是作为结果返回的field的indexed设置为false
  • 删除所有不必要的copyField声明
  • 为了索引字段的最小化和搜索的效率,将所有的 text fields的index都设置成field,然后使用copyField将他们都复制到一个总的 text field上,然后对他进行搜索。
  • 为了最大化搜索效率,使用java编写的客户端与solr交互(使用流通信)
  • 在服务器端运行JVM(省去网络通信),使用尽可能高的Log输出等级,减少日志量。

2、

  • name:标识这个schema的名字
  • version:现在版本是1.2

3、filedType

 

1 < fieldType name =" string " class =" solr.StrField " sortMissingLast =" true " omitNorms =" true " />
  • name:标识而已。
  • class和其他属性决定了这个fieldType的实际行为。(class以solr开始的,都是在org.appache.solr.analysis包下)

可选的属性:

  • sortMissingLast和sortMissingFirst两个属性是用在可以内在使用String排序的类型上(包括:string,boolean,sint,slong,sfloat,sdouble,pdate)。
  • sortMissingLast="true",没有该field的数据排在有该field的数据之后,而不管请求时的排序规则。
  • sortMissingFirst="true",跟上面倒过来呗。
  • 2个值默认是设置成false

 StrField类型不被分析,而是被逐字地索引/存储。

StrField和TextField都有一个可选的属性“compressThreshold”,保证压缩到不小于一个大小(单位:char)

1  < fieldType name =" text " class =" solr.TextField " positionIncrementGap =" 100 " >

 solr.TextField 允许用户通过分析器来定制索引和查询,分析器包括一个分词器(tokenizer)和多个过滤器(filter)

   

  • positionIncrementGap:可选属性,定义在同一个文档中此类型数据的空白间隔,避免短语匹配错误。

 

  name: 字段类型名
  class: java类名
  indexed: 缺省true。 说明这个数据应被搜索和排序,如果数据没有indexed,则stored应是true。
  stored: 缺省true。说明这个字段被包含在搜索结果中是合适的。如果数据没有stored,则indexed应是true。
  sortMissingLast: 指没有该指定字段数据的document排在有该指定字段数据的document的后面
  sortMissingFirst: 指没有该指定字段数据的document排在有该指定字段数据的document的前面
  omitNorms: 字段的长度不影响得分和在索引时不做boost时,设置它为true。一般文本字段不设置为true。
  termVectors: 如果字段被用来做more like this 和highlight的特性时应设置为true。
  compressed: 字段是压缩的。这可能导致索引和搜索变慢,但会减少存储空间,只有StrField和TextField是可以压缩,这通常适合字段的长度超过200个字符。
  multiValued: 字段多于一个值的时候,可设置为true。
  positionIncrementGap: 和multiValued
一起使用,设置多个值之间的虚拟空白的数量

1  < tokenizer class =" solr.WhitespaceTokenizerFactory " />

空格分词,精确匹配。

1  < filter class =" solr.WordDelimiterFilterFactory " generateWordParts =" 1 " generateNumberParts =" 1 " catenateWords =" 1 " catenateNumbers =" 1 " catenateAll =" 0 " splitOnCaseChange =" 1 " />

在分词和匹配时,考虑 "-"连字符,字母数字的界限,非字母数字字符,这样 "wifi"或"wi fi"都能匹配"Wi-Fi"。

 

1 < filter class =" solr.SynonymFilterFactory " synonyms =" synonyms.txt " ignoreCase =" true " expand =" true " />

同义词

1  < filter class =" solr.StopFilterFactory " ignoreCase =" true " words =" stopwords.txt " enablePositionIncrements =" true " />

在禁用字(stopword)删除后,在短语间增加间隔

stopword:即在建立索引过程中(建立索引和搜索)被忽略的词,比如is this等常用词。在conf/stopwords.txt维护。

 4、fields

 

1 < field name =" id " type =" string " indexed =" true " stored =" true " required =" true " />

 

  • name:标识而已。
  • type:先前定义的类型。
  • indexed:是否被用来建立索引(关系到搜索和排序)
  • stored:是否储存
  • compressed:[false],是否使用gzip压缩(只有TextField和StrField可以压缩)
  • mutiValued:是否包含多个值
  • omitNorms:是否忽略掉Norm,可以节省内存空间,只有全文本field和need an index-time boost的field需要norm。(具体没看懂,注释里有矛盾)
  • termVectors:[false],当设置true,会存储 term vector。当使用MoreLikeThis,用来作为相似词的field应该存储起来。
  • termPositions:存储 term vector中的地址信息,会消耗存储开销。
  • termOffsets:存储 term vector 的偏移量,会消耗存储开销。
  • default:如果没有属性需要修改,就可以用这个标识下。

 

包罗万象(有点夸张)的field,包含所有可搜索的text fields,通过copyField实现。

 

在添加索引时,将所有被拷贝field(如cat)中的数据拷贝到text field中

作用:

  • 将多个field的数据放在一起同时搜索,提供速度
  • 将一个field的数据拷贝到另一个,可以用2种不同的方式来建立索引。

 

 如果一个field的名字没有匹配到,那么就会用动态field试图匹配定义的各种模式。

  • "*"只能出现在模式的最前和最后
  • 较长的模式会被先去做匹配
  • 如果2个模式同时匹配上,最先定义的优先
1  < dynamicField name =" * " type =" ignored " multiValued=" true " />

如果通过上面的匹配都没找到,可以定义这个,然后定义个type,当String处理。(一般不会发生)

但若不定义,找不到匹配会报错。

 5、其他一些标签

 

1 < uniqueKey > id  uniqueKey >

 

文档的唯一标识, 必须填写这个field(除非该field被标记required="false"),否则solr建立索引报错。

< defaultSearchField > text  defaultSearchField >

如果搜索参数中没有指定具体的field,那么这是默认的域。

1 < solrQueryParser defaultOperator =" OR " />

配置搜索参数短语间的逻辑,可以是"AND|OR"。

 

Solr3.6.1 在Tomcat6下的环境搭建 http://www.cnblogs.com/chinway/p/6187260.html

基于Tomcat的Solr3.5集群部署 http://www.cnblogs.com/chinway/p/6187271.html

在Linux上使用Nginx为Solr集群做负载均衡 http://www.cnblogs.com/chinway/p/6187292.html

Linux下安装使用Solr http://www.cnblogs.com/chinway/p/6187322.html

Solr实现Low Level查询解析(QParser) http://www.cnblogs.com/chinway/p/6187332.html

Solr 4.0 部署实例教程 http://www.cnblogs.com/chinway/p/6187382.html

 

 

三、全文检索引擎Solr系列—–全文检索基本原理

新华字典,我们都使用过,如叫你翻开第38页,找到“坑爹”所在的位置,此时你会怎么查呢?毫无疑问,你的眼睛会从38页的第一个字开始从头至尾地扫描,直到找到“坑爹”二字为止。这种搜索方法叫做顺序扫描法。对于少量的数据,使用顺序扫描是够用的。但是妈妈叫你查出坑爹的“坑”字在哪一页时,你要是从第一页的第一个字逐个的扫描下去,那你真的是被坑了。此时你就需要用到索引。索引记录了“坑”字在哪一页,你只需在索引中找到“坑”字,然后找到对应的页码,答案就出来了。因为在索引中查找“坑”字是非常快的,因为你知道它的偏旁,因此也就可迅速定位到这个字。

那么新华字典的目录(索引表)是怎么编写而成的呢?首先对于新华字典这本书来说,除去目录后,这本书就是一堆没有结构的数据集。但是聪明的人类善于思考总结,发现每个字都会对应到一个页码,比如“坑”字就在第38页,“爹”字在第90页。于是他们就从中提取这些信息,构造成一个有结构的数据。类似数据库中的表结构:

word    page_no
---------------
坑 38
爹 90
... ...

这样就形成了一个完整的目录(索引库),查找的时候就非常方便了。对于全文检索也是类似的原理,它可以归结为两个过程:1.索引创建(Indexing)2. 搜索索引(Search)。那么索引到底是如何创建的呢?索引里面存放的又是什么东西呢?搜索的的时候又是如何去查找索引的呢?带着这一系列问题继续往下看。

索引

Solr/Lucene采用的是一种反向索引,所谓反向索引:就是从关键字到文档的映射过程,保存这种映射这种信息的索引称为反向索引

  • 左边保存的是字符串序列
  • 右边是字符串的文档(Document)编号链表,称为倒排表(Posting List)

字段串列表和文档编号链表两者构成了一个字典。现在想搜索”lucene”,那么索引直接告诉我们,包含有”lucene”的文档有:2,3,10,35,92,而无需在整个文档库中逐个查找。如果是想搜既包含”lucene”又包含”solr”的文档,那么与之对应的两个倒排表去交集即可获得:3、10、35、92。

索引创建

假设有如下两个原始文档:
文档一:Students should be allowed to go out with their friends, but not allowed to drink beer.
文档二:My friend Jerry went to school to see his students but found them drunk which is not allowed.
创建过程大概分为如下步骤:

一:把原始文档交给分词组件(Tokenizer)
分词组件(Tokenizer)会做以下几件事情(这个过程称为:Tokenize),处理得到的结果是词汇单元(Token)

  1. 将文档分成一个一个单独的单词
  2. 去除标点符号
  3. 去除停词(stop word)
    • 所谓停词(Stop word)就是一种语言中没有具体含义,因而大多数情况下不会作为搜索的关键词,这样一来创建索引时能减少索引的大小。英语中停词(Stop word)如:”the”、”a”、”this”,中文有:”的,得”等。不同语种的分词组件(Tokenizer),都有自己的停词(stop word)集合。经过分词(Tokenizer)后得到的结果称为词汇单元(Token)。上例子中,便得到以下词汇单元(Token)
      "Students","allowed","go","their","friends","allowed","drink","beer","My","friend","Jerry","went","school","see","his","students","found","them","drunk","allowed"

二:词汇单元(Token)传给语言处理组件(Linguistic Processor)
语言处理组件(linguistic processor)主要是对得到的词元(Token)做一些语言相关的处理。对于英语,语言处理组件(Linguistic Processor)一般做以下几点:

  1. 变为小写(Lowercase)。
  2. 将单词缩减为词根形式,如”cars”到”car”等。这种操作称为:stemming。
  3. 将单词转变为词根形式,如”drove”到”drive”等。这种操作称为:lemmatization。

语言处理组件(linguistic processor)处理得到的结果称为词(Term),例子中经过语言处理后得到的词(Term)如下:

"student","allow","go","their","friend","allow","drink","beer","my","friend","jerry","go","school","see","his","student","find","them","drink","allow"。

经过语言处理后,搜索drive时drove也能被搜索出来。Stemming 和 lemmatization的异同:

  • 相同之处:
    1. Stemming和lemmatization都要使词汇成为词根形式。
  • 两者的方式不同:
    1. Stemming采用的是”缩减”的方式:”cars”到”car”,”driving”到”drive”。
    2. Lemmatization采用的是”转变”的方式:”drove”到”drove”,”driving”到”drive”。
  • 两者的算法不同:
    1. Stemming主要是采取某种固定的算法来做这种缩减,如去除”s”,去除”ing”加”e”,将”ational”变为”ate”,将”tional”变为”tion”。
    2. Lemmatization主要是采用事先约定的格式保存某种字典中。比如字典中有”driving”到”drive”,”drove”到”drive”,”am, is, are”到”be”的映射,做转变时,按照字典中约定的方式转换就可以了。
    3. Stemming和lemmatization不是互斥关系,是有交集的,有的词利用这两种方式都能达到相同的转换。

三:得到的词(Term)传递给索引组件(Indexer)

  1. 利用得到的词(Term)创建一个字典
    Term    Document ID
    student 1
    allow 1
    go 1
    their 1
    friend 1
    allow 1
    drink 1
    beer 1
    my 2
    friend 2
    jerry 2
    go 2
    school 2
    see 2
    his 2
    student 2
    find 2
    them 2
    drink 2
    allow 2
  2. 对字典按字母顺序排序:
    Term    Document ID
    allow 1
    allow 1
    allow 2
    beer 1
    drink 1
    drink 2
    find 2
    friend 1
    friend 2
    go 1
    go 2
    his 2
    jerry 2
    my 2
    school 2
    see 2
    student 1
    student 2
    their 1
    them 2
  3. 合并相同的词(Term)成为文档倒排(Posting List)链表

  4.  

    • Document Frequency:文档频次,表示多少文档出现过此词(Term)
    • Frequency:词频,表示某个文档中该词(Term)出现过几次

对词(Term) “allow”来讲,总共有两篇文档包含此词(Term),词(Term)后面的文档链表总共有两个,第一个表示包含”allow”的第一篇文档,即1号文档,此文档中,”allow”出现了2次,第二个表示包含”allow”的第二个文档,是2号文档,此文档中,”allow”出现了1次

至此索引创建完成,搜索”drive”时,”driving”,”drove”,”driven”也能够被搜到。因为在索引中,”driving”,”drove”,”driven”都会经过语言处理而变成”drive”,在搜索时,如果您输入”driving”,输入的查询语句同样经过分词组件和语言处理组件处理的步骤,变为查询”drive”,从而可以搜索到想要的文档。

搜索步骤

搜索”microsoft job”,用户的目的是希望在微软找一份工作,如果搜出来的结果是:”Microsoft does a good job at software industry…”,这就与用户的期望偏离太远了。如何进行合理有效的搜索,搜索出用户最想要得结果呢?搜索主要有如下步骤:

一:对查询内容进行词法分析、语法分析、语言处理

  1. 词法分析:区分查询内容中单词和关键字,比如:english and janpan,”and”就是关键字,”english”和”janpan”是普通单词。
  2. 根据查询语法的语法规则形成一棵树
  3. 语言处理,和创建索引时处理方式是一样的。比如:leaned–>lean,driven–>drive

二:搜索索引,得到符合语法树的文档集合
三:根据查询语句与文档的相关性,对结果进行排序

我们把查询语句也看作是一个文档,对文档与文档之间的相关性(relevance)进行打分(scoring),分数高比较越相关,排名就越靠前。当然还可以人工影响打分,比如百度搜索,就不一定完全按照相关性来排名的。

如何评判文档之间的相关性?一个文档由多个(或者一个)词(Term)组成,比如:”solr”, “toturial”,不同的词可能重要性不一样,比如solr就比toturial重要,如果一个文档出现了10次toturial,但只出现了一次solr,而另一文档solr出现了4次,toturial出现一次,那么后者很有可能就是我们想要的搜的结果。这就引申出权重(Term weight)的概念。

权重表示该词在文档中的重要程度,越重要的词当然权重越高,因此在计算文档相关性时影响力就更大。通过词之间的权重得到文档相关性的过程叫做空间向量模型算法(Vector Space Model)

影响一个词在文档中的重要性主要有两个方面:

  • Term Frequencey(tf),Term在此文档中出现的频率,ft越大表示越重要
  • Document Frequency(df),表示有多少文档中出现过这个Trem,df越大表示越不重要
    物以希为贵,大家都有的东西,自然就不那么贵重了,只有你专有的东西表示这个东西很珍贵,权重的公式:

空间向量模型

文档中词的权重看作一个向量

Document = {term1, term2, …… ,term N}
Document Vector = {weight1, weight2, …… ,weight N}

把欲要查询的语句看作一个简单的文档,也用向量表示:

Query = {term1, term 2, …… , term N}
Query Vector = {weight1, weight2, …… , weight N}

把搜索出的文档向量及查询向量放入N维度的空间中,每个词表示一维:

夹角越小,表示越相似,相关性越大

 

Solr3.6.1 在Tomcat6下的环境搭建 http://www.cnblogs.com/chinway/p/6187260.html

基于Tomcat的Solr3.5集群部署 http://www.cnblogs.com/chinway/p/6187271.html

在Linux上使用Nginx为Solr集群做负载均衡 http://www.cnblogs.com/chinway/p/6187292.html

Linux下安装使用Solr http://www.cnblogs.com/chinway/p/6187322.html

Solr实现Low Level查询解析(QParser) http://www.cnblogs.com/chinway/p/6187332.html

Solr 4.0 部署实例教程 http://www.cnblogs.com/chinway/p/6187382.html

 


推荐阅读
  • Hadoop 2.6 主要由 HDFS 和 YARN 两大部分组成,其中 YARN 包含了运行在 ResourceManager 的 JVM 中的组件以及在 NodeManager 中运行的部分。本文深入探讨了 Hadoop 2.6 日志文件的解析方法,并详细介绍了 MapReduce 日志管理的最佳实践,旨在帮助用户更好地理解和优化日志处理流程,提高系统运维效率。 ... [详细]
  • 本文详细介绍了如何在Java Web服务器上部署音视频服务,并提供了完整的验证流程。以AnyChat为例,这是一款跨平台的音视频解决方案,广泛应用于需要实时音视频交互的项目中。通过具体的部署步骤和测试方法,确保了音视频服务的稳定性和可靠性。 ... [详细]
  • “近年来最大计算机漏洞”被中国程序员发现!
    头条中国程序员,计算机漏洞头条(观察者网讯)据美联社12月11日报道,中国阿里云安全团队在Web服务器软件阿帕奇(Apache)下的开源日志组件Log4j内,发现一个漏洞Log4S ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送www方式的数据。HTTP协议采用了请求响应模型。客服端向服务器发送一 ... [详细]
  • 用阿里云的免费 SSL 证书让网站从 HTTP 换成 HTTPS
    HTTP协议是不加密传输数据的,也就是用户跟你的网站之间传递数据有可能在途中被截获,破解传递的真实内容,所以使用不加密的HTTP的网站是不 ... [详细]
  • 如何在Linux服务器上配置MySQL和Tomcat的开机自动启动
    在Linux服务器上部署Web项目时,通常需要确保MySQL和Tomcat服务能够随系统启动而自动运行。本文将详细介绍如何在Linux环境中配置MySQL和Tomcat的开机自启动,以确保服务的稳定性和可靠性。通过合理的配置,可以有效避免因服务未启动而导致的项目故障。 ... [详细]
  • 本文深入探讨了如何利用Maven高效管理项目中的外部依赖库。通过介绍Maven的官方依赖搜索地址(),详细讲解了依赖库的添加、版本管理和冲突解决等关键操作。此外,还提供了实用的配置示例和最佳实践,帮助开发者优化项目构建流程,提高开发效率。 ... [详细]
  • 在Java应用程序中调用`response.getStatus()`方法时遇到了`NoSuchMethodError`异常,经过分析,初步判断为依赖冲突问题。通过检查项目依赖树发现,当前项目版本与某些库的版本不兼容,导致该方法无法被正确识别。建议通过更新相关依赖版本或使用依赖管理工具(如Maven或Gradle)来解决此问题,确保所有依赖项版本一致且兼容。 ... [详细]
  • MQ的使用
    安装环境:linuxredhatactivemq版本:5.8.01.从http:activemq.apache.orgdownload.html地址下载 ... [详细]
  • Hbase 的伪分布部署、shell基本操作及hbase相关理念
    1,HBase的的的的伪分布式配置-对zookeeper的配置,这个前面配置过,修改zoo.cfg文件,指定zookeeper的主入口-配置的HBase的的:进入optmo ... [详细]
  • 本文讨论了在shiro java配置中加入Shiro listener后启动失败的问题。作者引入了一系列jar包,并在web.xml中配置了相关内容,但启动后却无法正常运行。文章提供了具体引入的jar包和web.xml的配置内容,并指出可能的错误原因。该问题可能与jar包版本不兼容、web.xml配置错误等有关。 ... [详细]
  • 在JavaWeb开发中,文件上传是一个常见的需求。无论是通过表单还是其他方式上传文件,都必须使用POST请求。前端部分通常采用HTML表单来实现文件选择和提交功能。后端则利用Apache Commons FileUpload库来处理上传的文件,该库提供了强大的文件解析和存储能力,能够高效地处理各种文件类型。此外,为了提高系统的安全性和稳定性,还需要对上传文件的大小、格式等进行严格的校验和限制。 ... [详细]
  • PHP 各版本对比:标准版与最新顶级版的详细分析 ... [详细]
  • Elasticsearch简单使用系列安装
    2019独角兽企业重金招聘Python工程师标准1.elasticsearch支持的操作系统和JVM版本https:www.elastic.cosupportmatrix2. ... [详细]
author-avatar
暴君1566
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有