前言
Elasticsearch 7.10版本最近发布,该版本有一个重磅特性Searchable snapshots可搜索快照功能,因为该功能可以大幅度地降低存储成本,我们对这个特性也是期待已久。所以Searchable snapshots这个功能的使用方式和实现效果是怎样的呢,让我们来一探究竟吧!
功能介绍
在Searchable snapshots可搜索快照功能发布之前,通过调用_snapshot API对索引打的快照,不管是存储在S3还是HDFS或者是腾讯云的对象存储COS上,都是不能够直接进行查询的,快照只能用于数据的冷备份,如果需要查询的话需要先调用API把快照恢复到集群中,当快照中的索引初始化完成后,才可以去查询。而可搜索快照功能就使得存储在远端S3、HDFS、COS中的快照能够满足查询的需求了,ES的数据文件不是只能存储在本地文件系统上,还可以支持存储在远端的S3、HDFS、COS等存储介质上,实际上实现了存储与计算的分离。
Searchable snapshots可搜索快照功能会给ES带来新的繁荣,因为有非常多的用户使用ELK架构构建日志系统,日志的数据量是非常大的,但是查询的频率一般比较低,所以用户有个痛点是在满足基本查询需求的条件下同时降低ES的存储成本。现在基于Searchable snapshots可搜索快照功能,可以把大量的比较旧的索引都存储到S3/COS上,真正需要查询的时候可以去查询S3/COS中的数据。因为S3/COS本身成本是非常低的,大约只有SSD磁盘的十分之一,所以使用ES存储数据的成本大大降低了。另外一方面,可搜索快照功能也可以提高集群的稳定性,可以仅仅使用一个较小规模的集群支撑最近一段时间热索引的读写即可,老的索引都可以存放在S3/COS中,真正需要查询的时候再去查S3/COS中的数据,因为集群规模小,不至于出现一个超大规模的集群存储所有的数据,从而导致集群不稳定的现象发生。
不过就当前7.10版本的可搜索快照功能的特点来看,没有我们预想的可以完全实现存储计算分离,因为当把一个存储在S3/COS上的快照mount到一个集群中时,需要先执行快照恢复,把快照中的文件从S3/COS读取到集群的本地磁盘上,快照中的索引先进行初始化,索引所有的数据文件恢复完毕后该索引才变为green,看起来和我们手动去从快照中恢复索引没有什么两样。区别在于Searchable snapshots可搜索快照功能时,在执行快照恢复的这段过程中索引仍然是可以查询的,如果集群本地磁盘上的索引文件不存在的话就直接去S3/COS中去读,只不过读的过程会比较慢。
而为什么需要先把数据文件从S3/COS恢复到本地呢,官方的解释是这样可以保证查询性能,在一个可搜索快照中的索引完全初始化完成后,读取该索引和读取普通的索引的性能几乎没有差别。实际上可搜索快照类型的索引在集群的本地磁盘上存放了完整的一份数据文件,只不过命名规则和普通的索引不一样。
因为当前7.10版本的可搜索快照功能,因为数据还需要从S3/COS中恢复到集群的本地磁盘上缓存一份,所以该功能真正的用处在于可以节省最多一半的存储空间。可搜索快照类型的索引在集群中默认副本数为0, 数据的可靠性以及弹性完全交由S3/COS来保证,不需要额外给索引增加副本,从而可以降低一半的存储成本。当集群中可搜索快照类型的索引的分片因为节点故障不可用时, ES会自动地从S3/COS中读取分片对应的数据文件进行恢复,从而保证数据的可靠性;如果需要提高可搜索快照类型的索引的副本数量,也是直接从S3/COS中读取数据,而不是从本地磁盘上复制主分片的数据文件。
利用当前版本的可搜索快照功能,我们可以对一些老的查询频率非常低的索引,先备份到S3/COS,之后删除,然后再把备份好的快照mount到集群中,使得这些索引下需要的时候仍然可以查询。在极端情况下,实际上只需要对这些老的查询频率非常低的索引,只进行备份,真正需要查询的时候再mount到集群上,当然,需要容忍缓慢的查询过程。
当前7.10版本的可搜索快照功能的为Beta版,社区里也给出了该功能的路线图,会在将来的版本中实现完全的计算存储分离,直接去访问S3/COS中的索引数据完成查询, 而不是像当前这个版本需要先恢复到本地磁盘中。
所以,总的来说,当前7.10版本的可搜索快照功能,一方面可以降低一半左右的存储空间,大大的节省了成本;另外一方面保证了从快照中恢复到集群上的索引的查询性能,使得应用层不必感知到这种新的存储方式带来的变化。
使用方式
可搜索快照的使用方式比较简单,我们可以选择通过手动调用API来把远端的快照mount到集群中,也可以在ILM中使用。
1. 手动mount快照
直接调用API:
POST /_snapshot/my_repository/my_snapshot/_mount?wait_for_completion=true
{
"index": "test",
"renamed_index": "test1",
"index_settings": {
"index.number_of_replicas": 0
},
"ignored_index_settings": [ "index.refresh_interval" ]
}
上述操作把快照my_snapshot
中的test
索引挂载到集群中,重命名为test1
, 挂载后的索引副本数设置为0, 同时忽略掉旧索引中设置的index.refresh_interval
参数。
在执行完上述操作后,可以看到集群中出现了一个新的索引test1, 集群当前状态为yellow,test索引的分片执行初始化,初始化完成后,test1索引状态变为green。
此时查看新索引test1的settings,发现其和普通的索引有以下不同点:
{
"test1":{
"settings":{
"index": {
"blocks":{
"write":"true"
},
"recovery":{
"type":"snapshot_prewarm"
},
"store":{
"type":"snapshot",
"snapshot":{
"snapshot_name":"test",
"index_uuid":"p1Opq7gdQz6WTeKgiIEaTw",
"index_name":"test-aggregation-2020-11-25-02",
"repository_name":"my_repository2",
"snapshot_uuid":"Muy7vsiLSWKbQf3mJALfLw"
}
}
}
}
}
}
- index.blocks.write默认为true,也即可搜索快照索引默认是只读的
- index.recovery.type为snapshot_prewarm, 意味着数据是从快照中恢复的
- index.store.type为snapshot,区别于普通索引的fs方式
另外需要注意的是,索引test1恢复到green后,除了索引的部分元数据和底层的数据文件命名方式与普通的索引不同,索引自身的一些数据结构如FST也是常驻内存的,并不会在查询完毕后自动释放掉内存,所以此时已经和普通的索引区别不大了。当然,新索引test1也是可以冻结的,冻结的执行过程和普通的索引相同。
2. 在ILM中使用
在ILM索引生命周期管理中也可以使用可搜索快照功能,通过API使用该功能的基本用法如下:
PUT _ilm/policy/my_policy
{
"policy": {
"phases": {
"cold": {
"actions": {
"searchable_snapshot" : {
"snapshot_repository" : "my_repository",
"force_merge_index": true
}
}
}
}
}
}
对于使用上述ILM策略的索引,在cold phase会首先把该索引备份到指定的快照仓库my_repository
中,然后再把快照中的索引挂载为一个可搜索快照的索引。使用过程中需要注意以下两点:
- 可搜索快照只能在cold phase使用
- 如果ILM策略有配置delete phase, 默认情况下,在delete phase会主动删除cold phase中的可搜索快照, 因此需要在delete phase中显式设置delete_searchable_snapshot为false
- 默认情况下force_merge_index为true, 也即在索引进入到cold phase时,会先把索引force merge到1个segment,然后再备份到快照仓库中。此举一方面是为了降低存储到S3/COS上的存储成本,同时降低后续从S3/COS中拉取数据时的产生的费用,文件越少读取S3/COS产生的费用就越低;另外一方面当数据从S3/COS恢复到本地后,也可以获得较好的查询性能。
比较遗憾的是,在当前7.10版本中,还不支持直接在kibana的索引生命周期管理页面中,通过操作界面直接使用可搜索快照功能。
未来展望
Searchable snapshots可搜索快照功能,在当前Beta版本中,仍然需要把存储在远端S3/COS中的数据恢复到本地缓存起来,所以可以节省的存储成本是有限的。所以,官方也给出了可搜索快照功能的路线图:
结合Data tiers数据分层功能我们看到,当前Beta版的可搜索快照是用在数据分层的Cold层,在该层中的索引一般是只读的,但是仍然需要保证一定的查询性能,所以在Cold层可以把数据先从S3/COS中恢复到集群的本地磁盘上,做一层缓存,查询索引的时候优先从本地缓存中读取,这样查询性能就有了保证。但是数据的可靠性或者弹性可以完全由S3/COS来保证,因此在Cold层中的索引,可以只保留主分片,当主分片所在的节点故障时可以从远端的S3/COS中恢复数据,这样存储成本就降低了一半。
而官方未来的规划,是要开发Frozen层,在该层中的索引,对查询性能没有较高的要求,因此可以直接去查询S3/COS中的数据,而不需要再把数据从S3/COS中恢复到本地缓存起来。因此在Frozen层,才真正实现了存储与计算的分离,带来的影响是不可估量的,因为一个集群能够支撑的数据存储量可以无限大,用户的成本可以大大的降低。
然而,在Frozen层,直接去查询存储在S3/COS上的数据,查询性能就完全取决于S3/COS的API接口的性能,可能会造成查询过程非常缓慢。而在早先的版本中,ES已经实现了异步查询Async search, 提交查询请求时只返回一个ID, 后续通过轮询这个ID获取到查询结果,在轮询过程中可以获取到查询的部分结果,直至查询结果完全返回。因此Async search就解决了在Frozen层因为查询数据缓慢带来的的体验效果不好的问题。
所以,在将来Frozen层开发完成之后,我们可以借助于完全实现存储于计算分离的可搜索快照功能,根据需要从S3/COS中去查询数据,真正做到按需加载,查询完毕后,此次查询而加载的内存数据将会自动释放,不仅节省了大量的存储成本,也因为集群的规模可以变得非常小而使得集群的稳定性大大地提高。
所以总的来说,不光是Searchable sanpshots功能,还有Data tiers数据分层功能,都还在逐渐演进的路上,两者结合起来,将会给Elasticsearch带来革命性的变革!