请教大佬们几个关于 redis 的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
imherer
V2EX    Redis

请教大佬们几个关于 redis 的问题

  •  
  •   imherer 2019-05-22 13:24:28 +08:00 12726 次点击
    这是一个创建于 2343 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 redis 做缓存,总共有 16db,在实际应用为了方便管理把不同的业务放在了不同的 db 中(虽然 16 个没全部用到,但基本上也用了差不多一半左右的样子)

    最开始操作 redis 的代码是这样的

    比如我要 SET 一个 string 到 db=1 的库中,命令顺序就是:SELECT > SET

    这样做了之后发现一个问题:并发稍微高了一点就会导致 dbindex 错乱,就是我明明想 SET 到 db=1 的库里,可能跑了到 db=2 的或者其他的库里

    于是将所有的 redis 操作改为了用事物来代替,即:MULTI > SELECT > SET > EXEC

    这样做了之后就没有问题了

    那么问题来了:

    • 1.全部用事物和不用事物有没有什么弊端(比如性能上的损耗啥的)
    • 2.比如我现在已经把我的业务划分好了,总共要用到 6 个 db,是不是一开始直接初始化 6 个 client 分别对应 1-6 的 db 来操作会好一点,这样我就不需要用事物了。但是这样会不会又会带来别的什么问题呢?(或者极限情况直接初始化 16 个 client )
    • 3.有没有必要分 db 存储呢? redis 设置 16 的 db 的原因应该不仅仅是为了方便管理吧?应该还是有性能上的考虑啥的吧?

    最后:开发语言用的是 go,client 使用的是redigo

    17 条回复    2019-07-03 09:12:57 +08:00
    huhu3312
        1
    huhu3312  
       2019-05-22 13:31:28 +08:00 via iPhone   1
    完全没必要分 db,需要的话把 key 用业务划分即可(比如业务前缀),切换 db 需要消耗性能
    gaius
        2
    gaius  
       2019-05-22 13:48:35 +08:00   1
    db 只有单机才有,感觉没啥用..直接初始化 6 个也不是不可以
    qwerthhusn
        3
    qwerthhusn  
       2019-05-22 13:55:14 +08:00 via iPhone   1
    这个跟连接池有关系吧,对于 lurtence 的话,无论线程池多大,是只有一个 tcp 链接,多路复用的,你可以并发跑起来,用 netstat 看一下有几个连接
    beshe
        4
    beshe  
       2019-05-22 14:08:10 +08:00   1
    没必要分 db,反而增加了你的代码复杂度。如果只是为了区分不同的业务,直接在 key 里设置不同的前缀就可以了。另外分 db 也不太有利于你后面使用集群。
    v2orz
        5
    v2orz  
       2019-05-22 14:29:55 +08:00   1
    同一楼,完全不需要分 db
    而且后期你如果要使用 cluster,你使用多 db 反而需要改代码,因为 cluster 只有 db 0

    个人目前的理解是事务会带来性能下降,毕竟执行的命令多了?实际应用中没有使用过事务,类似场景都用 lua 脚本搞定了

    ps,多 db 没有性能提升(几乎没有?)
    judeng
        6
    judeng  
       2019-05-22 14:59:47 +08:00
    redis 的 db 没啥用,又没数据隔离,不如放一个 db 中
    ilyh
        7
    ilyh  
       2019-05-22 15:00:34 +08:00   1
    方法 2 没有什么问题啊, 我一直这么用, redigo 的连接池实现也是这样子
    ilyh
        8
    ilyh  
       2019-05-22 15:01:56 +08:00   1
    多 db 确实没有性能提升, 但管理起来还是方便一些
    wuchujie
        9
    wuchujie  
       2019-05-22 15:24:37 +08:00   1
    没必要分 db。 项目上的 redis 一般可以分 2 个 db
    主要业务用 1 个。。
    另外一个可以存一些 log 或者后台平时要监测的数据。。
    业务环境主要用 1 个就可以
    imherer
        10
    imherer  
    OP
       2019-05-22 15:31:41 +08:00
    @ilyh 请教下 redigo 连接池里 MaxIdle、MaxActive、IdleTimeout 这三个值建议设置多少合适呢?

    还有一点 IdleTimeout 这个值我没太搞明白。 我测试了下 MaxActive=1,MaxIdle=1,IdleTimeout=2 * time.Second 这样的配置的时候。当我 pool.Get 一个连接,然后操作完 redis 最后再 close 掉这个 conn 之后,通过 info 命令查看 connected_clients=2 (其中有一个是我 terminal 的连接)。 按 IdleTimeout 的配置,应该是过 2s 之后这个 idle 的 conn 已经被回收了 connected_clients=1 才对呀?
    polebug
        11
    polebug  
       2019-05-22 15:33:10 +08:00 via Android   1
    用 key 前缀划分就会
    crohn
        12
    crohn  
       2019-05-22 15:58:16 +08:00   1
    不需要分 db,这和 MySQL 的分库不是一码事
    katsusan
        13
    katsusan  
       2019-05-22 16:04:03 +08:00
    redis 下的多 db 就是初始化时申请了默认 12 个 redisDb 指针数组,用 0 号数据库的时候就是 server.db[0].性能应该和楼上所说都差不多。

    ```c
    struct RedisServer {
    ...
    redisDb *db; //初始化:server.db = zmalloc(sizeof(redisDb)*server.dbnum),dbnum 默认是 12
    ...
    }; -> struct RedisServer server (全局变量 server)
    ```

    当客户端 select 某个数据库的时候 redis 会将自己维护的客户端状态表里对应的客户端 redisDb 指定成 select 的那个数据库,
    至于为啥高并发会错乱具体要看执行时 redigo 为什么没有将命令有序送达到 redis 侧。

    ```c
    typedef struct client {
    redisDb *db; /* Pointer to currently SELECTed DB. */
    }
    ```
    ilyh
        14
    ilyh  
       2019-05-22 16:04:58 +08:00
    @imherer MaxActive 得看你的应用负载情况.
    既然 MaxIdle=1 那就有一个连接不会被回收啊, connected_clients=2 没毛病, MaxIdle=0 才会被回收
    zarte
        15
    zarte  
       2019-05-22 16:26:11 +08:00
    我分 db 是用来做全部清除用的
    zarte
        16
    zarte  
       2019-05-22 16:26:59 +08:00
    怀疑你的代码有并发问题导致 dbid 错了
    pastgift
        17
    pastgift  
       2019-07-03 09:12:57 +08:00
    应该是并发问题导致的
    我也同意楼上说的不需要分 db,加业务前缀即可

    如果一定要分 db,其实没必要每次 select,还不如按照不同业务数据建不同的 redisClient
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6016 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 06:11 PVG 14:11 LAX 23:11 JFK 02:11
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86