海量数据存储与快速查询(一)
接上篇文章,在经历很多尝试后,终于发现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.