redis-storage icon indicating copy to clipboard operation
redis-storage copied to clipboard

与redis的关系

Open aloasut opened this issue 11 years ago • 17 comments

请问这个实现是把redis原来放在内存的数据通过leveldb放在硬盘这样子吗?然后一切操作都跟原生的redis一样?还是说只有加强版的那些命令存取的数据是通过leveldb引擎存放,其他的还是原生redis一样放在内存?

aloasut avatar Dec 28 '12 10:12 aloasut

你理解是对的。 逻辑上和memcache + mysql 类似 ( get命令从内存中取,没取到数据,再用dsGet从leveldb里取) 但效率和速度不可同日而语。

shenzhe avatar Dec 28 '12 12:12 shenzhe

我举个很简单的例子

--这些是在redis的内存中完成 set name qiye get name

--这些是在leveldb操作的 ds_set name qiye ds_get name

ds_开头的命令存取的数据是通过leveldb引擎存放,其他的还是原生redis一样放在内存

qiye avatar Dec 28 '12 16:12 qiye

其实redis-storage在redis基础上增加了leveldb的“客户端”功能,可以用来处理leveldb数据库,这样好理解些。

LazyZhu avatar Dec 29 '12 04:12 LazyZhu

哈哈不是客户端功能。增加了leveldb服务端功能。因为 ldb只是个存储引擎。没有服务端。

qiye avatar Dec 30 '12 06:12 qiye

性能下降的原因是什么?leveldb磁盘操作会导致阻塞,而redis只有单线程的缘故吧?


但效率和速度不可同日而语。

allenlz avatar Jan 06 '13 16:01 allenlz

首先你了解下leveldb的写操作就知道他为什么写比读还快。 况且如果是主从配置的话,就更不会阻塞了。 主可以是纯的redis,可以关闭rdb或aof , 从库是leveldb,做持久化数据。 下一步,我正好要改造主从复制这块,可以直接把数据复制到leveldb里。这样就更省事了。

shenzhe avatar Jan 07 '13 02:01 shenzhe

个人对leveldb还算比较熟悉。

即使是顺序写,写磁盘操作和内存操作的耗时也不是同一量级。leveldb内部的磁盘操作是没有挂到事件堆里的,如果是单线程,当压力大时(引擎自身的,或者是外界导致磁盘压力大时),必然会阻塞住的,从而导致整体吞吐下降。 即使是主从分离,incr操作也要先读后写吧。

另外,个人认为redis做主、leveldb做从的价值有限,因为整体数据量会受限于主机的总内存大小。并且主从切换会变的很麻烦。

整体的性能有benchmark数据么?

allenlz avatar Jan 07 '13 02:01 allenlz

另外有一个叫做SSDB的项目:https://code.google.com/p/zdb/ 是自己实现的服务器端。思路好像清晰一些,除了set外的redis数据类型都支持。看起来就是redis的持久化实现了。他的主从同步据说考虑到了网络差的情况,比redis优秀。

aloasut avatar Jan 07 '13 03:01 aloasut

里面提到 http://www.udpwork.com/ 用了 zdb ?

rchunping avatar Jan 07 '13 03:01 rchunping

是呀,他说用到了生产环境。把用户库放到了zdb。

aloasut avatar Jan 07 '13 03:01 aloasut

@aloasut: 我是SSDB项目的创建者. 根据业务开发的经验, 我发现zset数据结构的表达能力非常强大, 同时, 我们遇到了redis内存限制以及主从同步不完善的瓶颈, 所以在LevelDB上面寻找解决方案.

SSDB支持zset, 不过不是完全支持, 例如zcard, 我的思路是使用者自己维护计数. 新浪微博的经验也是使用独立的计数服务维护各种集合的计数.

SSDB的主从同步, 利用LevelDB来持久化更新log, log里只记录变更的key, 而没有value, 所以可以保存非常大的更新log(默认是100万条), 并根据序号(LevelDB内部序号)进行断点续传. 所以, SSDB可以容忍不稳定的网络.

