海量数据存储与快速查询(一)

接上篇文章,在经历很多尝试后,终于发现kt+leveldb有下面无法避免的缺点:

1. Leveldb原生只有压缩操作,数据的清理是依赖重复key的,但是kt封装后,会失去这一特性,导致内存无法释放,需要修改leveldb源代码解决。

2. kt+leveldb 封装,由于其非原生,不能满足性能需求,KV平均负载在1k/s左右,虽然业务逻辑使他变复杂,但是1k的处理速度不能满足现在的需求。

结合上面的考虑,还是要做一个更加强大的系统,为了解决问题:

A. 更灵活、简单的历史数据释放机制,避免负载、高IO、难维护的清理操作。

B. 根据业务逻辑,需要快速查询出同一维度的所有key。

    目前已有的逻辑是封装了额外几倍KV(string,string)查询、写入来实现的。

    需要尽可能简化,这样才会真正有提速。

----

考虑了很长的时间,决定放弃leveldb+kt的封装模式(主要原因还是他太复杂了,维护成本初始就很高),切换为 redis引擎,优点和缺点如下:

1.  更简单,相比kt+leveldb的复杂封装、维护,redis 2.6以上版本的安装、使用非常简单。

2.  更快,redis为存储、服务一体,比kt+leveldb两层封装更快。

3.  支持更多结构,这里我们会额外用到list范式,来简化业务逻辑。

4.  更好的调试模式。redis原生支持很多操作命令。

缺点:

1.  在高性能目标下,落地相比于使用,需要做额外工作。

2.  内存使用听说很大,仍旧不清楚是否能够hold住过亿数据。

----

新架构下,A问题的解决:

   旧的历史数据,是采用定时器清理的方法,不断检查,内存的存储区中,是否有超时数据,发现后清理。

   但是数据的维护开销较大,并且因为使用了kv的映射,在还原到内存矩阵中时,需要增加row-index的维护,由此出现了比较多的 index 申请、释放、重用逻辑。

   新架构的优化,站在数据的时间维度角度看。

    既然历史数据是会超时淘汰的,那么是否可以分小时保存?例如缓存最大3小时数据,那么3小时前的数据块是可以整块淘汰、清理、重用的。 这样,复杂的数据检查、刷新、重用,被我们转化为简单的分块存储,释放,重用逻辑。

   这样的改动,简单的理解是用空间换取复杂度的节省,但是实际上是架构的进步,做到更简单,更纯粹,就更好控制和扩展。

   此外,预估每小时数据在千万级别,根据业务模式计算,1小时使用内存在1G左右,即使使用4G内存,对于32/64G的服务器来说也是绰绰有余的。

 

有点晚了,B问题的解决留在(二)里描写。

Send from MarsEdit.

 

posted @ 2014-04-23 00:03  miuc  阅读(2271)  评论(0编辑  收藏  举报