多线程操作 redis 会有并发问题嘛?

2019-08-01 15:42:20 +08:00
 Buffer2Disk

如题, 我看网上都说 redis 是单线程的,内部使用 epoll

我这边使用 jedis 来操作 redis, jedis 从 jedisPool 中取出来

有两个线程 1,2

线程 1 不断的 get ( keyA )

线程 2 不断的 lpop (keyB)

keyA 和 keyB 是 2 个不同的键

现在我发现在并发操作的时候,lpop 有一定几率 会把 keyA 里面数据给拿出来,get 操作 有一定几率会拿到 keyB 的数据

这是什么鬼。。。。。

6673 次点击
所在节点    程序员
31 条回复
Buffer2Disk
2019-08-01 18:01:41 +08:00
@Jrue0011 我看到有个 maxWaitMillis
当资源池连接用尽后,调用者的最大等待时间(单位为毫秒),默认值 -1:表示永不超时

有没有什么参数可以控制 close 后,多久返回连接池的。,。。。

/**
* 获取 Jedis 实例
*
* @return Jedis
*/
public static Jedis getJedis() {
poolInit();
Jedis jedis = null;
try {
if (jedisPool != null) {
jedis = jedisPool.getResource();
}
} catch (Exception e) {
logger.error("get jedis error", e);
returnResource(jedis);
logger.debug("<---jedis return resource--->");
}
return jedis;
}


public static String get(String key) {
Jedis jedis = null;
try {
jedis = getJedis();
return jedis.get(key);
} catch (Exception ex) {
logger.error("redis get error", ex);
} finally {
returnResource(jedis);
}
return null;
}

/**
* 释放 jedis 资源
*
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
leafre
2019-08-01 18:06:12 +08:00
有安全问题,用 jedispool
Buffer2Disk
2019-08-01 18:13:50 +08:00
@leafre 注意审题啊,我用的就是 jedisPool,只不过现在查出来是我的用法不太对
Jrue0011
2019-08-01 20:12:29 +08:00
@Buffer2Disk 没有设置调用 close()之后多久返回连接池的这种设定。。。只要调用 jedis.close(),内部做一些处理就会返回对象池了,你调用 100 次之后的阻塞应该是别的问题。
Buffer2Disk
2019-08-01 20:51:55 +08:00
@Jrue0011 但是我测试以后,这个阻塞的上限确实是一直跟着 maxTotal 变化的,给人的感觉就像是用完以后没有释放回连接池里面一样。。。。但是你看我上面的代码,调用 get(key) 后确实 finally 里面 close()了
Buffer2Disk
2019-08-01 21:08:03 +08:00
@Jrue0011 我设置了 maxWaitMillis 为 2 秒,当到达 maxTotal 2 秒后,抛出了这个错误

edis.clients.jedis.exceptions.JedisException: Could not get a resource from the pool

说明确实拿不到新的实例了,那么为啥没释放回去呢。。。。
Buffer2Disk
2019-08-01 21:13:12 +08:00
@Jrue0011

我明白了,是我自己傻逼了,测试的这个新方法没去释放连接,应该没问题了

我看楼上他们说用 lettuce 这个玩意,内部用了 netty,可以复用连接

不知道大佬你用过没有?有没有坑啊
kppwp
2019-08-02 08:28:26 +08:00
redis 我记得都是原子操作
Buffer2Disk
2019-08-02 10:15:33 +08:00
@kppwp 注意审题哈,这里其实跟 redis 其实没啥关系, 是我操作 jedis 的去连接 redis 的方式不对,

导致并发场景下,向 redis 发送请求的数据被污染了
razertory
2019-08-02 10:39:48 +08:00
你可以认为 redis 中的指令没有并发安全问题。但是外部并发地去调用 redis 服务就需要自己去控制了
Joyboo
2019-08-02 11:43:22 +08:00
每个线程使用不同的 redis 连接

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/588230

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX