文章目录
分布式搜索
1. elasticsearch
elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容
elasticsearch结合kibana、Logstash、Beats,就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域
- elasticsearch是核心,负责存储、计算、搜索、分析数据
- kibana负责数据可视化
- Logstash、Beats负责数据抓取
1.1 正向索引和倒排索引
正向索引:基于文档id创建索引。查询词条时必须先找到文档,然后判断是否包含词条
倒排索引:对文档内容分词,对词条创建索引,并记录词条所在文档的信息。查询时先根据词条查询到文档id,然后获取到文档
elasticsearch采用倒排索引:
- 文档(document):每条数据就是一个文档
- 词条(term):文档按照语义分成的词语,中文按照语义分,英文按照空格分
elasticsearch是面向文档存储的,可以是数据库中的一条商品数据,一个订单信息。
文档数据会被序列化为json格式后存储在elasticsearch中
索引(index):相同类型的文档的集合
映射(mapping):索引中文档的字段约束信息,类似表的结构约束
架构:
- MySQL:擅长事务类型操作,可以确保数据的安全和一致性
- Elasticsearch:擅长海量数据的搜索、分析、计算
使用docker安装elasticsearch,并启动
docker pull elasticsearch:7.12.1
docker run -d \
--name es \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
--privileged \
--network es-net \
-p 9200:9200 \
-p 9300:9300 \
elasticsearch:7.12.1
命令解释:
-e "cluster.name=es-docker-cluster"
:设置集群名称-e "http.host=0.0.0.0"
:监听的地址,可以外网访问-e "ES_JAVA_OPTS=-Xms512m -Xmx512m"
:内存大小-e "discovery.type=single-node"
:非集群模式-v es-data:/usr/share/elasticsearch/data
:挂载逻辑卷,绑定es的数据目录-v es-logs:/usr/share/elasticsearch/logs
:挂载逻辑卷,绑定es的日志目录-v es-plugins:/usr/share/elasticsearch/plugins
:挂载逻辑卷,绑定es的插件目录--privileged
:授予逻辑卷访问权--network es-net
:加入一个名为es-net的网络中-p 9200:9200
:端口映射配置
安装kibana并运行
docker pull kibana:7.12.1
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.12.1
命令解释:
--network es-net
:加入一个名为es-net的网络中,与elasticsearch在同一个网络中-e ELASTICSEARCH_HOSTS=http://es:9200"
:设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch-p 5601:5601
:端口映射配置
1.2 ik分词器
es在创建倒排索引时需要对文档分词,在搜索时,需要对用户输入内容分词。但默认的分词规则对中文处理并不友好。所以处理中文分词,一般会使用ik分词器
IK分词器包含两种模式:
GET /_analyze
{
"analyzer": "ik_smart",
"text": "今天的天气真不错"
}
-
ik_smart
:最少切分,粗粒度切分响应 { "tokens" : [ { "token" : "今天", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 }, { "token" : "的", "start_offset" : 2, "end_offset" : 3, "type" : "CN_CHAR", "position" : 1 }, { "token" : "天气", "start_offset" : 3, "end_offset" : 5, "type" : "CN_WORD", "position" : 2 }, { "token" : "真不错", "start_offset" : 5, "end_offset" : 8, "type" : "CN_WORD", "position" : 3 } ] }
-
ik_max_word
:最细切分,细粒度切分{ "tokens" : [ { "token" : "今天", "start_offset" : 0, "end_offset" : 2, "type" : "CN_WORD", "position" : 0 }, {