前言
最近又是学习的爆发期,我戒除了上班划水和看知乎故事会,也戒除了游戏和小说
也戒除了频繁参加外面的无用活动,也逐渐修复了寂寞侵蚀内心的恐惧
将心思逐渐稳定下来,所以,我本月开始到年底,将会爆发式更新blog和歌曲
请大家和我一起学习吧!对了,如果有机会,请不要忘记帮我看看是否有合适的工作
我最近在换工作,走过路过,也别忘记我找份工作。
开始!
1 | 从不去关心他人的定位 |
当我们在说Es索引设计时,我们在说什么?
在我的开发生涯中,我使用过Mysql,Etcd,Mongodb之类的数据库
当我拿到一个数据库要进行开发任务的时候,我的第一件事往往就是查看数据结构,或者是查看表结构
如果是Mysql一类的数据库,数据表中,表的字段类型是否合适,表设计是否合理,涉及到联合查询的机制是否完全?这往往就是数据库表设计的核心。
嵌套到es当中,es的索引,你也可以理解为表
当我们要设计索引的时候,我们就是设计表
当我们说要设计高可用的的索引时,往往就是指索引
- 可支撑大数据量
- 性能影响小
- 结合业务场景,全维度考虑增,删,改,查
ElasticSearch索引的基础知识
索引,这个东西在数据库里面就是帮助加快检索速度的
它是一种数据结构,这个我原来提过一点点
具体的地址,请参看
今天我们的主题并不是原理,而是如何设计索引
如何设计索引才能让我们的ES更加健壮,避免后期存入数据过多后还要更改结构
这个才是这篇文章的核心。
所以基础知识这里,我将不会表述太多,请大家见谅。
默认你已经会用Es,就这样,Over。
Mapping的设计
Mapping是什么?
Mapping在Es里面,相当于表结构,我举个例子
1 | "mappings": { |
- 我们定义的mapping里面有若干个字段,name,id…
- 类型不同,有long,keyword,date
Mapping在索引设计中是非常重要部分,就和表设计一样的,你需要定义字段
一个好的字段能让我们的检索速度飞快,一个差的字段会让我们浪费很多平白无故的存储空间
首先Mapping的基础知识可以参看这篇文章
这篇文章的大佬把Mapping说的很清楚了
Mapping 分为两种,静态Mapping和动态Mapping
下面我分别说下静态和动态的几个优缺点
静态Mapping
事先定义好字段,也就是定义好基础的Mapping格式,就像章节最开始我举的例子。
静态Mapping,就相当于我们创建Mysql表,事先建表,规定好所有的字段和类型
静态Mapping的优点如下
- 可选可控
- 节约存储空间
静态Mapping的缺点如下
- 设计要求高,后期无法进行更改
- 将数据格式全部规定死,不够动态
动态Mapping
我们不创表,直接传入数据,Es会根据你传入的数据自动匹配合适的类型,也就是自动识别数据
说白了,就是你,传个json过来,Es根据你的json自动匹配类型,然后创建Mapping
动态Mapping这东西,其实我是不推荐用的,因为相当于,你把数据类型的判断逻辑交给了Es,这是很不可取的,因为Es,很傻,说下原因
- 当你不想检索一些字段的时候,你可以通过设置mapping事先指定,但是动态的不行
- 动态Mapping可控性没那么高,你往里导数据,要保证数据的一致性
高可用Mapping设计的流程
查了一些资料,其实大家可以看一下铭毅天下这个老哥的公众号
他的公众号给了我很大启发!
首先,设计Mapping,需要预先考虑如下几点
- 是否需要进行全文检索
- 是否需要排序
- 数据类型的多重选择
首先,先将Mapping里的几个参数及其基础设置梳理
参数 | 具体说明 | 传入参数 |
---|---|---|
enabled | 设置是否需要检索 | True/False |
index | 设置是否构建倒排索引 | True/False |
index_option | 设置存储倒排索引的哪些信息 | True/False |
doc_values | 是否开启聚合分析 | True/False |
dynamic | 动态更新mapping | True/False |
data_detection | 自动识别日期类型 | True/False |
进行Mapping设计时,首先要考虑我们到底有多少字段,这些字段的属性是什么
这里非常重要,因为,当你创建完Index的时候,Es是不许更新表结构,也就是Mapping的,
如果要选择更新,则需要重建Index,当数据量很大的时候,这种方案肯定是不可以的。
所以,我这里定义的流程如下
第一步:确定存储的数据类型
先细分析一波,先根据我们的需求,确定建立好我们的数据类型
一般的数据类型如下
根据我们的需求去梳理数据类型
这里提几点选择策略
- 如果你有很多文字,不需要分词,选text,需要分词,选keyword
- 如果你未来不确定你到底有多少数据,将类型设置为long是比较合适的
- keyword检索比较短的字符会更快,如果字符很大,那么会增加存储和检索成本
第二步:确定哪些字段需要检索
如果我们存储的一个json十分巨大,例如content是一篇文章,或者我们的Mapping字段非常的多,那么如果全部默认检索,那我们会搜出一大堆无用的东西
这样既增加了存储成本,又减弱了检索效率,所以下一步,我们就要根据需求,确定哪些字段需要检索
一些固定参数,或者不想给用户展示的参数也就没有检索价值
例如ID一类的参数
这里如果我们不想ID被检索,那么需要设置
1 | "id":{ |
第三步:检索的方式
这里一般指的是分词的设置,这里需要指定分词器
分词器我以前的blog里面也讲过
这里相当于是,给指定的字段,添加分词
假如我们现在有一个字段,名字叫name,我们需要指定中文分词器IK
1 | "name":{ |
第四步:指定mapping的特殊设置
这里的设置,不针对某个字段,而是针对整个mapping的setting设置
这里有如下几个常用设置
1 | { |
一般都是这么几个设置
甭管那么多,直接上,不要怂
这张图是铭毅天下那里找来的!爱你!
这个流程,非常清楚了
Mapping的模版
这里给出我自己开发时候的一个模版,这个模版扛住了千万数据量,直接上,不要怕
大家拿过来改改字段就行
1 | { |
大数据下索引的切分
当我通过filebeat或者logstash倒入数据到Es中的时候
传输到Es中,创建的index是可以自己控制的
一般的划分方法是:
- 年
- 月
- 日
- 自定义
举例来说
假如我们的log索引,名字叫”log-2021-09”
那么每天的数据量都有千万,那么这个索引就会越来越大,越来越大
你做检索的时候,就会在一个非常大的索引中进行
这样检索的时候,卡,慢就出现了
万一这索引坏了,那。。。丢数据吧
所以,如何进行切分,或者优化索引,势在必行
下面我这里将给出一些我自己实战的手法,给大家一些建议。
动态创建索引
首先,上一节我们讲了Mapping模版,这里我就不再多说
我们需要结合模版去动态创建索引
方法如下
rollver滚动创建索引
现在开始设定 log-2021-09 这个索引
这步的意思是创一个索引,名字叫做log-2021-09-00001,别名为logs_write
1 | curl -XPUT 'localhost:9200/log-2021-09-00001 ?pretty' -d' |
现在开始设置动态索引创建
这步的意思是,设定logs_write,当天数大于7天,或者文档数量大于100000,或者大小大于5gb,创建一个新的log-2021-09-00002 索引
1 | POST /logs_write/_rollover |
定时清理过期数据
Curator索引管理工具
这个工具,可以进行索引管理
安装的方法,网上找RPM包直接安就得了
https://www.elastic.co/guide/en/elasticsearch/client/curator/current/yum-repository.html
它的功能有
- 关闭索引
- 创建快照
- 创建索引
- 打开索引
…..
这里,我们可以通过Curator来进行索引创建,定时配置删除等等
例如我们要动态删除7天前的索引
1 | # Remember, leave a key empty if there is no value. None will be a string, |
以上命令删除了7天前,以log-*开头的索引
可以看下这篇文章
结尾
这些大概就是我实战遇到的一些问题,结合网上的一些资料
我输出了这篇blog
最近我开始疯狂学习,希望未来会有突破吧
狗公司不发年终,淦,还是赶紧找机会跑路,才是最重要的。
大家加油吧!写算法Ing!
加油!