写在前面
有一个问题被关注的比较少,就是ES对本地磁盘的占用情况。有人可能觉得这个问题的答案显而易见,不就是ES软件本身占用的空间,还有索引数据持久化占用的磁盘空间,另外就是一些日志了。
事实上,关于ES占用磁盘空间的问题远比这个要复杂的多。本篇文章就想聚焦这个问题,深入ES的底层原理来分析磁盘的占用情况。
正文
是否执行分析
首先对于一个索引,其中的字段在写入是,写入分析对磁盘是有影响的。那么什么是写入分析? 当我们index一个文档时,如果不指定分析器,默认使用的是standard
,可以做个测试,看下默认的分析器执行的结果。
GET /_analyze
{
"analyzer": "standard",
"text": "Text to analyze"
}
我们可以为字段单独指定analyzed
或者 not_analyzed
, 比如:
PUT /my_index
{
"mappings": {
"my_type": {
"properties": {
"status_code": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
- not_analyzed:将字段的原始值放入索引中,作为一个独立的term,它是除string字段以外的所有字段的默认值。
- analyzed:string字段的默认值,会先进行分析后,再把分析的term结果存入索引中。
分析的目的主要是为了建立倒排索引,进行全文检索分析。如果没有这个需求可以关掉。
_all字段和_source字段
很多时候,我们查询文档会发现返回的结果里,带有一个_source
字段,里面是全部字段的内容。_source
字段默认是存储的,这个会占用磁盘空间。
什么情况下不用保留 _source
字段?比如如果某个字段内容非常多,我们的业务场景只需要能对该字段进行搜索,可以考虑关闭 _source
字段,我们搜索到文档id后,再通过文档id去数据库拿到这个字段的内容。这样可以节省很多空间。如何关闭呢?
PUT my-index-000001
{
"mappings": {
"_source": {
"enabled": false
}
}
}
_all
字段默认是关闭的,如果要开启_all
字段,索引就更大,占用磁盘空间当然就更大。_all
字段开启适用于不指定搜索某一个字段,根据关键词,搜索整个文档内容。
Doc values
Doc Values 通过序列化把数据结构持久化到磁盘,我们可以充分利用操作系统的内存,而不是 JVM 的 Heap 。
Doc Values 默认对所有字段启用,除了 analyzed strings。也就是说所有的数字、地理坐标、日期、IP 和不分析( not_analyzed )字符类型都会默认开启。
Doc Values的作用是开启的字段可以支持排序,聚合等能力,如果业务场景确定不需要这样的能力可以显示的把这个功能禁掉,从而节省磁盘空间。
PUT my_index
{
"mappings": {
"my_type": {
"properties": {
"session_id": {
"type": "string",
"index": "not_analyzed",
"doc_values": false
}
}
}
}
}
副本机制
这个其实不用多说。ES的副本分片机制,目的是实现高可用,但是牺牲了空间。每个副本其实都是主分片的完整拷贝,在文档数量非常大的时候,这个对磁盘的占用是相当可观的。
测试对比
看上图,从上往下看,磁盘占用基本是一直在减少。很直观的看出上面讲的那些因素对ES磁盘的占用影响。
参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。