如何实现简单的过期机制

101 views
Skip to first unread message

Yin Xu

unread,
Dec 3, 2014, 5:42:28 AM12/3/14
to bea...@googlegroups.com
由于实际需要,需要实现一个简单的过期机制。不需要非常精确的过期,只需把最老的.data文件整个删掉。

尝试了几种利用外部脚本的办法:
1. 直接删掉最老的.data和.hint.qlz,然后重启benasdb.这种办法简单干脆,但是重启时需要重新生成htree,这样会有1分钟以上的服务中断。
2. 删除所有创建时间比需要删除的data文件最后修改时间早的文件,然后flush_all xxxx xxxx为需要删除文件的最后修改时间到现在的时间,这样flush_all时这些老文件的空间就收回了。坏处是要遍历一遍benasdb造成一段时间的io读写增大,而且整个删除过程耗时比较久。是否能有一个更好的办法拿到某个.data文件中的key,不用遍历beansdb?


请问大家有更好的办法或者优化上面两种方法吗?需要满足服务不中断,io读写压力尽量控制小,操作时间能比较短

Davies Liu

unread,
Dec 3, 2014, 12:13:52 PM12/3/14
to bea...@googlegroups.com
可以改进一下方法一,删除最老的.data和 .hint.qlz 文件,然后touch 一个 空 .data文件(保证次序不变)。把目录中的所有文件(出去最新的数据文件.data)做符号链接到另外一个目录,并启动 beansdb 来让它重建 htree,生成 .htree文件。
最后关闭原先的 beansdb(并删掉可能生成的.htree),最后把生成的 .htree 文件拷贝回源目录,启动 beansdb, 它应该会增量读取 .qlz.gz 文件,比重建整个 htree 快很多。


-- 
Davies Liu
Sent with Sparrow

--
You received this message because you are subscribed to the Google Groups "BeanDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beandb+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Yin Xu

unread,
Dec 3, 2014, 10:19:03 PM12/3/14
to bea...@googlegroups.com
谢谢Davies的回复,这样确实会快一些。
不知是否可以提这样一个意见加入到后续的beansdb功能中来实现一个简单的过期机制而不必要重启:
设计一个类似于flush_all 的命令,比如叫 expire time, 其作用是遍历删除所有过期data文件并更新htree,如果可以重命名.data保证从000开始(避免文件增长到256)。这样的过期机制在实际应用场景非常有用:
可以考虑一个2层的文件存储,底层用普通硬盘存储所有图片,上层用固态硬盘存储需要高频访问的文件(有一定的时效性)。在我们的实际环境中需要放在固态硬盘的数据是T级别的,所以memcached对我们来说不如直接上3T固态硬盘来的合算,但苦于一直没用一个好的过期机制,让服务持续运行而不需要人工干预.
有考虑过rocksdb,但总觉得没有benasdb简单易用

在 2014年12月4日星期四UTC+8上午1时13分52秒,Davies写道:

lifeweaver

unread,
Dec 3, 2014, 10:29:15 PM12/3/14
to bea...@googlegroups.com
建议可以采用SSDB,支持redis协议:
1、set时可以设置过期时间,SSDB会自动删除;
2、针对SSD盘,可以把SSDB的leveldb引擎换成rocksdb引擎;

Yin Xu於 2014年12月3日星期三UTC+8下午6時42分28秒寫道:

Yin Xu

unread,
Dec 4, 2014, 5:52:29 AM12/4/14
to bea...@googlegroups.com
这个有考虑过,但没有beansdb简单方便。配置太复杂,参数没有调整好性能会有比较大的差别,贸然在应用环境中更换风险有点大。我们有做过压力测试,可能是参数的原因,出现了一些问题,主要担心compaction时发生阻塞现象。半夜被老板抓起来干活这是非常痛苦的事情:(
另一方面喜欢beansdb这种简单优美的做法,在作为文件存储时非常符合我们的需求。

在 2014年12月4日星期四UTC+8上午11时29分15秒,deep写道:

Davies Liu

unread,
Dec 5, 2014, 1:10:59 AM12/5/14
to beandb
或许可以这样做:

1. 加一个过期时间的命令行参数(默认为零,即不过期),如果设置了的话,就启动一个后台线程来扫描需要过期的值,以数据文件为单位整体删除。
2. 当发现有一个数据文件的最后一个记录已经过期时,加载 hint.qlz 文件,从内存中删除对应的索引(当它指向当前数据文件时)。最后删除数据文件
3. 这样数据文件的序号会不断增加,我们可以允许它超过256,只要保证工作集不超过256就可以了,比如工作集的序号可以是 100 -
300, 它们仍然可以用一个字节来表示100 - 44,加一个函数做这种换算就可以了。或者也可以字节用两个字节表示,会增加大概 5%
的内存开销,也要改不少代码。

如果你有兴趣的话可以尝试一下。
> --
> You received this message because you are subscribed to the Google Groups
> "BeanDB" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to beandb+un...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
- Davies
Reply all
Reply to author
Forward
0 new messages