欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

落地数据的key-value的库 key-valueleveldbmysql

程序员文章站 2024-02-22 16:50:16
...

最近在做项目时,遇到了一个问题,现在没有非常好的落地数据的key-value的库。下面就总结一下现有的实现方式,结合使用过程中发现的问题,最后找到一个简单的实现自用的库的方法。

 

首先总结一下现有的实现方式

 

1.在mysql上层封装一层接口,将mysql变成一个落地数据的key-value库,然后加上memcache。

这种方式比较适合域读多写少的地方,因为mysql的写性能比较差。读的时候多数会命中memcache所以性能比较好。

针对写性能差的缺点,mysql也有自己的解决方法:读写分离加上主从同步。

建立多个mysql节点,一个节点设置为master,然后其他节点设置为slave(这是扁平的mysql架构)。

在master上开启bin-log,然后slave会读取master的bin-log。

问题:

在一块磁盘上的分表作用有多大?

考虑只读的情况,对建立索引的查询,大部分都是一次IO就可以完成读操作。分表的作用就比较小

如果有写的情况,mysql如果只是锁记录的话,则分表做的作用也非常小。

2.leveldb

leveldb是一个非常好的支持落地数据的key-value的库,它的读性能和写性能都非常好。

性能分析:

读性能:在写不是很多的时候,能保证一次磁盘IO就能得到随机读的数据。

写性能:leveldb采取了合并写的模式,普通的写都是写到内存中,然后过一段时间会顺序的写到一个disk上。所以写的性能也是非常好的。

然后分析一下具体使用问题

在使用的过程中也发现了非常多的问题:

1.leveldb的读性能不是很稳定。我们几个开玩笑的时候说,如果一个库一般情况性能好,但是在某些情况下的性能差,还不如在所有情况下都比较差。因为在评估机器的时候,如果性能差,可以采用scale-out的方式来扩展。

leveldb的merge是一个非常耗时的操作,在通常情况下,merge会涉及到11-12个文件,一个文件2M,就是所涉及到22M文件的读写,这个会花费200ms(200M/s),这个最坏的情况会涉及到24次寻道的时间,大约会花费200ms(一次10ms)。在这个时间内,如果有读请求需要磁盘IO,那么就非常困难了。

可能的解决方法:

1).缩小文件的大小有可能能解决这个问题,比如一个文件1M,这样能降低一次merge花费的时间,涉及的文件会变少。

2).通过merge中的限制,减少merge中间可能会涉及的文件的数目。在merge时,leveldb生成一个文件时,会考虑如果这个文件merge会涉及到多少文件,可以修改这个参数做到减少merge中间可能会涉及的文件的数目。

2.leveldb不支持主从同步。

这个问题比较容易解决,可以采用和mysql的解决方法一样的思路,dump+bin-log的方法。

 

组装自己的落地数据的key-value库

个性化的leveldb+主从同步,用组装这个词非常合适,嘻嘻。

附:mysql主从同步的实现思路。

今天还学习了一下mysql的bin-log的实现思路,bin-log中记录了insert,update,delete操作的具体内容,然后在slave上重现执行一下bin-log。这种bin-log在slave上的执行时间是和master上一样的,本来我还以为mysql会在binlog中记录内部数据的一些操作(比如B+树的操作和文件diff等等),这样应该能减少slave上的执行时间。但是这样就会让bin-log的设计非常复杂。