版本选择
- 见官网 www.elastic.co/cn/support/… 可以查看各个版本的差别
- 尽量选择各个组件都比较切合的版本,这里选择7.17版本,需要jdk11支持,同时可以使用logstash等组件
Elastic组件
- Elastic中有三个基本组件,组合成为ELK,即ElasticSearch、logstash、Kibana。
- ElasticSearch:搜索引擎
- Logstash:提供数据转换功能,可将不同的数据源转换为ES数据并导入数据库
- Kibana:提供ES的可视化操作和监控界面等
基本组件
index(索引)
- ES会索引所有的字段,经过处理后写入到一个反向索引中,查询数据时,直接查询该索引
- ES数据管理的顶层单位为Index,相当于table
document(文档)
- Index中单条记录叫做document,许多条document构成了一个Index
- 同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。
Type
- Document可以进行分组,是逻辑分组,用来过滤Document
- 不同的Type应该有相同的结构,例如,id不能在一个分组中为字符串,在另一个分组中是整型
- 根据规划,Elastic 6.x 版只允许每个 Index 包含一个 Type,7.x 版将会彻底移除 Type。
关系型数据库和ES结构对比
| 关系型数据库 | ES | 备注 |
|---|---|---|
| column | field | |
| row | document | |
| index | table | |
| schema | implicit | ES并没有像关系型数据库那样有schema这样的数据库标识 |
:star2:schema和database的区别
- 在mysql中schema和database是同一个东西,oracle中schema等同于命名空间
- schema和user以及role结合用来控制权限
安装和启动
- 需要有jdk8的环境
- 从官网下载对应版本的包,解压即可
- 执行bin目录下的
elasticSearch即可启动,或通过./elasticsearch -d后台运行,日志可通过log/elasticsearch.log查看- 启动后,访问localhost:9200即可查看是否启动成功
启动可能用到的问题
不能使用root用户运行
- 不能使用root用户运行
- 需要自己创建一个新的用户来启动ES,具体如下:
groudadd 分组名 useradd 用户名 -g 分组名 -p 密码
file descriper too low
- file descriper too low,即文件描述符设置较低,导致无法正常运行,此时需要修改服务器的文件描述符的数量,具体如下
vim /etc/security/limits.conf
- 在
limits.conf最后,追加以下内容, *表示所有用户,可以根据需要配置不同的用户- 重启服务器后,生效
* soft nofile 10000 * hard nofile 10000
vm.max_map_count is too low
- vm.max_map_count is too low
- 修改、/ect/sysctl.conf文件,追加vm.max_map_count=10000即可
java.net.UnknownHostException: geoip.elastic.co
- 不影响运行和使用
- 最新版本默认会去官网下载ip的geo信息,可以通过配置
ingest.geoip.downloader.enable:false来配置,不自动下载。
配置文件
- elasticSearch的配置文件位置在config目录下,elasticSearch.yml
- 常用配置项
# 设置host,用于外部访问es的ip,端口号默认为9200
network.host: 127.3.2.1
http.port: 9200
# 节点名称,可以不写
node.name: node-1
# 集群节点,可以不写
cluster.initial_master_nodes: ['node-1']
# 设置不自动下载ip的geo信息,不配置可能控制台会出现网络连接异常问题,虽然不会影响运行和使用
ingest.geoip.downloader.enabled: false
# 如果索引不存在,是否自动创建索引,如果为false,则创建文档时,如果索引不存在,则会报错
action.auto_create_index: false
快速开始
创建文档
curl -X POST/PUT 'http://127.0.0.1:9200/index/doc/1' -H 'Content-Type: application/json' -d '{ "name": "柯南小海盗", "age": 17,"email": "knxhd@knxhd.com","sex": "男","enable": true}'
- index:索引名,如果数据库没有,默认会自动创建,可以通过
action.auto_create_index: false进行设置- doc:索引类型,必填,在7.X版本的ES中,一个索引仅仅能创建一个type
- 1:文档的ID,唯一标识,可以不填,不填则会自动创建ID,如果重复创建,则会覆盖原来的数据
- 如果不写ID,则请求类型必须为POST,因此为统一格式,一般新增建议都使用POST形式
- pretty表示会格式化返回的结果,为了方便查看数据
- 返回结果
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "KWxMXoIBYDuUCopKeOMq",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 2,
"_primary_term" : 2
}
- result为执行操作的类型,即created、updated、deleted等
- _version:表示版本,可用于控制并发和事务
- 返回结果中 _开发头的表示es的元数据,也就是默认属性
批量操作
- 批量创建文档,使用_bulk接口实现,请求方式:POST
- 请求类型和单个类似,需要传索引和文档类型等
- 基本格式
{action: {metadata}} \n
{request body} \n
{action: {metadata}} \n
{request body} \n
- action表示操作类型,即create、index、update、delete
- create: 创建文档,如果文档存在,则抛出异常
- index:创建文档,如果存在,则覆盖
- update:更新文档
- delete:删除文档
- metadata表示文档的元数据,即
- _index:所属索引
- _type:索引类型
- _id:文档ID
- 元数据可以写在url中,即 /index/doc/_bulk
- request body为要创建的文档对象
{"create":{}}
{"serviceid": 1,"service": "VIDEO_SEARCH_SERVICE","className": "com.hisense.keylab.semantic.service.SAVODSearchService","not": ""}
{"create":{}}
{"serviceid": 2,"service": "WEATHER_SEARCH_SERVICE","className": "com.hisense.keylab.semantic.service.SAWeatherSearchService","not": ""}
// 这里有个空行,匹配操作需要结尾为换行符
批量删除文档
curl --location --request POST 'http://127.0.0.1:9200/hiservice/_bulk' \
--header 'Content-Type: application/json' \
--data-raw '{"delete":{"_index":"hiservice", "_id": 10}}
- 批量删除数据时,需要传入要删除的文档ID,否则会抛出
Validation Failed: 1: id is missing异常
批量更新文档
curl --location --request POST 'http://127.0.0.1:9200/hiservice/_bulk' \
--header 'Content-Type: application/json' \
--data-raw '{"update":{"_index": "hiservice","_type": "_doc", "_id": "2ODM3YIBlOfFpc05V8IW"}}
{"doc": {"serviceid": 1,"service": "VIDEO_SEARCH_SERVICE","className": "com.hisense.keylab.semantic.service.SAVODSearchService","not": "ddfcfcr"}}
- request body中的doc为固定写法,不能进行省略
删除索引
- 根据ID进行删除,URL和新增相同,只不过需要请求类型为
DELETE- 利用接口
_delete_by_query删除数据- 根据接口
_bulk删除文档
根据ID删除数据
curl --location --request DELETE 'http://127.0.0.1:9200/index/doc/1?pretty'
根据参数删除数据
修改索引
- 方式一:全覆盖形式,使用新增索引相同的命令即可,ID为相同的
- 方式二:修改部分字段,使用
_update接口,请求方式为POST
全覆盖修改
curl --location --request PUT 'http://127.0.0.1:9200/index/doc/1?pretty' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "江户川柯南",
"age": 7,
"email": "kenan@knxhd.com",
"sex": "男",
"enable": true
}'
--header和-H等同
--data-raw与-d等同
--request和-X等同
返回结果中_version会增加,类似于版本号,用于版本控制
返回结果为:
{
"_index": "index",
"_type": "doc",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}
修改部分数据
- 此时只会更新name的值,其中,参数doc为固定写法,只需要将要修改的数据放到doc中即可
curl --location --request POST 'http://127.0.0.1:9200/index/doc/1/_update' \
--header 'Content-Type: application/json' \
--data-raw '{
"doc" : {
"name" : "柯南小海盗"
}
}'
查询索引
- ES有两种查询机制,即评分查询和不评分查询。评分查询会根据查询条件通过评分逻辑对结果进行评分,并安装评分从高到低返回结果
- 方式一:通过ID查询
- 方式二:通过
_search接口查询,详情_search- 方式三:通过
_sql接口查询
根据ID查询
curl -X GET 'http://127.0.0.1:9200/index/doc/1?pretty'
_search接口
- 请求方式:POST
- 基本格式:
/index/index_type/_search,index:索引(可选) index_type:索引类型(可选)- 可通过url传参和request body两种方式,详细细节见_search接口
:one: 查询全部数据
curl --location --request GET 'http://127.0.0.1:9200/hiservice/_search' \
--header 'Content-Type: application/json' \
--data-raw '{
"query": {
"match_all": {}
},
"sort": {
"serviceid": "ASC"
}
}'
sort表示排序,key为排序字段,value为排序类型,即desc(倒序)、asc(正序)
:two: 查询部分字段
curl --location --request GET 'http://127.0.0.1:9200/hiservice/_search' \
--header 'Content-Type: application/json' \
--data-raw '{
"query": {
"match_all": {}
},
"sort": {
"serviceid": "ASC"
},
"_source": false,
"fields": ["service", "className"]
}'
- fields用来表示要返回的字段
- _source表示是否显示源数据,如果为true,则既返回要查询的字段,又会返回原数据全部字段
- _source=true,返回值为:
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "hiservice",
"_type": "_doc",
"_id": "2eDM3YIBlOfFpc05V8Ig",
"_score": null,
"_source": {
"serviceid": 2,
"service": "WEATHER_SEARCH_SERVICE",
"className": "com.hisense.keylab.semantic.service.SAWeatherSearchService",
"not": ""
},
"fields": {
"service": [
"WEATHER_SEARCH_SERVICE"
],
"className": [
"com.hisense.keylab.semantic.service.SAWeatherSearchService"
]
},
"sort": [
2
]
}
]
}
}
- 这里的_source为原数据,fields为特定字段返回的数据
- _source为false时,则没有_source这个字段
:three: 范围查询
- 范围查询使用字段`range``
gte:表示大于等于gt:大于lt:小于lte:小于等于
- 根据数字范围查询
curl --location --request POST 'http://127.0.0.1:9200/hi_type/_search' \
--header 'Content-Type: application/json' \
--data-raw '{
"query": {
"range": {
"ID": {
"gte": 2,
"lte": 10
}
}
}
}'
- 根据日期范围查询
{
"query": {
"range": {
"updatetime": {
"gte": "2014-03-06 18:24:23",
"lt": "2014-03-16 15:40:43"
}
}
}
}
- 查询字段
updatetime很有可能查询后为空,这是由于分词策略导致,此时,将查询字段修改为updatetime.keyword即可
:four: 联合查询
使用bool可以实现联合查询,详情可见_search
:five: 分页查询
- 分页查询使用参数
from和size设置当前页和每页大小,from从0开始
curl --location --request POST 'http://localhost:9200/hinickname/h1i/_search' \
--header 'Content-Type: application/json' \
--data-raw '{
"from": 1,
"size": 10
}'
:six: 多索引和多类型搜索
- 使用
_search搜索时,默认会对所有的索引进行搜索,包括系统提供的索引,这样可能会影响效率,同时也会搜索出不需要的数据,可以在路径中定义搜索的索引和类型- 方式一:/index/_search 在index索引下查询,支持模糊搜索,例如:/in*/_search 查询索引in开头
- 方式二:/index/doc/_search 在index索引中doc类型下查询
- 方式三:/index,index2/_search 在index和index2两个索引下查询
- 方式四:/index,index2/doc,doc1/_search 在index和index2两个索引下查询doc,doc1两个类型的数据
- 方式五:/_all/doc1,doc2/_search 查询所有索引中doc1,doc2类型的数据
ES配置
配置文件
es默认配置文件在config目录下,可以通过
ES_PATH_CONF进行配置。配置方式有两种
启动时,通过参数配置
ES_PATH_CONF=/path/to/my/config ./bin/elasticsearch在环境变量中进行配置
路径配置
path:
data: /var/data/elasticsearch
log: /var/log/elasticsearch
- data路径下的数据不能通过简单的赋值粘贴来完成数据备份
集群设置
cluster.name: custom
node.name: node1
network.host: 192.168.1.10
- 默认集群名称为
elasticsearch- node.name用来设置节点名称
- network.host用来设置回环地址,默认可以通过localhost/127.0.0.1进行访问
集群节点设置
discovery.seed_hosts:
- 192.168.1.10:9300
- 192.168.1.11
- seeds.mydomain.com
- [0:0:0:0:0:ffff:c0a8:10c]:9301
discovery.seed_hosts用来设置集群模式下的节点有哪些,配置支持ip、域名和vp6形式- 其中默认端口为9300,如果为9300则,端口可以不写
主节点设置
cluster.initial_master_nodes:
- master-node-a
- master-node-b
- master-node-c
- 在集群启动时,会默认自动选择主节点,但是生产环境下,自动选择可能存在问题,可通过
cluster.initial_master_nodes来设置主节点
审计日志
- 可以通过审计日志记录对于安全性和权限相关的操作,例如:对用户和角色的增删改、认证失败、拒绝连接、数据拒绝操作等
- 开启审计日志有两种方式
- 通过yml文件进行配置,设置
xpack.security.audit.enabled为true即可- 通过接口调用来进行修改
- 不论是哪种方式修改,都需要所有节点都进行修改
审计日志设置
审计事件设置
xpack.security.audit.logfile.events.include
- 通过设置可以设置哪些事件可以被记录,可以使用
_all设置所有的事件,但是不推荐- 默认事件为:
access_denied, access_granted, anonymous_access_denied, authentication_failed, connection_denied, tampered_request, run_as_denied, run_as_granted, security_config_change- 事件类型查看地址:www.elastic.co/guide/en/el…
xpack.security.audit.logfile.events.exclude
- 排除审计事件设置
设置是否包含请求正文
xpack.security.audit.logfile.events.emit_request_body
用户验证
xpack.security.enabled: true
- 在配置文件
elasticsearch.yml中配置是否进行身份验证,开启身份验证后,启动ES- 通过命令
elasticsearch-setup-passwords设置密码。密码设置方式有两种方式:
./elasticsearch-setup-passwords auto,自动生成一个随机密码./elasticsearch-setup-passwords interactive,为每个用户设置特定的密码,密码设置后,如果再次设置密码,则会提示密码已设置成功
- 修改密码后,可通过curl校验用户名和密码是否正确
curl -u elastic:elastic123@ http://127.0.0.1:9200
修改密码
已知当前密码
- 采用CURL的形式调用修改密码的接口,需要校验原来的密码
curl -XPOST -u elastic "127.0.0.1:9200/_security/user/elastic/_password" -H 'Content-Type: application/json' -d'{"password" : "elastic123456@"}'
忘记当前密码
如果已经忘记了密码,则需要先关闭身份校验配置,即
xpack.security.enabled: true在设置好密码后,可以看到生成的密码保持在索引
.security-7中,可通过索引查看的接口,查询出多出的索引删除对应的索引,重新设置密码`
curl -XDELETE 127.0.0.1:9200/.security-7
同步数据
input {
stdin {}
jdbc {
type => "jdbc"
# 数据库连接地址
jdbc_connection_string => "jdbc:mysql://192.168.1.1:3306/TestDB?characterEncoding=UTF-8&autoReconnect=true""
# 数据库连接账号密码;
jdbc_user => "username"
jdbc_password => "pwd"
# MySQL依赖包路径;
jdbc_driver_library => "mysql/mysql-connector-java-5.1.34.jar"
# the name of the driver class for mysql
jdbc_driver_class => "com.mysql.jdbc.Driver"
# 数据库重连尝试次数
connection_retry_attempts => "3"
# 判断数据库连接是否可用,默认false不开启
jdbc_validate_connection => "true"
# 数据库连接可用校验超时时间,默认3600S
jdbc_validation_timeout => "3600"
# 开启分页查询(默认false不开启);
jdbc_paging_enabled => "true"
# 单次分页查询条数(默认100000,若字段较多且更新频率较高,建议调低此值);
jdbc_page_size => "500"
# statement为查询数据sql,如果sql较复杂,建议配通过statement_filepath配置sql文件的存放路径;
# sql_last_value为内置的变量,存放上次查询结果中最后一条数据tracking_column的值,此处即为ModifyTime;
# statement_filepath => "mysql/jdbc.sql"
statement => "SELECT KeyId,TradeTime,OrderUserName,ModifyTime FROM `DetailTab` WHERE ModifyTime>= :sql_last_value order by ModifyTime asc"
# 是否将字段名转换为小写,默认true(如果有数据序列化、反序列化需求,建议改为false);
lowercase_column_names => false
# Value can be any of: fatal,error,warn,info,debug,默认info;
sql_log_level => warn
#
# 是否记录上次执行结果,true表示会将上次执行结果的tracking_column字段的值保存到last_run_metadata_path指定的文件中;
record_last_run => true
# 需要记录查询结果某字段的值时,此字段为true,否则默认tracking_column为timestamp的值;
use_column_value => true
# 需要记录的字段,用于增量同步,需是数据库字段
tracking_column => "ModifyTime"
# Value can be any of: numeric,timestamp,Default value is "numeric"
tracking_column_type => timestamp
# record_last_run上次数据存放位置;
last_run_metadata_path => "mysql/last_id.txt"
# 是否清除last_run_metadata_path的记录,需要增量同步时此字段必须为false;
clean_run => false
#
# 同步频率(分 时 天 月 年),默认每分钟同步一次;
schedule => "* * * * *"
}
}
filter {
json {
source => "message"
remove_field => ["message"]
}
# convert 字段类型转换,将字段TotalMoney数据类型改为float;
mutate {
convert => {
"TotalMoney" => "float"
}
}
}
output {
elasticsearch {
# host => "192.168.1.1"
# port => "9200"
# 配置ES集群地址
hosts => ["192.168.1.1:9200", "192.168.1.2:9200", "192.168.1.3:9200"]
# 索引名字,必须小写
index => "consumption"
# 数据唯一索引(建议使用数据库KeyID)
document_id => "%{KeyId}"
}
stdout {
codec => json_lines
}
}