前言:
要论入门最好的文档,非elasticsearch权威指南和官方的开发文档莫属,我只是基于这两份文档,记录一些关键知识点和自己的理解。
我们为什么要用elasticsearch,或者说来解决什么问题?
- mysql like查询
- 全文检索服务
- 数据库字段太多,查询太慢,索引没有办法再做优化
举个视频网站性能瓶颈,视频资源检索,根据导演,演员,介绍,标题等字段检索,mysql的解决方案是使用模糊匹配,但如果视频过多,检索性能急剧下降。这时就需要elasticsearch化解危机。
基本概念
先了解一下elasticsearch的基本概念【集群cluster,节点node,索引index,类型type,文档document,分片和复制shards and replicas】
与传统关系型数据库对比,有更直观的理解。
Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices -> Types -> Documents -> Fields
千万不要用对于传统数据库的索引来理解elasticsearch中的索引,elasticsearch中的索引更像是mysql中的database.
着重来讲讲分片和复制
一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点可能没有这样大的磁盘空间来存储或者单个节点处理搜索请求,响应会太慢。
为了解决这个问题,Elasticsearch提供了将索引划分成多片的能力,这些片叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引” 可以被放置到集群中的任何节点上。
分片之所以重要,主要有两方面的原因:
- 允许你水平分割/扩展你的内容容量
- 允许你在分片(位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。
在一个网络/云的环境里,失败随时都可能发生。在某个分片/节点因为某些原因处于离线状态或者消失的情况下,故障转移机制是非常有用且强烈推荐的。为此, Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。
复制之所以重要,有两个主要原因:
- 在分片/节点失败的情况下,复制提供了高可用性。复制分片不与原/主要分片置于同一节点上是非常重要的。
- 因为搜索可以在所有的复制上并行运行,复制可以扩展你的搜索量/吞吐量
总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(即没有复制) 或多次。一旦复制了,每个索引就有了主分片(作为复制源的分片)和复制分片(主分片的拷贝)。 分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你不能再改变分片的数量。
默认情况下,Elasticsearch中的每个索引分配5个主分片和1个复制。这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样每个索引总共就有10个分片。
基本操作
这里我想应该只需要记住几个常用的关键词就ok了
# 查看集群健康状况,其中v参数是为了显示表头
GET /_cat/health?v
# 查看节点列表
GET /_cat/nodes?v
# 查看索引
GET /_cat/indices?v
操作文档的话,由于elasticsearch的交互遵循RESTful API的规范,所以GET,PUT,POST,DELETE对应请求资源,更新,创建,删除,但是要注意一点,因为文档在Elasticsearch中是不可变的,更新的实质操作是覆盖更新。
创建索引
这里我的elasticsearch版本为7,移除了type,确切的说,正确的使用方法,使用默认的_doc作为type就可以了。
PUT /students
{
"settings": {
"number_of_shards": 5, # 分片数
"number_of_replicas": 1 # 副本数
},
"mappings": {
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
},
"id": {
"type": "text"
},
"birth": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"class": {
"type": "keyword"
}
}
}
}
小栗子创建一张学生表
PUT /students/_doc/1
{
"name": "John",
"age": 18,
"id": "f20140201",
"birth": "1995-02-01",
"class": "二班"
}
名字 | 说明 |
---|---|
students | 索引名 |
_doc | 类型名 |
1 | 这个学生的ID |
简单搜索
GET /students/_doc/1
GET /students/_doc/_search
# 响应内容的hits数组中包含了我们所有的文档。默认情况下搜索会返回前10个结果
一些更复杂的具体操作就不演示了,为了保持这篇文章的简洁性,因为记录操作的知识点足足能写一篇文章,这里一笔带过。