V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
tanteng
V2EX  ›  Redis

如何取出大数据量的 redis hash 结构的数据并遍历导出?

  •  
  •   tanteng ·
    tanteng · Mar 1, 2016 · 28868 views
    This topic created in 3709 days ago, the information mentioned may be changed or developed.

    redis hgetall

    如图,存了一个 hash 结构的数据, key 是用户名, value 是这个用户的一些信息,这个 hash 结构的数据会增长,最后数据量可能非常大。

    假如用 hgetall 一次取出所有数据,然后去遍历导出,大数据的情况可能会: 1.影响其他 redis 的操作 2.内存溢出

    需求是把这个 hash 结构的数据导出,比如导出到数据表或者 excel 文件。

    有什么好的技术实现方法?谢谢!(程序语言 PHP , JAVA , Python 都可以)

    26 replies    2016-04-14 18:55:06 +08:00
    yuankui
        1
    yuankui  
       Mar 1, 2016   ❤️ 1
    一定是设计出了问题
    soli
        2
    soli  
       Mar 1, 2016   ❤️ 2
    你需要的是 HSCAN : http://redisdoc.com/hash/hscan.html
    tanteng
        3
    tanteng  
    OP
       Mar 1, 2016
    @yuankui 那像这种一开始没有记录到数据库,直接存到 redis 的数据,如何导出呢
    Jaylee
        4
    Jaylee  
       Mar 1, 2016   ❤️ 1
    先 keys * 取所有 key , 然后遍历
    tanteng
        5
    tanteng  
    OP
       Mar 1, 2016
    @Jaylee 先 hkeys key ,然后根据这个 key 去遍历取 hash 的数据?? 1.这个 keys 可能非常大有没有影响 2.这样会大大增加操作 redis 的次数,是不是问题
    Jaylee
        6
    Jaylee  
       Mar 1, 2016   ❤️ 1
    @tanteng 1, 没有影响 2.不是问题
    zhs227
        7
    zhs227  
       Mar 1, 2016   ❤️ 1
    @tanteng Redis 官方原来有个加密的功能,但是官方说你们不应该太相信这个功能,因为 Redis 的存取速度太快了,破解起来飞起。

    http://redis.io/commands/AUTH

    Note: because of the high performance nature of Redis, it is possible to try a lot of passwords in parallel in very short time, so make sure to generate a strong and very long password so that this attack is infeasible.

    高速存取是 Redis 的优势,操作次数根本不是问题。
    kingddc314
        8
    kingddc314  
       Mar 1, 2016
    可以使用 redis 内的 lua 脚本进行处理
    EVAL script numkeys key [key ...] arg [arg ...]
    kingddc314
        9
    kingddc314  
       Mar 1, 2016   ❤️ 1
    可能理解错了楼主的意思,同 2L ,你需要的应该是 HSCAN 进行遍历
    tanteng
        10
    tanteng  
    OP
       Mar 1, 2016
    @kingddc314 hscan 只支持 2.8 以上版本
    ynztyl10
        11
    ynztyl10  
       Mar 1, 2016
    keys * 确认没问题?不要误导。。
    fwrq41251
        12
    fwrq41251  
       Mar 1, 2016
    像这种情况一般还会有个 set 存所有用户的用户名吧。这样直接取这个 set,再根据 key 遍历就好了。
    zts1993
        13
    zts1993  
       Mar 1, 2016
    hscan 啊。。。。。
    tanteng
        14
    tanteng  
    OP
       Mar 1, 2016
    @fwrq41251 并没有
    rubytek
        15
    rubytek  
       Mar 1, 2016
    @tanteng 是说设计成自带一个 Key 的集合啊。
    tanteng
        16
    tanteng  
    OP
       Mar 1, 2016
    从集合中取出所有用户 id ,和从 hash 中通过 hkeys 取,有什么不同吗
    tanteng
        17
    tanteng  
    OP
       Mar 1, 2016
    @rubytek 从集合中取出所有用户 id ,和从 hash 中通过 hkeys 取,有什么不同吗
    neoblackcap
        18
    neoblackcap  
       Mar 1, 2016   ❤️ 1
    @tanteng 一个是全部读到你 Client 端的内存里面,在 Client 端以一个数据结构或者对象的形式存在。一个只是一个迭代器。
    简单而言,内存消耗不一样。
    soli
        19
    soli  
       Mar 1, 2016   ❤️ 1
    KEYS 、 HGETALL 等命令应禁止在生产环境使用。看官方文档,都有非常显眼的警告。
    tanteng
        20
    tanteng  
    OP
       Mar 1, 2016
    @neoblackcap 这个明白,但是要 2.8 才支持 hscan
    tanteng
        21
    tanteng  
    OP
       Mar 1, 2016
    @soli 看来不能用这种方式
    solaro
        22
    solaro  
       Mar 9, 2016
    @Jaylee 你这种做法就是要坑死楼主的, keys * 在生产环境里我都是禁用的,量大的时候秒蹦你缓存你信不信,执行一次得卡上 N 秒或者 N 十秒
    tanteng
        23
    tanteng  
    OP
       Mar 9, 2016
    @solaro 还没着手做这个,用 hscan 是否可行?
    solaro
        24
    solaro  
       Mar 9, 2016
    如果是我,我会这么做:
    1.一个 hash , hash-key :uid, hash-value:zsetid_uid
    2.一个 zset, id:uid ,value : user info
    各种好判断, hash 效率高,单量小, zset 可以用来分页,分段取出
    甚至你存储的时候可以做 shard
    solaro
        25
    solaro  
       Mar 9, 2016
    如果 hash 丢了,重建结构简单,
    如果 zset 丢了,重建,也不难。
    当然,你那个 hash 其实从业务上来说是最简单的
    abc123ccc
        26
    abc123ccc  
       Apr 14, 2016
    @tanteng 建议:
    方案 1 、凌晨某个点,一次 hgetall 把 key 写入到队列当中,这样你的队列与 hash 就能保持一致了,以后取数据就相当的容易。因为 list 里的值就为 hash 的 key 。但可以告诉你的是:一次性读入大量的数据,整个网站都会很慢。

    方案 2 、如果你的 hash 的 key 是有规律的,那就写个程序往 list 里赛吧,定时定量跑。跑完为止。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1196 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 18:02 · PVG 02:02 · LAX 11:02 · JFK 14:02
    ♥ Do have faith in what you're doing.