当前位置: 首页>后端>正文

Redisson简介

Redisson是Redis服务器上的分布式可伸缩Java数据结构----驻内存数据网格(In-Memory Data Grid,IMDG)。底层使用netty框架,并提供了与java对象相对应的分布式对象、分布式集合、分布式锁和同步器、分布式服务等一系列的Redisson的分布式对象。

IMDG是什么

将内存作为存储介质,在对主存的使用上IMDG有以下特性:
数据是分布式存储在多台服务器上,可以根据需要增减服务器
IMDG需要克服的核心问题是容量限制和可靠性。通过水平扩展克服了内存容量的限制,通过复制保证可靠性
一般使用堆外内存降低垃圾回收压力

与Spring Boot集成

1、Maven依赖

<dependency>
         <groupId>org.redisson</groupId>
         <artifactId>redisson-spring-boot-starter</artifactId>
         <version>3.11.6</version>
    </dependency>

2、添加配置文件redisson-xx.yml

# common spring boot settings

spring.redis.database=
spring.redis.host=
spring.redis.port=
spring.redis.password=
# Redisson settings
#path to config - redisson.yaml
spring.redis.redisson.config=classpath:redisson-xx.yaml

3、配置类创建RedissonClient

@Configuration
public class RedssonConfig {
    @Bean(destroyMethod="shutdown")
    public RedissonClient redisson() throws IOException {
        RedissonClient redisson = Redisson.create(
                Config.fromYAML(new ClassPathResource("redisson-xx.yml").getInputStream()));
        return redisson;
    }
}

之后通过@Autowired注入RedissonClient 就可以使用Redisson分布式应用了(例如秒杀系统)。

单个集合分片

自动分片功能是将单个数据结构拆分,根据分片算法分为若干片段(默认231,231个片段分到4个主节点,每个大约57个),均匀分布在整个集群。可以充分利用集群内存资源,可以提高读性能,读性能随集群扩张而提升。

分布式对象

每一个Redisson对象都有一个Redis数据实例相对应。
1、通用对象桶
Redisson分布式对象RBucket,可以存放任意类型对象
2、二进制流
Redisson分布式对象RBinaryStream,InputStream和OutoutStream接口实现
3、地理空间对象桶
Reddisson分布式RGo,储存于地理位置有关的对象桶
4、BitSet
Reddisson分布式RBitSet,是分布式的可伸缩位向量
通过实现RClusteredBitSet接口,可以在集群环境下数据分片
5、布隆过滤器
Reddisson利用Redis实现了java分布式的布隆过滤器RBloomFilter

public class BloomFilterExamples {

    public static void main(String[] args) {
        // connects to 127.0.0.1:6379 by default
        RedissonClient redisson = Redisson.create();

        RBloomFilter<String> bloomFilter = redisson.getBloomFilter("bloomFilter");
        bloomFilter.tryInit(100_000_000, 0.03);
        
        bloomFilter.add("a");
        bloomFilter.add("b");
        bloomFilter.add("c");
        bloomFilter.add("d");
        
        bloomFilter.getExpectedInsertions();
        bloomFilter.getFalseProbability();
        bloomFilter.getHashIterations();
        
        bloomFilter.contains("a");
        
        bloomFilter.count();
        
        redisson.shutdown();
    }
    
}

实现RClusteredBloomFilter接口,可以分片。通过压缩未使用的比特位来释放集群内存空间
6、基数估计算法(RHyperLogLog)
可以在有限的空间通过概率算法统计大量数据
7、限流器(RRateLimiter )
可以用来在分布式环境下限制请求方的调用频率。适用于不同或相同的Reddisson实例的多线程限流。并不保证公平性

public class RateLimiterExamples {

    public static void main(String[] args) throws InterruptedException {
        // connects to 127.0.0.1:6379 by default
        RedissonClient redisson = Redisson.create();

        RRateLimiter limiter = redisson.getRateLimiter("myLimiter");
        // one permit per 2 seconds
        limiter.trySetRate(RateType.OVERALL, 1, 2, RateIntervalUnit.SECONDS);
        
        CountDownLatch latch = new CountDownLatch(2);
        limiter.acquire(1);
        latch.countDown();

        Thread t = new Thread(() -> {
            limiter.acquire(1);
            
            latch.countDown();
        });
        t.start();
        t.join();
        
        latch.await();
        
        redisson.shutdown();
    }
    
}

及原子整长形(RAtomicLong )、原子双精度浮点(RAtomicDouble )、话题(订阅分发)(RTopic )、整长型累加器(RLongAdder )、双精度浮点累加器(RLongDouble )等分布式对象

分布式集合

在Redis分布式的集合元素与java对象相对应。包括:映射、多值映射(Multimap)、集(Set)、有序集(SortedSet)、计分排序集(ScoredSortedSet)、字典排序集(LexSortedSet)、列表(List)、队列(Queue)、双端队列(Deque)、阻塞队列(Blocking Queue)

