V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fxrocks
V2EX  ›  Redis

全量读取速度

  •  
  •   fxrocks · 2021-01-03 15:34:40 +08:00 via Android · 2852 次点击
    这是一个创建于 1424 天前的主题,其中的信息可能已经有所发展或是发生改变。
    有 1 万多个用户,用户名为 key,hash 形式存储,use1:{k1:v1, k2: v2,...kn: vn}, 每天需要 load 一次所有用户,每个用户每次提取大概 10 个字段。

    求问
    1 。server 本机上用 Python redis 这样读一次大概多久? 10 万呢?
    2 。user 列表是否要有必要单独一条 kv 存储?
    17 条回复    2021-01-06 14:20:39 +08:00
    YouLMAO
        1
    YouLMAO  
       2021-01-03 15:38:04 +08:00
    扫库操作, 自动被 dba 的监控脚本拦截了, 不要骚操作
    fxrocks
        2
    fxrocks  
    OP
       2021-01-03 16:20:05 +08:00 via Android
    @YouLMAO 自己搞得,没有 dba :D,那有其他办法吗?我用 Python redis
    YouLMAO
        3
    YouLMAO  
       2021-01-03 16:22:30 +08:00
    分段扫描 SCAN 0 COUNT 100 MATCH papapa*
    RedisMasterNode
        4
    RedisMasterNode  
       2021-01-03 17:26:26 +08:00
    只有 1w 个用户,既然没有 dba,考虑到数据量也很小,如果可以接受阻塞其他命令,直接 keys user:*这样的操作即可。从哈希表中 scan 出这么点数据耗时会很低;而且不是可以自己实践测试一下吗,向 redis 里面写 10w 个用户 key 非常快吧
    niubee1
        5
    niubee1  
       2021-01-03 17:28:28 +08:00
    你先搞清楚为嘛要这样做,从源头分析,万一你的方案从根本上就不对呢
    Ptu2sha
        6
    Ptu2sha  
       2021-01-03 17:56:36 +08:00
    一万条小 case 啊 redis 很快的
    当然单机 rdb 或从机拉下来处理最好
    fxrocks
        7
    fxrocks  
    OP
       2021-01-03 18:21:03 +08:00
    @niubee1 因为偷懒不想搞 mysql 之类,搞关系麻烦,redis 都堆在一个 hash 里方便啊 :D, 查询和更新单个用户数据也快。就是每天读一次所有 key 感觉不太爽。

    @RedisMasterNode 嗯,等下试一试。

    @Ptu2sha 单机 rdb 是指复制 rdb 到另外机器然后再读取?。。。
    crclz
        8
    crclz  
       2021-01-03 18:29:30 +08:00
    你是准备把 redis 当 mysql 使吗?想想 ACID 有保障吗?
    如果是对 redis 以及缓存了解不深的人,我推荐你只将 redis 用于缓存,严格按照:查数据库时写缓存、数据库更新时 invalidate 缓存、缓存条目自动过期。

    另外,如果想要方便,可以用 mysql json 或者 postgres jsonb,或者 mongo
    fxrocks
        9
    fxrocks  
    OP
       2021-01-03 18:50:53 +08:00
    @RedisMasterNode

    试了一下读写 10 万条 10 个字段在 15 秒以内,1 万条在 3 秒以内,完全可以接受。反正每天才一次,而且短期不会有 1 万个用户。就这么搞算了。估计放到云上要快些,现在是在树莓派 4 上测试的。


    t0=time.time()
    pool = redis.ConnectionPool(host='192.168.31.115', port=6379, db=0,decode_responses=True)
    r = redis.Redis(connection_pool=pool)

    with r.pipeline(transaction=False) as p:
    for n in range(100000):
    k=f"client_{n}"
    v={"k1":"v1","k2":"v2","k3":"v3","k4":"v4","k5":"v5","k6":"v6","k7":"v7","k8":"v8","k9":"v9","k10":"v10"}
    p.hmset(k,v)
    t1=time.time()
    print(f"set in pip in {t1-t0} secs")
    p.execute()
    t2=time.time()
    print(f"pipe exec in {t2-t1} secs")
    print(f"total write in {t2-t0} secs")

    t0=time.time()
    with r.pipeline(transaction=False) as p:
    for n in range(100000):
    k=f"client_{n}"
    p.hgetall(k)
    t1=time.time()
    print(f"read in pip in {t1-t0} secs")
    result=p.execute()
    t2=time.time()
    print(f"pipe exec in {t2-t1} secs")
    print(f"total read in {t2-t0} secs")
    <ipython-input-71-ba09b5712492>:9: DeprecationWarning: Pipeline.hmset() is deprecated. Use Pipeline.hset() instead.
    p.hmset(k,v)
    set in pip in 0.4727442264556885 secs
    pipe exec in 14.024574041366577 secs
    total write in 14.497318267822266 secs

    read in pip in 0.18680548667907715 secs
    pipe exec in 12.720657110214233 secs
    total read in 12.90746259689331 secs
    fxrocks
        10
    fxrocks  
    OP
       2021-01-03 19:03:50 +08:00
    @crclz

    感谢提醒。ACID,我的业务比较特殊,大部分读写都在某个固定时间段,几乎每 10 秒就更新,过了业务时间段后,基本就没有操作了,所以 D 问题不大。A 的话,我还不知道事务失败会不会被 python redis 捕获。。。要查看一下。

    另外 mongoDB 就没有这个问题么?

    看来没有人用纯 redis 哈。
    php8
        11
    php8  
       2021-01-03 22:19:57 +08:00 via Android
    普通服务器,单条 1kb 以内,redis 读取大概 10 万每秒
    wellsc
        12
    wellsc  
       2021-01-03 22:23:32 +08:00 via iPhone
    才一万多数据,分分钟搞定
    pkupyx
        13
    pkupyx  
       2021-01-04 00:16:04 +08:00
    单机 redis,至少抗个 1Wqps 吧。
    不过干嘛不存 mysql,缓存开大点甚至整个 user 表都在内存里了。。。
    nooper
        14
    nooper  
       2021-01-04 00:37:03 +08:00
    10w 一秒钟
    RedisMasterNode
        15
    RedisMasterNode  
       2021-01-06 12:47:09 +08:00
    @php8 不可以,10w+的 qps 是针对普通 get set 这类命令的;如果需要扫描哈希表匹配 pattern,需要遍历 memory 中的完整哈希表,如果想得到 10w 个内容,扫描的数量(一般)远远不止 10w
    php8
        16
    php8  
       2021-01-06 13:02:35 +08:00 via Android
    @RedisMasterNode 迫于 redis 的单线程,设计时就要避免 scan
    RedisMasterNode
        17
    RedisMasterNode  
       2021-01-06 14:20:39 +08:00
    @php8 看题主需求,使用上要结合场景灵活变通,否则 redis 应该禁掉 keys 命令
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:20 · PVG 07:20 · LAX 15:20 · JFK 18:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.