对于 redis-storate, 我有个问题: ( get命令从内存中取,没取到数据,再用dsGet从leveldb里取) -- 这是发生在服务器端的行为吗? 还是说要求客户端(PHP)主动调用 ds_get 命令?

ideawu avatar Jan 07 '13 03:01 ideawu

请教ssdb是如何应用到你们会员系统的? 在 2013-1-7 上午11:52,"ideawu" [email protected]写道:

@aloasut https://github.com/aloasut: 我是SSDB项目的创建者. 根据业务开发的经验, 我发现zset数据结构的表达能力非常强大, 同时, 我们遇到了redis内存限制以及主从同步不完善的瓶颈, 所以在LevelDB上面寻找解决方案.

SSDB支持zset, 不过不是完全支持, 例如zcard, 我的思路是使用者自己维护计数. 新浪微博的经验也是使用独立的计数服务维护各种集合的计数.

SSDB的主从同步, 利用LevelDB来持久化更新log, log里只记录变更的key, 而没有value, 所以可以保存非常大的更新log(默认是100万条), 并根据序号(LevelDB内部序号)进行断点续传. 所以, SSDB可以容忍不稳定的网络.

对于 redis-storate, 我有个问题: ( get命令从内存中取,没取到数据,再用dsGet从leveldb里取) -- 这是发生在服务器端的行为吗? 还是说要求客户端(PHP)主动调用 ds_get 命令?

— Reply to this email directly or view it on GitHubhttps://github.com/qiye/redis-storage/issues/1#issuecomment-11940110.

aloasut avatar Jan 07 '13 04:01 aloasut

@ideawu 目前有 rl_get命令支持。(内存中取,没取到数据,再从leveldb里取)zset等redis相关命令,在 redis-storage 会持续实现。

@aloasut 我不知道你的业务场景是如何的bt,以致于性能这么吃紧。 目前我这边的设想就是用leveldb来解决 redis 数据始终必需在内存的问题。 大概思路是这样: 主库是纯内存redis ,关闭rdb,aof, 从库是 leveldb, 主库里的数据强制设置一个生命周期(比如三天),这个生命周期是动态的(最后一次读取的时间点 + 三天) 三天内这个数据都没读到,就会变成冷数据,从redis里淘汰掉,再要取的话,就从leveldb里取了。 只要数据被读取到,就变回热数据 理论上,再怎么活跃的网站,冷数据还是占绝大多数的,而leveldb用于冷数据的读取,应该就是足够应付的。 主从复制,一般来讲,从库做批量sync到leveldb ,应该压力会小很多, 更可以打开aof ,保持数据的更强的完整性。

shenzhe avatar Jan 07 '13 06:01 shenzhe

@shenzhe 你这种冷热数据的设想太好了。我现在在维护一个约千万级别的用户库。是在redis保持30天用户基本信息,过期就去数据库查,数据库在并发大的时候也有点压力,现在有点想把mysql存的数据都迁移到leveldb。但是leveldb是写的性能好于读的性能,所以正在评估中。非常感谢你的解释。

aloasut avatar Jan 07 '13 11:01 aloasut

目前我维护的是 两千万上下的用户库。 数据存在redis-storage 上。 然后加上redis 自己的缓存。用lua 封装了下 供客户端调用。 效率杠杠的。 以后打算把帖子信息 也转意到redis-storage来

qiye avatar Jan 07 '13 12:01 qiye

@qiye 你说的“然后加上redis 自己的缓存”说的是redis-storage 中的redis服务,还是从官方版本的redis呢?

bestsunnyandy avatar Mar 06 '13 02:03 bestsunnyandy

@aloasut 如果主redis不做rdb/aof持久化,从redis使用leveldb进行持久化,那么从redis每次set的时候是直接写透内存写到leveldb吗?这样会有一个问题就是从redis的写性能会成为瓶颈。redis的主从备份是异步的,当主redis挂掉之后,因为主从写性能差距较大(一个有持久化,一个没有),切主会有数据不一致问题,或者说要等从redis同步完成之后才能切主,有可能导致切主长时间不能提供服务,影响可用性。

hgqislub avatar Mar 16 '15 07:03 hgqislub