最近自己练个项目需要将HDFS中的数据检索出来,并做成对应的报表,从效率上说,直接考虑上Elasticsearch(下文直接用ES代替)
全文检索
数据库查询select * from xxx where xxx like '%xxx' 速度慢,结果不是很准确,而全文检索可以快速,准确的找到你想要的数据
快:先从索引库中查找
准:对查询条件进行分词,然后对查询的结果进行相关排序,得分越高,排的越靠前
ES简介
是大数据生态系统的后起之秀,有自己的生态系统(ELK E:Elasticserch(全文检索) L: Logstash(数据采集), K: Kibana(报表)等)Elasticserch 是基于Lucene的分布式全文检索系统,可以认为是一个分布式的NoSQL(not only SQL,不仅仅有SQL)数据库,而且支持全文检索。Lucene是Apache的顶级项目,是一个全文检索框架,遗憾的是Lucene是个单机版程序,ES底层用就是Lucene,操作API比Lucene方便很多。
ES集群搭建 (我用的三台linux: haoop01,hadoop02,hadoop03)
第一步:ES为了数据安全,是不允许root身份直接启动,以root身份启动会报权限错误。
es启动时需要使用非root用户,所以我这里创建一个dog用户
useradd dog复制代码
为dog用户添加密码:
echo 123456a | passwd --stdin dog复制代码
用户权限
1: echo "dog ALL = (root) NOPASSWD:ALL" | tee /etc/sudoers.d/dog 2: chmod 0440 /etc/sudoers.d/dog 复制代码
创建一个用来存放ES以及数据,日志的目录
mkdir /{bigdata,data}复制代码
给相应的目录添加用户和用户组权限
chown -R dog:dog /{bigdata,data}复制代码
第二步:安装和配置,注意这一步最好切换到dog身份来操作,省的后面修改文件权限,记得sudo
解压
tar -zxvf elasticsearch-6.6.0.tar.gz -C /bigdata/复制代码
修改配置
vi /bigdata/elasticsearch-6.6.0/config/elasticsearch.yml复制代码
#集群名称,通过组播的方式通信,通过名称判断属于哪个集群
cluster.name: bigdata复制代码
#节点名称,要唯一
node.name: hadoop01复制代码
#数据存放位置
path.data: /data/es/data复制代码
#日志存放位置(可选)
path.logs: /data/es/logs复制代码
#es绑定的ip地址
network.host: 192.168.2.4复制代码
#初始化时可进行选举的节点(在这几台机器中选举老大,比如有50台机器就从这三台中选举,选举的节点数量给3台就好了)
discovery.zen.ping.unicast.hosts:["hadoop01", "hadoop02", "hadoop03"]复制代码
第三步:启动
使用scp拷贝到其他节点
scp -r elasticsearch-6.6.0/ hadoop02:$PWD scp -r elasticsearch-6.6.0/ hadoop03:$PWD 复制代码
在其他节点上修改es配置,需要修改的有node.name和network.host
启动ES (三台都启动)
/bigdata/elasticsearch-6.6.0/bin/elasticsearch -d复制代码
注意:启动可能会报错(用户最大可创建文件数太小和最大虚拟内存太小)
[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
[2]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
解决方法:
#用户最大可创建文件数太小
sudo vi /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
复制代码
#查看可打开文件数量
ulimit -Hn复制代码
#最大虚拟内存太小
sudo vi /etc/sysctl.conf
vm.max_map_count=262144复制代码
#查看虚拟内存的大小
sudo sysctl -p
到此位置 集群安装就搞定收工,是不是很easy
来,检查以下看看是否安装成功,浏览器敲 http://192.168.2.4:9200/
{
"name" : "es-1",
"cluster_name" : "bigdata",
"cluster_uuid" : "DoB3Oc1hR_aX0HoTeNedSg",
"version" : {
"number" : "6.6.0",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "a9861f4",
"build_date" : "2019-01-24T11:27:09.439740Z",
"build_snapshot" : false,
"lucene_version" : "7.6.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}复制代码
看到以上信息说明成功了
#在浏览器中查看集群状态
http://192.168.2.4:9200/_cluster/health?pretty复制代码
#在linux终端中查看集群状态
curl -XGET 'http://192.168.2.4:9200/_cluster/health?pretty'复制代码
{
"cluster_name" : "bigdata",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 5,
"active_shards" : 10,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}复制代码
三个节点正常运行没毛病
操作他的API,增删改查搞起来老弟
ES是RESTful接口URL的格式,数据是以json形式存放
http://192.168.2.4:9200/
其中index、type是必须提供的。
id是可选的,不提供es会自动生成。
index、type将信息进行分层,利于管理。
index可以理解为数据库;type理解为数据表;id相当于数据库表中记录的主键,是唯一的。
1: 向home索引(库)中添加dog(表) (ES6.0+ 增加安全机制 添加请求头即可正常查询 -H "Content-Type: application/json" )
[dog@hadoop01 bigdata]$ curl -H "Content-Type: application/json" -XPUT 'http://192.168.2.4:9200/home/dog/1' -d '{
> "title": "Elasticsearch: The dogs home",
> "name" : {
> "first" : "二",
> "last" : "狗"
> },
> "publish_date":"2019-02-16",
> "price":"1314"
> }'复制代码
2: 在linux中通过curl的方式查询
curl -XGET 'http://192.168.2.4:9200/home/dog/1'复制代码
3: 通过浏览器查询
http://192.168.2.4:9200/home/dog/1复制代码
4: 通过_source获取指定的字段
curl -XGET 'http://192.168.2.4:9200/home/dog/1?_source=title'curl -XGET 'http://192.168.2.4:9200/home/dog/1?_source=title,price'curl -XGET 'http://192.168.2.4:9200/home/dog/1?_source'复制代码
5: 可以通过覆盖的方式更新
[dog@hadoop01 bigdata]$ curl -H "Content-Type: application/json" -XPUT 'http://192.168.2.4:9200/home/dog/1' -d '{
> "title": "Elasticsearch: The xxxxxx",
> "name" : {
> "first" : "三",
> "last" : "狗"
> },
> "publish_date":"2019-02-16",
> "price":"1199.99"
> }'复制代码
6:或者通过 _update API的方式单独更新你想要更新的字段等
curl -H "Content-Type: application/json" -XPOST 'http://192.168.2.4:9200/home/dog/1/_update' -d '{
"doc": {
"price" : 111111111
}
}'复制代码
7: 删除一个文档
curl -XDELETE 'http://192.168.2.4:9200/home/dog/1'复制代码
8: filter查询
# SELECT * FROM dog WHERE price = 35.99
# filtered 查询价格是35.99的
# 返回的的分是1.0
curl -H "Content-Type: application/json" -XGET 'http://192.168.2.4:9200/home/dog/_search' -d '{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"term": {
"price": 35.99
}
}
}
}
}'复制代码
9: bool过滤查询,可以做组合过滤查询
# SELECT * FROM dog WHERE (price = 35.99 OR price = 99.99) AND publish_date != "2019-02-16"
# 类似的,Elasticsearch也有 and, or, not这样的组合条件的查询方式
# 格式如下:
# {
# "bool" : {
# "must" : [],
# "should" : [],
# "must_not" : [],
# }
# }
#
# must: 条件必须满足,相当于 and
# should: 条件可以满足也可以不满足,相当于 or
# must_not: 条件不需要满足,相当于 not
curl -H "Content-Type: application/json" -XGET 'http://192.168.2.4:9200/home/dog/_search' -d '{
"query" : {
"bool" : {
"should" : [
{ "term" : {"price" : 35.99}},
{ "term" : {"price" : 99.99}}
],
"must_not" : {
"term" : {"publish_date" : "2019-02-16"}
}
}
}
}'
复制代码
10: range范围过滤
# SELECT * FROM dogWHERE price >= 10 AND price < 99
# gt : > 大于
# lt : < 小于
# gte : >= 大于等于
# lte : <= 小于等于
curl -H "Content-Type: application/json" -XGET 'http://192.168.2.4:9200/home/dog/_search' -d '{
"query": {
"range" : {
"price" : {
"gte" : 10,
"lt" : 99
}
}
}
}'
复制代码
有没发现这DSL风格写的要死啊,我靠还要拼接json串,肯定写sql舒服多了啊,下期介绍
- Elasticsearch SQL (写sql简洁舒服),
- Elastic官方的图形化框架Kibana(Kibana 能够以图表的形式呈现数据,并且具有可扩展的用户界面,供您全方位配置和管理 Elastic Stack。这个真的很屌),当然还可以使用比较轻便的图形化框架elasticsearch-head(比较老,界面也比较丑),地址:https://github.com/mobz/elasticsearch-head
- elasticsearch-hadoop (如何检索hdfs数据并通过图形化框架做成相应报表)
欢迎关注我的微信公众号(玩玩大数据),刚开的,文章会第一时间更新在公众号上,哈哈