最代码官方的gravatar头像
最代码官方 2019-10-20 10:16:12

redis如何实现多个项目间同一条数据的并发读写控制?

目前最代码的多个项目(www,admin,edu)的同一个数据的读写缓存是通过ehcache实现,jgroups实现同步,但是发现,如果服务器负载较高的情况下,jgroups同步会出现问题。

redis如何实现多个项目间同一条数据的并发读写控制?

最近在思考换成redis替代ehcache

redis如何实现多个项目间同一条数据的并发读写控制?

但是同一条数据之间的读写并发控制是个问题,首先想到的是redis的加锁机制,如果Redis中有这条数据的锁则读写MySQL,如果没有则读写Redis,这样是否会对MySQL的压力加大?

另外百度搜索到的Redis共享数据全部是对Session的操作,请教牛牛们是否有类似的解决方案。

所有回答列表(7)
2603824096刘秋平的gravatar头像
2603824096刘秋平  LV3 2019年10月20日

牛人

人间蒸发的gravatar头像
人间蒸发  LV23 2019年10月21日

我不知道cheeky

liuliu的gravatar头像
liuliu  LV23 2019年10月21日

smileysmileysmiley

最代码-上海-飞儿的gravatar头像
最代码-上海-飞儿  LV9 2019年10月22日

@Scheduled(initialDelay = 1000, fixedDelay = 60000)
    public void redisTest(){
        Jedis jedis = jedisPool.getResource();
        try{
            jedis.set("red_packet_num","5000");
        }catch (Exception e)
        {
            e.printStackTrace();
            if (jedis != null) {
                jedis.close();
            }
        }
        finally {
            if (jedis != null) {
                jedis.close();
            }
        }
        Lock lock=new ReentrantLock();
        for(int i=0;i<2000;i++){
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    Jedis jedis = jedisPool.getResource();
                    try {
                        lock.lock();
                        String red_packet_num = jedis.get("red_packet_num");
                        int a = Integer.parseInt(red_packet_num) - 1;
                        jedis.set("red_packet_num", String.valueOf(a));
                        lock.unlock();
                        System.out.println("数据是:" + a+"当前线程是:"+Thread.currentThread().getName()+"当前时间"+ CommonUtil.getCurrentTimeFormatForHMS());
                    }
                    catch (Exception e){
                        e.printStackTrace();
                        if (jedis != null) {
                            jedis.close();
                        }
                    }
                    finally {
                        if (jedis != null) {
                            jedis.close();
                        }
                    }
                }
            });
        }
    }
代码推荐调试看看,看处其中的处理操作逻辑,如何其中的推荐实践做实际实践看看吧,谢谢!

treeke的gravatar头像
treeke  LV11 2019年10月22日

redis 读写操作都是基于多路I/O复用的单线程操作, 所以不存在多个连接读写并发的问题,所有的并发操作到redis都会阻塞,但是其基于epoll模型的多路I/O复用和高速的内存操作还是使它在数据读写方面表现的非常优秀。但是超大数据的操作会阻塞当前线程挂起其他所有的读写线程,这也是redis最大的缺陷。但是这个也可以通过集群配置和读写分离弥补上,此外redis支持string,hash,list,set及zset结构的数据,本质上可以通过redis共享任意数据

songyii的gravatar头像
songyii  LV2 2019年10月24日

redis有个setNx

1236cat的gravatar头像
1236cat  LV2 2019年10月28日

可以用Redis分布锁,基于redis.setNx实现.需要设置自动过期时间,避免死锁.只有拿到锁的才会crud,其他的会阻塞,等待这个执行成功后才会开始.正因为都是基于对缓存的操作,才能缓解数据库的压力.还可以把热门访问的资源也放到redis里,redis不同于一般的缓存,不光存的数据量多,对数据的结构要求也较广泛.这样访问热门资源时,可以先查redis,redis没有在请求数据库,请求后在存入redis,也能缓解数据库压力.

顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友