大数据分析处理流行技术栈
E(elasticsearch)L(logstash)K(Kibana)技术栈
Easticsearch
# docker安装ES
安装直接用docker。
docker pull registry.docker-cn.com/library/elasticsearch
拉取国内镜像站的经镜像docker run -d -p 9200:9200 -p 9300:9300 registry.docker-cn.com/library/elasticsearch
出错了如下jdk分配内存太大2G更改一下为512m
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000085330000, 2060255232, 0) failed; error='Cannot allocate memory' (errno=12) # # There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 2060255232 bytes for committing reserved memory. # An error report file with more information is saved as: # /tmp/hs_err_pid1.log
docker run -d -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms256m -Xmx256m" registry.docker-cn.com/library/elasticsearch
"You Know, for Search"
# 数据存储结构
ES的存储是Index(数据库)和Document(表),文档和索引。组织结构是Node(节点)和Cluster(集群)
对外提供RESTapi,json传输
- Json Object,由字段(Field)组成,常见数据类型如下:
- 字符串:text,keyword
- 数值型:long,integer,short byte,double,float,half_float scaled_float
- 布尔:boolean
- 日期:date
- 二进制:binary
- 范围类型:integer range,float range,long_range,double_range,date_range 每个document都有一个固定_id,如果你自己不指定系统自动指定哈希
- 元数据(DocumentMetaData),用于标注文档的相关信息每个document中都有元数据
- _index:文档所在的索引名
- type:文档所在的类型名
- id:文档唯一id
- _uid:组合id,由_type和_id组成(6.x_type不再起作用,同_id一样)
- _source:文档的原始Json数据,可以从这里获取每个字段的内容
- all:整合所有字段内容到该字段,默认禁用
- 索引中存储具有相同结构的文档(Document)
- 每个索引都有自己的mapping定义,用于定义字段名和类型(元数据)
- 一个集群可以有多个索引,比如:nginx日志存储的时候可以按照日期每天生成一个索引来存储,nginx-log-2017-01-01,nginx-log-2017-01-03
# RESTapi
访问http://127.0.0.1:9200/_cat 查看可用的api比如查看索引,查看某个索引数目,健康情况等等。
- PUT方法+索引名可以创建一个index (PUT http://127.0.0.1:9200/ohh)创建了ohh索引
response
{
"acknowledged":true,
"shards_acknowledged":true,
"index":"test_index"
}
- 创建文档PUT index/type/id+请求内容
(PUT http://127.0.0.1:9200/ohh/doc/1 requestbody:{username":"alfred","age":1})
ohh创建一个id为1的document
response
{
"_index":"test_index",
"_type":"doc",
"id":"1",如果不指定id只指定到type,自己生成一个id
"version":1,
"result":"created",
"_shards":{
"total":2,
"successful":1,
"failed":0
"_seq_no":0,
"_primary_term":1
}
}
WARNING
如果插入之前没有es自动创建index和type
在未来type可能会废除,不提倡使用,现在尽量把type全都弄成doc或者是一样的东西不要使用type来分类
- GET /index/type/_search?q=xx 查询关键词的不带关键词是全查询放在body里面{"query":{"term":{"_id":"1"}}}
response
{
"took":0,查询耗时,单位ms
"timed_out":false,是否超时
"_shards":{
"total":5,总记录
"successful":5,查询成功的记录
"skipped":0,跳过了
"failed":0失败了
"hits":{
"total":1,符合条件的总文档数
"hits":[ 返回的文档详情数据数组,默认前10个文档
"_index":"test index",索引名
"_type":"doc",记录的type
"_id":"1" 文档的id
"_score":1,文档的得分
"_source":{文档详情
username":"alfred",
"age":1
}
}
- 允许批量创建文档POST /_bulk
body里面 {"index":{"_index":"test_index","_type":"doc","_id":"3"}{"username":"alfred","age":10}
{"delete":{"_index":"test_index","_type":"doc","_id":"1"}
{"update":{"_id":"2","_index":"test_index","_type":"doc"}{"doc":{"age":"20"}
- 方法
- index 创建文档如果存在则覆盖
- update 更新一个文档
- delete 删除某个文档
- create 创建文档如果存在则报错
- 批量查询根据id GET /_mget
body里面{"docs":[
{"index":"test_index",
"_type":"doc",
"id":"1"
},
{"index":"test_index",
"type":"doc",
"id":"2"
}]
}
# 索引
# 正排索引
- 文档Id到文档内容、单词的关联关系id为x的文档中出现了什么词
# 倒排索引
- 单词到文档Id的关联关系对句子进行分词之后每个词在哪个文档id出现过
一般是通过倒排索引查找到哪些文档,然后通过正排索引取出文档的完整内容倒排索引是搜索引擎的核心,主要包含两部分
- 单词词典(Term Dictionary)
- 记录所有文档的单词,一般都比较大
- 记录单词到倒排列表的关联信息
- 倒排列表(Posting List)记录了单词对应的文档集合,由倒排索引项(Posting)组成
倒排索引项(Posting)主要包含如下信息: - 文档Id,用于获取原始信息
- 单词频率(TF,Term Frequency),记录该单词在该文档中的出现次数,用于后续相关性算分
- 位置(Position),记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)
- 偏移(Offset),记录单词在文档的开始和结束位置,用于做高亮显示
# 分词
# 分词器和它的构成
分词把一系列句子分成一系列的词语,例如word to Vec.分词器是es中专门处理分词的组件,Analyzer,它的组成如下:
Character Filters针对原始文本进行处理,比如去除html特殊标记符
Tokenizer将原始文本按照一定规则切分为单词
Token Filters针对tokenizer处理的单词就行再加工,比如转小写、删除或新增等处理 使用_analyze接口可以指定字段,指定analyzer,自定义分词器进行测试
POST /_analyze {"analyzer":"standard","text":"hello samasiis"}指定分词器和想要分词的文本, "filter":["lowercase"]自己可以指定比如指定filter就可以返回全小写的结果
response
{"tokens": [{"token":"analyzer",
"start_offset":1,
"end_offset":9,
"type":"< ALPHANUM >",
"position":0}
]}
- 自带的分词器有:
[Standard,Simple,Whitespace,Stop,Keyword,Pattern,Language]
[1]Standard
默认分词,按词切分,全员小写支持多语言
[2]Simple
简单分词多,非字符(下划线,数字,单引号等等都切分并且去掉)小写处理
[3]Whitespace
空格切分,保留大写
[4]Stop
the,an,的等停止词进行分词
[5]Keyword
不分词直接返回
[6]Pattern
通过正则表达式自定义分割符默认是\W+,即非字词的符号作为分隔符,小写
[7]Language
提供多语言分词器(用到就百度)
# 中文分词
难点
常用IK,jieba,THULAC,hanlp
# 自定义分词
通过自定义Character Filters、Tokenizer和Token Filter实现
- Character Filters在Tokenizer之前对原始文本进行处理,比如增加、删除或替换字符等自带的有:
- HTML Strip去除html标签和转换html实体
- Mapping 进行字符替换操作
- Pattern Replace 进行正则匹配替换
- 会影响后续tokenizer解析的postion和offset信息
例子(其他的留坑以后试试):
POST /_analyze
{"tokenizer":"keyword",
A"char_filter":["html_strip"],
"text":"<\p>I& apos;m so<//b>happy<//b>!<//p>"}
- Tokenizer将原始文本按照一定规则切分为单词(term or token)自带:
- standard 按照单词进行分割-letter 按照非字符类进行分割
- whitespace 按照空格进行分割
- UAXURL Email 按照 standard分割,但不会分割邮箱和url
- NGram 和Edge NGram 连词分割
- Path Hierarchy 按照文件路径进行切割
例子(其他的留坑以后试试):
POST /_analyze
{"tokenizer":"path_hierarchy",
"text":"/one/two/three"
}
Token Filters对于tokenizer输出的单词(term)进行增加、删除、修改等操作自带的:
- lowercase将所有term转换为小写
- stop 删除 stop words
- NGram和Edge NGram连词分割
- Synonym添加近义词的term
POST _analyze
{
"text":"a Hello,world!",
"tokenizer":"standard",
"filter":[
"stop",
"lowercase",
{
"type":"ngram",
"min_gram":4,
"max_gram":4
}
]
}
# 自定义分词的api
创建或更新文档时(Index Time),会对相应的文档进行分词处理查询时(Search Time),会对查询语句进行分词。
索引时分词是通过配置Index Mapping中每个字段的analyzer属性实现。不指定分词时,使用默认standard。查询的时候通过 analyzer 指定分词器或者在通过index mapping 设置search_analyzer实现
一般不需要特别指定查询时分词器,如果查询时制定分词器和文档默认分词器不一样可能无法匹配。明确字段是否需要分词,不需要分词的字段就将 type 设置为keyword,可以节省空间和提高写性能
可以先用_anaylize检查然后再测试
api像这样
PUT test_index(自己指定索引)
{
"settings":{
"analysis":
{
"char_filter":{},
"tokenizer":{},
"filter":{},
"analyzer":{}
}
}
}