超过内存容量的 KV Cache,你选择怎样的方案?

2012-06-30 00:54:13 +08:00
 clowwindy
我们需要做一个线上的 cache 系统,key 上亿,value 有多个 field。key 的访问频度分布不均,即只有一部分是热门 key,需要放在内存里。总数据量很大,超过总内存,所以也需要把一部分数据存在 SSD 上。也要求重启后能恢复大部分数据。

今天测试了 Redis 和 RethinkDB 的性能。

Redis 设计目标是纯内存 KV 数据库,用磁盘文件 swap 的功能已经废弃了。不过我还是测试了最后一个支持 swap 功能的 2.4 版。
Redis 打开 VM,在没有用超内存的情况下速度很理想,4 个 Redis 实例和几十个 Client 可以用满千兆网卡。超过配置的内存限额,开始使用 swap 之后,插入速度骤降到 20MB/s。并且客户端频繁遇到 timeout 错误,需要重试。磁盘 IO 很小, CPU 用满。瓶颈应该在查找最老的数据上。
Redis 的文档写得很好,作者 antirez 还亲自在 StackOverflow 上回答问题,比较了和 memcached 的优缺点,态度非常诚恳。

RethinkDB 是一个商业的磁盘 KV 数据库,为机械硬盘、SSD 和 Raid 做过优化,理论上说是最符合我们的需求的。
RethinkDB 直接用 SSD 的设备(而不是用 ext3 文件系统上的文件)做数据库时,10 Client 并发插入速度 80000qps,30MB/s。客户端很稳定,没有遇到 timeout。但无法知道文件系统现在使用了多少,也偶尔遇到 kill 掉之后重启时加载数据库文件失败,崩溃的情况。而它的文档很少,竟然一共只有一张网页,Support 也很冷清,无法解决问题。

Memcached 因为不支持 dump 到备份文件,也不能存储超过内存容量的数据,所以排除在外。

不知道大家有没有用过其它的方案?
7022 次点击
所在节点    Redis
11 条回复
phuslu
2012-06-30 00:55:48 +08:00
试下 MongoDB 吧。
clowwindy
2012-06-30 01:02:11 +08:00
@phuslu 谢谢。裸用 MongoDB,还是前面加上 Memcached,MongoDB 光做存储?不知道 MongoDB 直接面对线上的压力,能否扛得住。
lyxint
2012-06-30 01:55:53 +08:00
Kyoto Cabinet
Livid
2012-06-30 11:16:58 +08:00
这次在 Velocity 2012 见到了一家以色列公司的 GarantiaData,他们在做的方案就是解决 Memcached 和 Redis 的 Scale 问题。

http://www.garantiadata.com/

不过目前他们只在 AWS 上提供试用。

另外就是,KV Cluster 的话,你可以考虑试试 Riak:

http://basho.com/products/riak-overview/
phuslu
2012-06-30 12:34:51 +08:00
@clowwindy 裸用 MongoDB,做好 index 和 sharding,对于热数据,效率和内存数据库差不多的。
lfeng
2012-06-30 13:45:31 +08:00
@Livid Riak +1
virushuo
2012-06-30 13:57:26 +08:00
当年用过tokyocabinet倒是不错,现在好像不怎么见人提起了?不知道为什么。

另外key都上亿了,这就不应该算是"Cache"方案了吧,这应该算存储方案了。数据量到这么大,已经失去Cache的意义了。换个角度考虑可能会更好点?
clowwindy
2012-06-30 17:22:52 +08:00
@Livid 看了一下文档,Riak 的容错和 scalability 很吸引人,省掉了不少自己做 sharding 和冗余的功夫。谢谢推荐。

@phuslu @virushuo
数据和可用内存在同一数量级,稍微多了一点。用硬盘一是快速恢复,二是留下缓冲空间。
我们只使用 KV 存储,没有条件查询,大约每天会把所有数据都 set 一遍成新的,如果用 redis,关闭修改触发式 dump,改用每天定时手动 dump,因为只有溢出的 部分会写入磁盘,所以 set 性能可能会更高?
zhuang
2012-07-01 00:36:53 +08:00
大致说下我的理解,这是一个上亿的 kv 数据库,写入远大于查找,有明显访问热点,以及需要数据持久化的情形。目前的问题有两个,内存不够,性能不够好(第二条不知道是不是有需要)。

在架构不做改动的情况下,加内存是最好的办法。看前面的说明没有提到集群,如果是单点服务器的话,32GB 内存大概能支持 10^8 kv 吧,不过 32GB 确实是很多小型服务器支持的内存上限,如果是硬件的限制那就没办法了。

数据持久化方面,我觉得传统数据库不如 redis 方案,而且每天一次 dump 保存到 ssd 已经是很好的办法了。性能方面,因为只有共享写入才会产生瓶颈,假如热点数据并发写入较多,还是分离出去比较好,其他地方应该不会存在瓶颈,有也是硬件级别的。

如果未来数据规模不会增长太多,硬件升级成本比软件架构更新的维护管理成品应该是少的,如果数据规模还会进一步扩大,转向集群应该是必然的。
muxi
2012-07-01 10:08:08 +08:00
membase
clowwindy
2012-07-01 11:44:11 +08:00
@zhuang 查找还是大于写入的,并且存在热点。写入则不存在热点。目前用了 8 台机器。
redis 在没有 swap 的时候,确实性能很好。swap 之后性能差了一个数量级,并且 swap 内存限制有时不起作用,写入超过内存一定数量后就 OOM 被 kill 了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/40959

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX