ElasticSearch
全文检索
先建立索引,再对索引进行搜索的过程叫全文检索
扫描文件生成索引(非结构提取信息重新组织,使其有结构),查找时通过查找索引
结构化数据
行数据,存储在数据库,固定格式,固定长度
非结构化数据
不固定长度,不固定格式(文本文件,电子邮件,Excel,音频,视频)
Lucense
全文检索引擎工具包
核心概念
Field
存储和索引
Term
搜索的最小单位,文档的一个词语
对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单 元从而找到 Document(文档)。
注意:创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫 倒排索引结构。 倒排索引结构是根据内容(词语)找文档
搜索过程
- 搜索条件被切分词
- 搜索条件分词取索引中查询,匹配词条
- 通过词条获得倒排列表,通过倒排列表获得 Document 队列,将 document 列表封装返回
ElasticSearch
分片
索引超过单机容量,将索引分为多个碎片,默认分片为 5.每个分片是一个功能齐全且独立的索引
类型 type
类型是文档的容器,相当于数据库的表
索引库
类似于数据库
映射配置
字段的数据类型,属性,是否索引,是否存储的约束
_source
文档原始数据
分词
两种分词器使用的最佳实践是:索引时用 ik_max_word,在搜索时用 ik_smart。
ik_max_word 和 ik_smart 的区别 - 知乎
查看映射关系
GET /索引库名/_mapping
映射数据类型
- text,会被分词,不用于排序,适用于 文章标题
- keyword:不会被分词,必须匹配完整内容,适合邮箱,身份证
查询
- 查询所有
GET /lagou/_search {
"query":{
"match_all": {}
}
}
- 匹配查询
查询条件的值会切 分词,查询的结果集取并集
GET /lagou/_search {
"query":{
"match": {
"title": "lagou 小米"
}
}
}
and查询
GET /lagou/_search {
"query":{
"match": {
"title": {"query":"lagou 小米","operator":"and"}
}
}
}
- 词条匹配(term)
精确查询,某个值 等于查询的值
GET /lagou/_search {
"query":{
"term": {
"price": 9999
}
}
}
- bool 组合
把各种其它查询通过 must(与)、must_not(非)、should(或)的方式进行组合
GET /lagou/_search
{
"query":{
"bool":{
"must": { "match": { "title": "大米" }},
"must_not": { "match": { "title": "电视" }},
"should": { "match": { "title": "手机" }}
}
}
}
- 过滤
GET /lagou/_search {
”_source“:["title","price"],
"query":{
"match": {
"title": "lagou 小米"
}
}
}
GET /lagou/_search {
”_source“: {
"excludes":["title","price"]
},
"query":{
"match": {
"title": "lagou 小米"
}
}
}
- 分页
from:目标数据的偏移值(开始位置),默认 from 为 0
size:每页大小
GET /lagou/_search {
"query": { "match_all": {} },
"sort": [ { "price": { "order": "asc" } } ],
"from": 3,
"size": 3
}
聚合 aggregations
桶 bucket
按照某种方式对数据分组,每一组数据在 ES 中是一个桶
度量(metrics)
分组完成,对组中的数据进行聚合运算
- hits:查询结果为空,因为我们设置了 size 为 0
- popular_colors:定义的聚合名称 buckets:查找到的桶,每个不同的 color 字段值都会形成一个桶 key
- aggs:在上一个 aggs(popular_colors)中添加新的 aggs。可见度量也是一个聚合
- avg_price:聚合的名称
- avg:度量的类型,这里是求平均值
- field:度量运算的字段
GET / car / _search {
"size": 0,
"aggs": {
"popular_colors": {
"terms": {
"field": "color"
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
ES 集群
查询数据
查询过程
- 客户端发送一个请求给 coordinate node
- 协调节点将搜索的请求转发给所有的 shard 对应的 primary shard 或 replica shard
- query phase(查询阶段):每一个 shard 将自己搜索的结果(其实也就是一些唯一标识),返回 给协调节点,有协调节点进行数据的合并,排序,分页等操作,产出最后的结果
- fetch phase(获取阶段) ,接着由协调节点,根据唯一标识去各个节点进行拉取数据,最终返回 给客户端
ES 客户端
新增文档
private RestHighLevelClient client;
// Json工具
private Gson gson = new Gson();
Product product = new Product();
...
// 格式化为json
String source = gson.toJson(product);
//3.创建索引请求对象 访问哪个索引库、哪个type、指定文档ID
//public IndexRequest(String index, String type, String id)
IndexRequest request = new IndexRequest("lagou","item",product.getId().toString());
request.source(source, XContentType.JSON);
//4.发出请求
IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
查询
SearchRequest request = new SearchRequest();
// 查询构建工具
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
// 添加查询条件,通过QueryBuilders获取各种查询
sourceBuilder.query(QueryBuilders.matchAllQuery());
request.source(sourceBuilder);
// 搜索
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
// 解析
SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit : searchHits) {
// 取出source数据
String json = hit.getSourceAsString();
// 反序列化
Product item = gson.fromJson(json, Item.class);
System.out.println("item = " + item);
}
Spring Data ElasticSearch
-
@Document:声明索引库配置
- indexName:索引库名称
- type:类型名称,默认是“docs” shards:
- 分片数量,默认 5
- replicas:副本数量,默认 1
- @Id:声明实体类的 id
-
@Field:声明字段属性
- type:字段的数据类型
- analyzer:指定分词器类型
- index:是否创建索引
/Product.java/
@Document(indexName = "lagou", type = "product", shards = 3, replicas = 1)
public class Product {
@Id
private Long id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title; //标题
@Field(type = FieldType.Keyword)
private String category;// 分类
@Field(type = FieldType.Keyword)
private String brand; // 品牌
@Field(type = FieldType.Double)
private Double price; // 价格
@Field(type = FieldType.Keyword, index = false)
private String images; // 图片地址
}
@Autowired
private ElasticsearchTemplate esTemplate;
// 创建索引库和映射并制定实体类的字节码
esTemplate.putMapping(Product.class);
查询索引数据
/ProductRespository.java/
public interface ProductRepository extends ElasticsearchRepository<Product, Long> { }
Optional<Product> goodsOptional = goodsRepository.findById(3L);
// orElse 方法,goodsOptional返回值如果为空,则返回orElse传入的参数
System.out.println(goodsOptional.orElse(null));
Docker
docker 开源的应用容器引擎
口号:
build,ship ,run
Build once,Run anywhere
容器和虚拟机比较
VM 在硬件层面虚拟化,需要虚拟机安装操作系统
docker 在 宿主机 os 层面虚拟化
镜像
相当于是一个 root 文件系统。提供容器运行时所需的程序、 库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数。
容器
镜像安装运行之后的实体
镜像和容器的关系
类似于 java 类和对象的关系
- 容器可以持久化为镜像
- 镜像安装运行之后的实体就是容器
镜像相关命令
# 查看本地镜像
docker images
docker search tomcat
#拉取版本 Tomcat 8.5
docker pull tomcat:8
# remove image
docker rmi 镜像id
容器相关命令
# 查看正在运行的容器
docker ps
# 查看所有容器(查看正在运行的和已经停止运行的)
docker ps -a
# 启动交互式容器,只有第一次这样,以后启动是守护式
# -i:表示运行容器,如果不加该参数那么只是通过镜像创建容器,而不启动。
docker run -it --name=tomcat imageId
# 交互式
docker run -id --name=tomcat imageId
# 停止容器
docker stop 容器名称(容器id)
# 删除容器
docker rm 容器名称(容器id)
Kafka
日志收集系统和消息系统
特点
解耦
高吞吐,低延迟
持久性
扩展性,集群支持热扩展
容错性
多客户端支持
多生产者和多消费者
docker 搭建 kafka 集群
docker-compose
通过 yml 配置文件 配置应用程序需要的所有服务
创建 topic
创建一个名字为 test 的主题, 有一个分区,有三个副本。一个主题下可以有多个分区,每个分区可以用对应的副本。
kafka-topics.sh --create --zookeeper zoo1:2181 --replication-factor 3 --partitions 1 --topic test
# 查看主题
kafka-topics.sh --list --zookeeper zoo1:2181
生产数据
kafka-console-producer.sh --broker-list kafka1:9092,kafka2:9093,kafka3:9094 --topic test
消息消费者
指定分组名,防止重复消费消息
分区副本机制
kafka 有三层结构:kafka 有多个主题,每个主题有多个分区,每个分区又有多条消息。
分区机制:主要解决了单台服务器存储容量有限和单台服务器并发数限制的问题
副本:仅冗余备份
消费者负载均衡机制
同一个分区中的数据,只能被一个消费者组中的一个消费者所消费。
多个消费组可以重复消费
网友评论