本文 ES 版本基于 7.1.1
相对于之前的不同
移除 type
ES7 相对于之前的版本,最大的不同就是 es7 开始去掉了 type 这个概念(也就是之前用来类比关系型数据库中的表,这也是由于参考了关系型数据库,所以留下了 type 这个不合理的概念)
在 6.x 版本时,一个 index 下只能创建一个 type,这应该是一个过渡阶段。(6.x 版本之前是可以创建多个 type 的)
至于为什么要去掉 type 呢,但是同一索引下不同 type 下相同 filed 最终会被 lucene 映射到一起,所以在不同 type 中的相同字段就可能会出现冲突,从而导致效率降低。而去掉了 type 之后,一个 index 就是一个索引,它们都是独立存储的,所以也就不会出现冲突了,效率也就提升了。
移除 string 类型
ES 5.x 开始,已经移除了 string 类型,而是将字符串拆分为两种类型:text 和 keyword。前者用于全文模糊搜索(会做分词),后者用于精准匹配(不会做分词,适合关键字精准匹配)
这样就可以自己来控制是否要对字符串进行分词了,避免一些不必要的开销,最重要的是可以做一些精准匹配,在之前的 string 中,搜索一个关键字总是会得到一些不需要的结果(因为是全文匹配,所以只要匹配到关键字就会返回,而不会关心它是否是完整匹配的)。
最佳实践
避免使用动态创建
通过设置 dynamic 来动态创建新出现的字段,虽然在有时候这显得很方便(可以不提前定义字段,动态的将不定字段存入 es)但有时候这将会是糟糕的,因为有时候你错误的添加了一个字段,它也会被自动创建到索引字段中,这并不是我们所希望的,我们应该希望这时候报错,提示我们这里的存储有问题,我们才能及时的发现问题。
我们可以设置 dynamic 的值来控制动态映射。
- true: 允许动态添加新的字段,这是默认值。
- false: 忽略新的字段,不会自动为它创建索引。
- strict: 如果遇到新的字段,会跑出异常。
合理使用 enabled
对于不需要索引的字段,可以设置为 enabled: false。例如存储请求日志时,你可能只会根据 uid, request_id 等来进行索引,而不会使用请求体或响应体去进行查询,(只需存储它们即可)这时候可以将它们设置为 enable: false,这样 es 就不会对它们进行索引,从而可以节省很大的存储开销。
合理使用 keyword 字段
有一些字段,你可能只需要对其精确匹配,不需要对其分词或者是范围查询,那么这个时候设置成 keyword 字段比设置成 text 字段或者是数值字段更能提高整体性能。而且还可以降低索引的使用空间,一般如果没有模糊匹配的场景,都建议将字符串字段设置为 keyword。
使用 index template
如果查询具有日期范围过滤子句,则按日期建立数据。 这适用于大多数日志记录和监控场景。我们可以按天、周或月组织索引,然后可以获得指定的日期范围内的索引列表,这样,Elasticsearch 只需要查询一个较小的数据集而不是整个数据集。另外,当数据过期时,删除旧的索引也很容易。
如果要每次自己来手动创建索引,这简直太麻烦了,es 的开发者们也考虑到了这点,所以为我们提供了索引模板。你可以创建一个索引模板,里面设置匹配规则,当写入的索引名匹配到索引模板时,将自动应用索引模板中的 settings 和 mappings。
索引生命周期管理(ilm)
参考官方文档 www.elastic.co/guide/en/el…
PUT _ilm/policy/log_save_policy
{
"policy": {
"phases": {
"delete": { // 定义删除阶段
"min_age": "365d", // 删除阶段在 365 天后开始
"actions": { // 定义删除动作
"delete": {}
}
}
}
}
}
索引模板创建
索引的 settings 和 mappings 具体参数设置: www.elastic.co/guide/en/el… www.elastic.co/guide/en/el…
PUT _template/req_log
{
"order": 0,
"index_patterns": ["req_log-*"],
"settings": {
"index": {
"lifecycle": {
"name": "log_save_policy" // 使用上面刚创建的生命周期策略。
},
"routing": {
"allocation": {
"enable": "all" // 索引碎片分配策略
}
},
"refresh_interval": "60s", // 索引刷新频率(es 是近实时搜索的原因)
"number_of_shards": "3", // 分片数,一般等于机器实例数
"number_of_replicas": "1", // 副本数,一般设置为1
}
},
"mappings": { // 索引字段映射
"dynamic": "false",
"properties": {
}
},
"aliases": { // 索引别名
"req_log": {}
}
}
索引模板创建成功后,如果要指定按月创建索引,那么索引名称可以设置为 req_log-2020-06 ,它就会自动匹配到上面创建的模板,并应用模板配置。