映射(RMap)

映射类型按照特性主要分为三类:元素淘汰、本地缓存、数据分片。
1、元素淘汰(Eviction)类:对映射中每个元素单独设置有效时间和最长闲置时间。保留了元素的插入顺序。不支持散列(hash)的元素淘汰,过期元素通过EvictionScheduler实例定期清理。实现类RMapCache
2、本地缓存(LocalCache)类:本地缓存也叫就近缓存,主要用在特定场景下。映射缓存上的高度频繁的读取操作,使网络通信被视为瓶颈的情况下。较分布式映射提高45倍。实现类RLocalCachedMap
3、数据分片(Sharding):利用分库的原理,将单一映射结构切分若干,并均匀分布在集群的各个槽里。可以突破Redis自身的容量限制,可以随集群的扩大而增长,也可以使读写性能和元素淘汰能力随之线性增长。主要实现类RClusteredMap
当然还有其他类型,比如映射监听器、LRU有界映射
映射监听器:监听元素的添加(EntryCreatedListener)、过期、删除、更新事件
LRU有界映射:根据时间排序,超过容量限制的元素会被删除

public class MapExamples {

    public static void main(String[] args) throws IOException {
        // connects to 127.0.0.1:6379 by default
        RedissonClient redisson = Redisson.create();
        
        RMap<String, Integer> map =  redisson.getMap("myMap");
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 3);
        
        boolean contains = map.containsKey("a");
        
        Integer value = map.get("c");
        Integer updatedValue = map.addAndGet("a", 32);
        
        Integer valueSize = map.valueSize("c");
        
        Set<String> keys = new HashSet<String>();
        keys.add("a");
        keys.add("b");
        keys.add("c");
        Map<String, Integer> mapSlice = map.getAll(keys);
        
        // use read* methods to fetch all objects
        Set<String> allKeys = map.readAllKeySet();
        Collection<Integer> allValues = map.readAllValues();
        Set<Entry<String, Integer>> allEntries = map.readAllEntrySet();
        
        // use fast* methods when previous value is not required
        boolean isNewKey = map.fastPut("a", 100);
        boolean isNewKeyPut = map.fastPutIfAbsent("d", 33);
        long removedAmount = map.fastRemove("b");
        
        redisson.shutdown();
    }
    
}
映射持久化方式(缓存策略)

将映射中的数据持久化到外部存储服务的功能
主要场景:
1、作为业务和外部存储媒介之间的缓存
2、用来增加数据的持久性、增加已被驱逐的数据的寿命
3、用来缓存数据库、web服务或其他数据源的数据
Read-through策略:如果在映射中不存在,则通过Maploader对象加载
Write-through策略(数据同步写入):对映射数据的更改则会通过MapWriter写入到外部存储系统,然后更新redis里面的数据
Write-behind策略(数据异步写入):对映射数据的更改先写到redis,然后使用异步方式写入到外部存储

分布式锁和同步器

如果负责存储分布式锁的Redisson节点宕机以后,而且这个锁正好处于锁住的状态,这时便会出现死锁。为了避免发生这种状况,提供了一个看门狗,它的作用是在Redisson实例被关闭之前,不断延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟。
分布式锁种类有:可重入锁(Reentrant Lock)、公平锁、联锁(MultiLock)
、红锁(RedLock)、 读写锁、信号量(Semaphore)、可过期性信号量(PermitExpirableSemaphore)、闭锁(CountDownLatch)

public class LockExamples {

    public static void main(String[] args) throws InterruptedException {
        // connects to 127.0.0.1:6379 by default
        RedissonClient redisson = Redisson.create();
        
        RLock lock = redisson.getLock("lock");
        lock.lock(2, TimeUnit.SECONDS);

        Thread t = new Thread() {
            public void run() {
                RLock lock1 = redisson.getLock("lock");
                lock1.lock();
                lock1.unlock();
            };
        };

        t.start();
        t.join();

        lock.unlock();
        
        redisson.shutdown();
    }
    
}

红锁

public class RedLockExamples {

    public static void main(String[] args) throws InterruptedException {
        // connects to 127.0.0.1:6379 by default
        RedissonClient client1 = Redisson.create();
        RedissonClient client2 = Redisson.create();
        
        RLock lock1 = client1.getLock("lock1");
        RLock lock2 = client1.getLock("lock2");
        RLock lock3 = client2.getLock("lock3");
        
        Thread t1 = new Thread() {
            public void run() {
                lock3.lock();
            };
        };
        t1.start();
        t1.join();
        
        Thread t = new Thread() {
            public void run() {
                RedissonMultiLock lock = new RedissonRedLock(lock1, lock2, lock3);
                lock.lock();
                
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                }
                lock.unlock();
            };
        };
        t.start();
        t.join(1000);

