闲聊存储引擎选型

作者: 贺大伟 | 来源:发表于2018-09-16 21:57 被阅读86次

这个话题很大,最近正好遇到这样的问题,我想我对这个问题的理解经历了一个过程,从这个过程中我也认识到其实如果你不深入去实践,有些问题只能泛泛而谈(就像我现在说的这样)。我就讲讲我在一个文档索引项目中的心得。

内存 or 磁盘

一开始我们想可不可以把数据放在内存里呢?这样速度可以很快。

很快我们发现又几个问题不好解决:

1. go,java语言的GC问题在大规模内存存储场景下是一个大问题,因为我们多副本之间使用raft一致性复制协议,如果因为GC导致leader的心跳不能正常发送会引起大规模leader选举,系统几乎不可用,随着数据量越多,这个问题越明显。笔者曾经一个项目就遇到过类似的问题,当时为了提升cache 的命中率,增大了cache size,结果full GC导致系统发生大规模通信异常,频繁发生选举,系统几乎不可用。

2. 因为数据在内存中,一旦进程重启,数据恢复耗时很长,无论是通过网络快照还是本地快照,这个过程都很长,对于一个分片采用三副本备份的系统,意味着期间再发生一个副本异常那么这个分片不可用了,并且这个过程越长发生的概率就越高。

3. 因为我们是文档存储系统,支持全文检索,这样不可避免的,存储的数据会比文档自身的大小大不少,这样原本就相对紧缺的内存资源就存在更大的消耗。

基于以上三个理由,其实还有第四个理由,那就没有没有一个高效的内存存储引擎适合我们。最后内存方案放弃了。

国内的悟空索引是采用内存存储,有兴趣的同学可以看看。

BadgerDB or RocksDB

rocksdb是一个很成熟的KV存储引擎,开源社区有比较好的针对go语言封装的gorocksdb,采用CGO调用实现go对C/C++的调用。我们在使用bleve作为索引内核去学习和使用的时候就是采用这个引擎作为底层的存储引擎,bleve的index driver底层可以是各种KV存储引擎,bleve封装了薄薄的一层接口,只要适配这些接口即可作为bleve的底层存储。

badgerDB是一个针对大value优化的类似levelDB的KV存储引擎,采用go语言编写。

在实践的过程我们发现相比于rocksdb,badgerDB并不合适,主要是因为在kv存储模型下,bleve把文档以及倒排索引都打散成KV存储了,基本上很少有大value,导致读写性能不理想(原因在于key,value的都写都至少进过两次磁盘IO)。

不过rocksdb也好不到哪里去,我们在使用rocksdb的bleve(不是裸的引擎,是我们整个系统)与ES系统在相同的环境下测试,写的性能不及ES,延时波动也不及ES那么稳定。我们分析是因为两者使用了不同的存储引擎导致的(我们也使用过一些null store来测试除存储引擎之外的系统组件的性能,排除了这些干扰)。

segment file or KV

经历了以上这写痛苦和曲折之后我开始分析这里的核心逻辑,是什么引起这样的不同?

我想一句话就可以概括这个本质的区别,那就是:两者看待document的角度不同。

segment file系统把document作为整体去看待,无论读写都是如此,segment file中不同的segment之间几乎毫无瓜葛,segment 合并也很简单。

KV存储系统基本上分为两大类,LSM架构和Btree架构(还有一类hash 架构(比如bitcask),因为对range scan很不友好,不在讨论之列)。但是核心逻辑就是kv,全局有序。因此一个文档包括它的倒排索引都是一个个KV,即document = kv group。全局有序的好处是大大得,这一点无可争议,作为一个KV存储引擎,这个基本上也是必须要保证的,否则读的性能就太差了(尤其是range scan)。但是作为document的存储引擎,这种离散的KV group对document并不友好,因为它要满足自身的一些核心功能而额外做很多事情,而这些并不是document追求的,那么在相同的资源下,谁是更适合的就不言而喻了,实践也证明了这一点。

不过这里我也看到segment file有一个“死穴”:实时性(或者是笔者孤陋寡闻,也许已经有高效的解决之道了,不过可以肯定一点那就是这个问题一点儿也不简单)。而KV系统可以做到实时性,(btree 架构天然写的慢,这个不讲),LSM架构就是优化了写,并且保证mem table可实时读写。

segment file才刚刚开始,但是我觉得从战略的角度讲,这个抉择是对的。

从这次的思考中笔者认为在存储领域,如何看待你的存储对象,从这角度出发去选择或者开发存储引擎也许才能找到更适合自己需求的那一个。

相关文章

  • 闲聊存储引擎选型

    这个话题很大,最近正好遇到这样的问题,我想我对这个问题的理解经历了一个过程,从这个过程中我也认识到其实如果你不深入...

  • MySQL存储引擎、事务日志并发访问以及隔离级别

    MySQL存储引擎 MySQL是插件式存储存储引擎,支持多种存储引擎常见的存储引擎有:MyISAM, Aria, ...

  • 「Mysql索引原理(一)」1.存储引擎简介

    存储引擎 0. 前言1. 存储引擎查看2. InnoDB存储引擎特性存储InnoDB历史3. MyISAM存储引擎...

  • MySQL数据库中存储引擎和数据类型

    一.什么是存储引擎 二.操作存储引擎 查看存储引擎 1.查看mysql支持的存储引擎 2.看你的mysql当前默认...

  • 浅谈InnoDB存储引擎中的锁

    InnoDB存储引擎是MySQL数据库默认的事务型存储引擎,也是使用比较多的存储引擎。InnoDB存储引擎不紧支持...

  • MySQL常用配置查询

    版本查询 存储引擎查询 当前支持的存储引擎 查看当前默认存储引擎 查看表所使用的存储引擎 查看用户信息 查看当前登...

  • 分布式基础-存储引擎

    题目和文章内容有点不太符合,这里存储引擎是指单机存储引擎。对于分布式存储系统来说,存储引擎是必须的。存储引擎决定了...

  • MySQL进阶——存储引擎

    上篇文章我们学习了MySQL基础——事务,这篇文章学习MySQL进阶——存储引擎。 存储引擎 存储引擎就是存储数据...

  • mysql引擎选型

    参考:https://www.jianshu.com/p/5486ce134b75 InnoDB使用数据更新较为频...

  • Mongodb存储引擎

    插件式存储引擎API 插件式存储引擎API的引入为处理更多不同类型的业务提供了无限可能,内存存储引擎、事务存储引擎...

网友评论

    本文标题:闲聊存储引擎选型

    本文链接:https://www.haomeiwen.com/subject/qabfnftx.html