用 redis 做缓存,总共有 16db,在实际应用为了方便管理把不同的业务放在了不同的 db 中(虽然 16 个没全部用到,但基本上也用了差不多一半左右的样子)
最开始操作 redis 的代码是这样的
比如我要 SET 一个 string 到 db=1 的库中,命令顺序就是:SELECT > SET
这样做了之后发现一个问题:并发稍微高了一点就会导致 dbindex 错乱,就是我明明想 SET 到 db=1 的库里,可能跑了到 db=2 的或者其他的库里
于是将所有的 redis 操作改为了用事物来代替,即:MULTI > SELECT > SET > EXEC
这样做了之后就没有问题了
那么问题来了:
最后:开发语言用的是 go,client 使用的是redigo
1
huhu3312 2019-05-22 13:31:28 +08:00 via iPhone 1
完全没必要分 db,需要的话把 key 用业务划分即可(比如业务前缀),切换 db 需要消耗性能
|
2
gaius 2019-05-22 13:48:35 +08:00 1
db 只有单机才有,感觉没啥用..直接初始化 6 个也不是不可以
|
3
qwerthhusn 2019-05-22 13:55:14 +08:00 via iPhone 1
这个跟连接池有关系吧,对于 lurtence 的话,无论线程池多大,是只有一个 tcp 链接,多路复用的,你可以并发跑起来,用 netstat 看一下有几个连接
|
4
beshe 2019-05-22 14:08:10 +08:00 1
没必要分 db,反而增加了你的代码复杂度。如果只是为了区分不同的业务,直接在 key 里设置不同的前缀就可以了。另外分 db 也不太有利于你后面使用集群。
|
5
v2orz 2019-05-22 14:29:55 +08:00 1
同一楼,完全不需要分 db
而且后期你如果要使用 cluster,你使用多 db 反而需要改代码,因为 cluster 只有 db 0 个人目前的理解是事务会带来性能下降,毕竟执行的命令多了?实际应用中没有使用过事务,类似场景都用 lua 脚本搞定了 ps,多 db 没有性能提升(几乎没有?) |
6
judeng 2019-05-22 14:59:47 +08:00
redis 的 db 没啥用,又没数据隔离,不如放一个 db 中
|
7
ilyh 2019-05-22 15:00:34 +08:00 1
方法 2 没有什么问题啊, 我一直这么用, redigo 的连接池实现也是这样子
|
8
ilyh 2019-05-22 15:01:56 +08:00 1
多 db 确实没有性能提升, 但管理起来还是方便一些
|
9
wuchujie 2019-05-22 15:24:37 +08:00 1
没必要分 db。 项目上的 redis 一般可以分 2 个 db
主要业务用 1 个。。 另外一个可以存一些 log 或者后台平时要监测的数据。。 业务环境主要用 1 个就可以 |
10
imherer OP @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 才对呀? |
11
polebug 2019-05-22 15:33:10 +08:00 via Android 1
用 key 前缀划分就会
|
12
crohn 2019-05-22 15:58:16 +08:00 1
不需要分 db,这和 MySQL 的分库不是一码事
|
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. */ } ``` |
14
ilyh 2019-05-22 16:04:58 +08:00
@imherer MaxActive 得看你的应用负载情况.
既然 MaxIdle=1 那就有一个连接不会被回收啊, connected_clients=2 没毛病, MaxIdle=0 才会被回收 |
15
zarte 2019-05-22 16:26:11 +08:00
我分 db 是用来做全部清除用的
|
16
zarte 2019-05-22 16:26:59 +08:00
怀疑你的代码有并发问题导致 dbid 错了
|
17
pastgift 2019-07-03 09:12:57 +08:00
应该是并发问题导致的
我也同意楼上说的不需要分 db,加业务前缀即可 如果一定要分 db,其实没必要每次 select,还不如按照不同业务数据建不同的 redisClient |