        lock3.forceUnlock();
        
        RedissonMultiLock lock = new RedissonRedLock(lock1, lock2, lock3);
        lock.lock();
        lock.unlock();

        client1.shutdown();
        client2.shutdown();
    }
    
}

分布式服务

分布式服务包括分布式远程服务(RRemoteService )、分布式实时对象服务(RLiveObjectService )、分布式执行服务(RExecutorService )、分布式调度任务服务(RScheduledExecutorService )、分布式映射归纳服务(MapReduce)
1、分布式远程服务:实现了java的RPC远程调用,可以通过共享接口执行另一个Redisson实例里的对象方法。
2、分布式实时对象(RLO):使用生成的代理类,将一个指定的普通java类的所有字段以及这些字段的操作(get set方法)全部映射到一个Redis Hash的数据结构。get和set方法被转义为hget和hset命令,从而使所有连接到同一个redis节点的客户端同时对一个指定对象操作。通过将这些值保存在一个像redis这样的远程共享的空间的过程,把这个对象强化成一个分布式对象。这个对象就叫RLO。
RLO使用方法:通过一系列注解@REntity(必选,类)、@RId(必选、主键字段)、@RIndex、@RObjectField、@RCascade(级联操作)
3、分布式执行服务:执行任务及取消任务

public class ExecutorServiceExamples {

    public static class RunnableTask implements Runnable, Serializable {

        @RInject
        RedissonClient redisson;

        @Override
        public void run() {
            RMap<String, String> map = redisson.getMap("myMap");
            map.put("5", "11");
        }
        
    }
    
    public static class CallableTask implements Callable<String>, Serializable {

        @RInject
        RedissonClient redisson;
        
        @Override
        public String call() throws Exception {
            RMap<String, String> map = redisson.getMap("myMap");
            map.put("1", "2");
            return map.get("3");
        }

    }
    
    public static void main(String[] args) {
        Config config = new Config();
        config.useClusterServers()
            .addNodeAddress("127.0.0.1:7001", "127.0.0.1:7002", "127.0.0.1:7003");
        
        RedissonClient redisson = Redisson.create(config);

        RedissonNodeConfig nodeConfig = new RedissonNodeConfig(config);
        nodeConfig.setExecutorServiceWorkers(Collections.singletonMap("myExecutor", 1));
        RedissonNode node = RedissonNode.create(nodeConfig);
        node.start();

        RExecutorService e = redisson.getExecutorService("myExecutor");
        e.execute(new RunnableTask());
        e.submit(new CallableTask());
        
        e.shutdown();
        node.shutdown();
    }
    
}

4、分布式调度任务服务:对计划任务的设定(可以通过CRON表达式)及去掉计划任务

public class SchedulerServiceExamples {

    public static class RunnableTask implements Runnable, Serializable {

        @RInject
        RedissonClient redisson;

        @Override
        public void run() {
            RMap<String, String> map = redisson.getMap("myMap");
            map.put("5", "11");
        }
        
    }
    
    public static class CallableTask implements Callable<String>, Serializable {

        @RInject
        RedissonClient redisson;
        
        @Override
        public String call() throws Exception {
            RMap<String, String> map = redisson.getMap("myMap");
            map.put("1", "2");
            return map.get("3");
        }

    }
    
    public static void main(String[] args) {
        Config config = new Config();
        config.useClusterServers()
            .addNodeAddress("127.0.0.1:7001", "127.0.0.1:7002", "127.0.0.1:7003");
        
        RedissonClient redisson = Redisson.create(config);

        RedissonNodeConfig nodeConfig = new RedissonNodeConfig(config);
        nodeConfig.setExecutorServiceWorkers(Collections.singletonMap("myExecutor", 5));
        RedissonNode node = RedissonNode.create(nodeConfig);
        node.start();

        RScheduledExecutorService e = redisson.getExecutorService("myExecutor");
        e.schedule(new RunnableTask(), 10, TimeUnit.SECONDS);
        e.schedule(new CallableTask(), 4, TimeUnit.MINUTES);

        e.schedule(new RunnableTask(), CronSchedule.of("10 0/5 * * * ?"));
        e.schedule(new RunnableTask(), CronSchedule.dailyAtHourAndMinute(10, 5));
        e.schedule(new RunnableTask(), CronSchedule.weeklyOnDayAndHourAndMinute(12, 4, Calendar.MONDAY, Calendar.FRIDAY));
        
        e.shutdown();
        node.shutdown();
    }
    
}

5、分布式映射归纳服务:通过映射归纳处理存储在Redis环境里的大量数据。示例代码单词统计

参考文档:

redisson

总结:

Reddisson提供的都是分布式对象,用来操作redis集群。
操作的数据分布在集群之中
分布式锁可以解决redis缓存击穿问题


https://www.xamrdz.com/backend/3fa1938389.html

相关文章: