ELK=elasticsearch+Logstash+kibana
elasticsearch:后台分布式存储以及全文检索
logstash: 日志加工、“搬运工”
kibana:数据可视化展示。
ELK架构为数据分布式存储、可视化查询和日志解析创建了一个功能强大的管理链。 三者相互配合,取长补短,共同完成分布式大数据处理工作。
2. ES特点和优势
1)分布式实时文件存储,可将每一个字段存入索引,使其可以被检索到。
2)实时分析的分布式搜索引擎。
分布式:索引分拆成多个分片,每个分片可有零个或多个副本。集群中的每个数据节点都可承载一个或多个分片,并且协调和处理各种操作;
负载再平衡和路由在大多数情况下自动完成。
3)可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。也可以运行在单台PC上(已测试)
4)支持插件机制,分词插件、同步插件、Hadoop插件、可视化插件等。
---------------------
ES科普教程:https://blog.csdn.net/laoyang360/article/details/52244917
为什么要用ES:https://www.quora.com/Why-do-people-use-Hadoop-or-Spark-when-there-is-ElasticSearch
curl -X PUT "localhost:9200/customer?pretty" 创建一个index
curl -X GET "localhost:9200/_cat/indices?v" 查看index的状态信息
curl -X PUT "localhost:9200/customer/doc/2?pretty" -H 'Content-Type: application/json' -d'
{
"name": "Leo"
}
' 在index里插入一些json数据
curl -X DELETE "localhost:9200/customer?pretty" 删除一个index(此处customer为一个index名)
--------
<REST Verb> /<Index>/<Type>/<ID> REST访问模式
curl -X POST "localhost:9200/customer/doc/2?pretty" -H 'Content-Type: application/json' -d'
{
"name": "Jane Doe"
}
' 修改index为customer,type为doc下,id为2的json,name改为“Jane Doe”
curl -X POST "localhost:9200/customer/doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
"doc": { "name": "Jane Doe", "age": 20 }
}
' 更新操作 添加了属性age
curl -X POST "localhost:9200/customer/doc/1/_update?pretty" -H 'Content-Type: application/json' -d'
{
"script" : "ctx._source.age += 5"
}
' 更新操作 更新了age的值
curl -X DELETE "localhost:9200/customer/doc/2?pretty" 删除id为2的所有json
curl -X POST "localhost:9200/customer/doc/_bulk?pretty" -H 'Content-Type: application/json' -d'
{"index":{"_id":"1"}}
{"name": "John Doe" }
{"index":{"_id":"2"}}
{"name": "Jane Doe" }
'
curl -X POST "localhost:9200/customer/doc/_bulk?pretty" -H 'Content-Type: application/json' -d'
{"update":{"_id":"1"}}
{"doc": { "name": "John Doe becomes Jane Doe" } }
{"delete":{"_id":"2"}}
'
以上为调用了_bulk API 实现批处理,可以同时实现多种操作
curl -H "Content-Type: application/json" -XPOST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
批量处理:导入一个json文件,前提是1.创建一个名为bank的index;2.进入该json文件的目录
search API:
调用search API的返回值及其含义:
took – time in milliseconds for Elasticsearch to execute the search
timed_out – tells us if the search timed out or not
_shards – tells us how many shards were searched, as well as a count of the successful/failed searched shards
hits – search results
hits.total – total number of documents matching our search criteria
hits.hits – actual array of search results (defaults to first 10 documents)
hits.sort - sort key for results (missing if sorting by score)
hits._score and max_score - The score is a numeric value that is a relative measure of how well the document
matches the search query that we specified. The higher the score, the more
relevant the document is, the lower the score, the less relevant the document is.
curl -X GET "localhost:9200/bank/_search?q=*&sort=account_number:asc&pretty" 按照account_number升序排列
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} },
"sort": [
{ "account_number": "asc" }
]
}
' 与上一条语句执行结果相同
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} }, #查询范围:整个文档
"from": 10, #查询开始的索引:10(默认值为0)
"size": 10 #返回文档数量10 (默认值为10)
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} },
"sort": { "balance": { "order": "desc" } } 按照balance的降序排序,默认输出10个文档
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_all": {} }, 查询所有
"_source": ["account_number", "balance"] 只返回account_number和balance字段
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match": { "address": "mill" } } 查询address字段中包含mill的所有账户
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match": { "address": "mill lane" } } 查询address字段中包含mill 或者包含 lane 的账户
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": { "match_phrase": { "address": "mill lane" } } ***注意与上一条的区别: 此处只返回同时包含 mill lane的信息
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": { 表示布尔逻辑查询,
"must": [ must表示必须满足所有的语句(与关系),即:同时包含mill和lane 可以为should 表示或关系, 也可以为must_not 表示非关系
{ "match": { "address": "mill" } },
{ "match": { "address": "lane" } }
]
}
}
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": [
{ "match": { "age": "40" } } 返回包含age=40,同时不包含state:ID
],
"must_not": [
{ "match": { "state": "ID" } }
]
}
}
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": { 制定查询范围
"range": { range查询,返回的是一个范围内的数据
"balance": { 指定balance字段
"gte": 20000, balance最小为20000
"lte": 30000 最大为30000 范围内的所有数据
}
}
}
}
}
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"size": 0, size设为0,表示只显示聚合情况,不显示具体信息
"aggs": { 聚合查询
"group_by_state": { 根据state字段分组
"terms": {
"field": "state.keyword" 根据state的关键字聚合
}
}
}
}
'
curl -X GET "localhost:9200/bank/_search" -H 'Content-Type: application/json' -d'
{
"size": 0,
"aggs": {
"group_by_state": {
"terms": {
"field": "state.keyword"
},
"aggs": {
"average_balance": { 聚合结果返回每一个聚合的平均账户余额(聚合嵌套)
"avg": {
"field": "balance"
}
}
}
}
}
}
'
以下语句,返回这个示例演示了如何按年龄等级(20-29岁、30-39岁和40-49岁)分组,然后按性别分组,
最后得到平均账户余额、每个年龄等级、每个性别
curl -X GET "localhost:9200/bank/_search?pretty" -H 'Content-Type: application/json' -d'
{
"size": 0,
"aggs": {
"group_by_age": {
"range": {
"field": "age",
"ranges": [
{
"from": 20,
"to": 30
},
{
"from": 30,
"to": 40
},
{
"from": 40,
"to": 50
}
]
},
"aggs": {
"group_by_gender": {
"terms": {
"field": "gender.keyword"
},
"aggs": {
"average_balance": {
"avg": {
"field": "balance"
}
}
}
}
}
}
}
}
'
./bin/elasticsearch -d -p pid 将ES作为后台守护进程启动,并将日志文件存储在ES下的logs里
kill 'cat pid' 关闭进程
2018.10.29
1. 关闭防火墙的命令: systemctl stop(distable/status) firewalld.service
2018.10.30 elasticsearch配置问题
1.解压包: tar -zxvf 文件名
2.切换到root用户下,改变最大打开文件数量的限制
①su 切换到root用户
②ulimit -n 65536
③切换到启动ES的普通用户 启动ES
或者直接改文档:修改 /etc/security/limit.conf 启动ES的用户名 - nofile 65536
④启动ES 查看设置是否生效 curl -X GET "localhost:9200/_nodes/stats/process?filter_path=**.max_file_descriptors"
若返回的是65536 则生效
3.设置JVM.option
①设置最小堆和最大堆大小一样
②最大堆不超过物理RAM的50%,
4.减少内存交换(内存交换堆性能和节点稳定性影响较大)
①注释掉/etc/fstab 文件里所有包含swap单词的行
②将vm.swappiness设置为1 , sysctl vm.swappiness=1
5.将ES的进程锁定在RAM里,禁止内存交换
修改elasticsearch.yml bootstrap.memory_lock: true (注意true前面有空格)
启动es查看设置是否成功 curl -X GET "localhost:9200/_nodes?filter_path=**.mlockall" 如果为true,即为成功
6. 修改mmap数量
(MMap:FS类型通过将文件映射到内存(MMap),在文件系统(映射到Lucene MMapDirectory)上存储碎片索引。
内存映射占用进程中虚拟内存地址空间的一部分,这部分空间与被映射文件的大小相等。在使用这个类之前,
请确保有足够的虚拟地址空间。)
①修改文件/etc/sysctl.conf vm.max_map_count=262144
②重启之后查看 sysctl vm.max_map_count
2018.10.31
1.x-pack 的安装与卸载
1.1 安装: https://segmentfault.com/a/1190000012789290
1.2 卸载: ./elasticsearch-plugin remove x-pack 然后 删除elasticsearch.yml中有关x-pack的配置信息
2.升级es版本,并安装elasticsearch-head和Kibana
https://www.jianshu.com/p/d53ef9aa8416
3.安装kibana
3.1 安装步骤:①找到对应你的es版本的kibana
②wget https://artifacts.elastic.co/downloads/kibana/kibana-6.0.0-linux-x86_64.tar.gz (注意修改版本号)
③tar -xzf kibana-6.0.0-linux-x86_64.tar.gz
3.2 配置kibana.yml 主要是 elasticsearch.url: "http://主机ip:9200" 剩下的可以默认,把配置前的#号去掉就行(之后又需求再进行修改)
3.3 启动kibana时,Discover 页默认会加载默认的索引模式。时间过滤器设置的时间为过去15分钟,查询设置为匹配所有 (\*) 。
如果看不到任何文档,试着把时间过滤器的范围调大。如果还是看不到任何结果,很可能是根本就 没有 任何文档。
所以,如果没有任何文档,那么第一次加载时间会很长
4.安装head 注: 5.x之后的版本不支持head插件的安装 只能下载好之后单独安装
2018.11.1
1.kibana的使用
1.1 导入数据前,先建立一个索引,对索引建立映射,在建立映射时,要输入字段类型,es版本不一样,字段类型也不一样,比如:ES6.x的字符串类型为text而不是string
(具体详见https://blog.csdn.net/u014516601/article/details/82885392)
以bank数据集为例:
①建立索引 curl -X PUT "localhost:9200/customer?pretty"
②创建类型(一个索引下可以包含多个类型,如果两个类型的字段集是互不相同的,这就意味着索引中将有一半的数据是空的(字段将是 稀疏的 ),
最终将导致性能问题。在这种情况下,最好是使用两个单独的索引。一个索引下的不同类型之间的数据模式最好是相同或类似的)
③建立映射(构建映射之前要先了解数据的格式,有哪些字段)
注:此处可能报错:1> Content-Type header [application/x-www-form-urlencoded] is not supported 原因是es6.0之后的建立映射的语句堪忧改变
2> mapping type is missing; in elasticsearch 原因指定类型, 一个索引下可以建立多个类型(类型名称自定义,我理解的是类型RDBMS里的表名),一个类型下又可以建立多个字段,每个字段都需要指定数据类型
curl -X POST "192.168.1.240:9200/bank/product/_mapping" -H "Content-Type: application/json" -d ' # 索引:bank 类型: product 字段:account_number,balance等等
{
"properties" : {
"account_number": {"type":"integer"},
"balance": {"type":"integer"},
"firstname": {"type":"text"},
"lastname": {"type":"text"},
"age": {"type":"integer"},
"gender": {"type":"text"},
"address": {"type":"text"},
"employer": {"type":"text"},
"email": {"type":"text"},
"city": {"type":"text"},
"state": {"type":"text"}
}
}'
1.2 具体对于kibana的图标操作 详见:https://blog.csdn.net/ming_311/article/details/50619859
1.3 kibana后台运行的命令 nohup ./kibana (输入回车之后稍微等一会,有点慢)
2.Java和Elasticsearch的相互操作
2018.11.3
1.ik中文分词器的安装与使用
1.1 匹配版本
使用./elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.0/elasticsearch-analysis-ik-6.3.0.zip (注意改版本号)
安装完成重新启动elasticsearch
1.2 新建索引和类型,
curl -XPOST http://localhost:9200/index/fulltext/_mapping -H 'Content-Type:application/json' -d'
{
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word" #细粒度分词,ik_smart:粗粒度分词
}
}
}'