zoukankan      html  css  js  c++  java
  • redisTemplate归纳

    前戏 | docker搭建redisHA集群

    搭建 redis 集群

    #docker-compose.yml 配置
    version: '3.1'
    services:
      master:
        image: redis
        container_name: redis-master
        ports:
          - 6379:6379
    
      slave1:
        image: redis
        container_name: redis-slave-1
        ports:
          - 6380:6379
        command: redis-server --slaveof redis-master 6379
    
      slave2:
        image: redis
        container_name: redis-slave-2
        ports:
          - 6381:6379
        command: redis-server --slaveof redis-master 6379
    

    搭建 Sentinel 集群

    #docker-compose.yml 配置
    version: '3.1'
    services:
      sentinel1:
        image: redis
        container_name: redis-sentinel-1
        ports:
          - 26379:26379
        command: redis-sentinel /usr/local/etc/redis/sentinel.conf
        volumes:
          - ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
    
      sentinel2:
        image: redis
        container_name: redis-sentinel-2
        ports:
          - 26380:26379
        command: redis-sentinel /usr/local/etc/redis/sentinel.conf
        volumes:
          - ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
    
      sentinel3:
        image: redis
        container_name: redis-sentinel-3
        ports:
          - 26381:26379
        command: redis-sentinel /usr/local/etc/redis/sentinel.conf
        volumes:
          - ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
    

    修改 Sentinel 配置文件

    在sentinel集群的docker-compose.yml同级目录下,需要三份 sentinel.conf 配置文件,分别为 sentinel1.conf,sentinel2.conf,sentinel3.conf,配置文件内容相同

    port 26379
    dir /tmp
    # 自定义集群名,其中 127.0.0.1 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
    sentinel monitor mymaster 127.0.0.1 6379 2
    sentinel down-after-milliseconds mymaster 30000
    sentinel parallel-syncs mymaster 1
    sentinel failover-timeout mymaster 180000
    sentinel deny-scripts-reconfig yes
    

    START | USE

    备注

    jedis版本:spring-boot-starter-data-redis 2.1.6.RELEASE
    完整代码: https://github.com/yonyong/MySpring/tree/master/myredis

    精华代码

    package top.yonyong.myredis.service.impl;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.data.redis.core.*;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    import org.springframework.stereotype.Service;
    import top.yonyong.myredis.common.constant.RedisConstant;
    import top.yonyong.myredis.common.redis.zset.PersonVoSet;
    import top.yonyong.myredis.entity.Person;
    import top.yonyong.myredis.service.RedisService;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import javax.annotation.Resource;
    import java.lang.reflect.Field;
    import java.math.BigDecimal;
    import java.util.*;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @Author yonyong
     * @Date 2020/6/29 10:21
     * @Version 1.0.0
     **/
    @Service
    @Slf4j
    public class RedisServiceImpl implements RedisService {
        @Resource
        RedisTemplate redisTemplate;
    
        private Person yonyong = Person.builder()
                .uid(542121321)
                .age(23)
                .name("yonyong")
                .sex('男')
                .salary(BigDecimal.valueOf(10000))
                .build();
        private Person smallfei = yonyong,
                smallxu = yonyong,
                bluesky = yonyong;
    
        @SuppressWarnings("unchecked")
        public Object fun() {
            String value = "hello";
            Set set = new HashSet();
            set.add(111);
            set.add(222);
            set.add("shit");
            redisTemplate.opsForValue().set(RedisConstant.STRING_KEY, "value", 1, TimeUnit.HOURS);
            final ValueOperations valueOperations = redisTemplate.opsForValue();
            final SetOperations setOperations = redisTemplate.opsForSet();
            return null;
        }
    
        @SuppressWarnings("unchecked")
        public void funString() {
            redisTemplate.setValueSerializer(new StringRedisSerializer());
            final ValueOperations valueOperations = redisTemplate.opsForValue();
            String strA = "holly shit";
            valueOperations.set(RedisConstant.STRING_STRA, strA);
    //        valueOperations.set(RedisConstant.STRING_STRB,person);
            valueOperations.set(RedisConstant.STRING_STRC, "10");
            valueOperations.increment(RedisConstant.STRING_STRC, 10);
        }
    
        /**
         * 列表的头部(左边)或者尾部(右边)
         */
        @SuppressWarnings("unchecked")
        public void funList() {
            final ListOperations listOperations = redisTemplate.opsForList();
            /**默认push的方式是left  返回总个数
             * 放1 : 1
             * 放2: 2 1
             * 放3 : 3 2 1
             * 放4 : 4 3 2 1
             */
            listOperations.leftPushAll(RedisConstant.LIST_LEFT, yonyong, smallfei, smallxu, bluesky);
            /**right的push 返回总个数
             * 放1 : 1
             * 放2: 1 2
             * 放3 : 1 2 3
             * 放4 : 1 2 3 4
             */
            final Long pushCount = listOperations.rightPushAll(RedisConstant.LIST_RIGHT, yonyong, smallfei, smallxu, bluesky);
            //跟leftPush是同样的操作,唯一的不同是,当且仅当key存在时,才会更新key的值。如果key不存在则不会对数据进行任何操作。 返回总个数
    
            final Long listLeft1 = listOperations.leftPushIfPresent(RedisConstant.LIST_LEFT, yonyong);
            //删除集合左边第一个元素 返回被删除的元素
            final Person listLeft = (Person) listOperations.leftPop(RedisConstant.LIST_LEFT);
            //在2分钟里移除集合中左边的第一个元素,返回被删除的元素. 如果超过等待的时间仍没有元素则退出。
            final Object list = listOperations.leftPop(RedisConstant.LIST_LEFT, 2, TimeUnit.MINUTES);
            //从左往右删 2个 value为 person的 返回删除的个数
            final Long deletCount1 = listOperations.remove(RedisConstant.LIST_LEFT, 2, yonyong);
            //从右往左删 2个 value为 person的 返回删除的个数
            final Long deletCount2 = listOperations.remove(RedisConstant.LIST_LEFT, -1, yonyong);
            //删除所有 value为 person的 返回删除的个数
            final Long deletCount3 = listOperations.remove(RedisConstant.LIST_LEFT, 0, yonyong);
            //只保留从左至右第2个元素到第四个元素,其他元素全部删除 无返回值(void)
            listOperations.trim(RedisConstant.LIST_RIGHT, 1, 3);
    
            //获取listLeft集合中从左至右二个元素
            final Person getPerson = (Person) listOperations.index(RedisConstant.LIST_LEFT, 1);
            final List<Person> listLeft2 = listOperations.range(RedisConstant.LIST_LEFT, 0, 100);
            //返回listRight集合的元素个数
            final Long totalCount = listOperations.size(RedisConstant.LIST_RIGHT);
    
            //设置第1个为smallxu  无返回值
            listOperations.set(RedisConstant.LIST_RIGHT, 1, smallxu);
    
            listOperations.getOperations().delete(RedisConstant.LIST_LEFT);
            listOperations.getOperations().delete(RedisConstant.LIST_RIGHT);
        }
    
        @SuppressWarnings("unchecked")
        public void funHash() {
            final HashOperations hashOperations = redisTemplate.opsForHash();
            Map<String, Object> map = new HashMap<>();
            map.put("smallfei", smallfei);
            map.put("smallxu", smallxu);
            map.put("bluesky", bluesky);
            //put 没有返回值
            hashOperations.put(RedisConstant.HASH_MAP, "person", yonyong);
            hashOperations.putAll(RedisConstant.HASH_MAP1, map);
    
            //获取所有redis中map1中的键值对中的所有key
            final Set map1 = hashOperations.keys(RedisConstant.HASH_MAP1);
            //获取所有redis中map1中的键值对中的所有value
            final List map12 = hashOperations.values(RedisConstant.HASH_MAP1);
            //获取所有redis中map1中的键值对中的所有key和value
            final Map map11 = hashOperations.entries(RedisConstant.HASH_MAP1);
            final Object o = hashOperations.get(RedisConstant.HASH_MAP1, "smallfei");
    
        }
    
        @SuppressWarnings("unchecked")
        public void funSet() {
            final SetOperations setOperations = redisTemplate.opsForSet();
            Set set = new HashSet();
            //添加四个person示例到key为set的redis里 发明会添加的个数
            final Long addRows = setOperations.add(RedisConstant.SET_SET, yonyong, smallfei, smallxu);
            final Long addRows1 = setOperations.add(RedisConstant.SET_SET1, smallfei, smallxu, bluesky);
    
            //获得set 和 set1 不同value,返回不同value的集合
            final Set<Person> diffSet = setOperations.difference(RedisConstant.SET_SET, RedisConstant.SET_SET1);
            //获得set 和 set1 不同value,并将不同value的集合存入到key为diffSet的redis里,返回不同value的数量
            final Long aLong = setOperations.differenceAndStore(RedisConstant.SET_SET, RedisConstant.SET_SET1, RedisConstant.SET_SET_DIFF);
    
            //获得set 和 set1 相同的alue,返回相同的value的集合
            final Set intersect = setOperations.intersect(RedisConstant.SET_SET, RedisConstant.SET_SET1);
            //获得set 和 set1 相同的value,并将相同的value的集合存入到key为sameSet的redis里,返回相同的value的数量
            final Long aLong1 = setOperations.intersectAndStore(RedisConstant.SET_SET, RedisConstant.SET_SET1, RedisConstant.SET_SET_SAME);
            //获得sameSet的value集合
            final Set sameSet = setOperations.members(RedisConstant.SET_SET_SAME);
        }
    
        @SuppressWarnings("unchecked")
        public void funZset() {
            final ZSetOperations zSetOperations = redisTemplate.opsForZSet();
            //按薪水排序 方式一 一个一个塞
            final Boolean addStatus = zSetOperations.add(RedisConstant.ZSET_SET, yonyong, yonyong.getSalary().doubleValue());
            final Boolean add1 = zSetOperations.add(RedisConstant.ZSET_SET, smallfei, smallfei.getSalary().doubleValue());
            final Boolean add2 = zSetOperations.add(RedisConstant.ZSET_SET, smallxu, smallxu.getSalary().doubleValue());
            final Boolean add3 = zSetOperations.add(RedisConstant.ZSET_SET, bluesky, bluesky.getSalary().doubleValue());
    
            //按薪水排序 方式二 塞集合 这里需要一个PersonVoSet实现ZSetOperations.TypedTuple接口,重写compare方法,向下造型,不需要重写hashcode和equals
            Set<ZSetOperations.TypedTuple> set2 = new HashSet();
            ZSetOperations.TypedTuple item = new PersonVoSet(yonyong,yonyong.getSalary().doubleValue());
            ZSetOperations.TypedTuple item1 = new PersonVoSet(smallfei,smallfei.getSalary().doubleValue());
            ZSetOperations.TypedTuple item2 = new PersonVoSet(smallxu,smallxu.getSalary().doubleValue());
            ZSetOperations.TypedTuple item3 = new PersonVoSet(bluesky,bluesky.getSalary().doubleValue());
            set2.add(item);
            set2.add(item1);
            set2.add(item2);
            set2.add(item3);
            zSetOperations.add(RedisConstant.ZSET_SET1,set2);
    
            //两种添加之后的结果都是 smallfei(-1500) bluesky(5000) smallxu(7000) yonyong(10000) 从小到大依次排序
            //给yonyong 涨薪 10000元 返回涨薪后的工资
            final Double score = zSetOperations.incrementScore(RedisConstant.ZSET_SET1, yonyong, 10000);
            //返回yonyong的薪资排名,因为是最高,从零开始,排第三, 返回的是排名3
            final Long rank = zSetOperations.rank(RedisConstant.ZSET_SET, yonyong);
    
            //返回ZSET_SET 从0-100的所有集合 不带有score
            final Set range = zSetOperations.range(RedisConstant.ZSET_SET, 0, 100);
            //返回薪水5000-1000的所有集合,min和max两边都是闭区间 不带有score
            final Set set = zSetOperations.rangeByScore(RedisConstant.ZSET_SET, 5000, 10000);
            //返回薪水5000-1000的集合 tempSet,从tempSet中的第0个开始,取2两数据,返回这两条数据的集合 不带有score
            final Set set1 = zSetOperations.rangeByScore(RedisConstant.ZSET_SET, 5000, 10000, 0, 2);
    
            //返回ZSET_SET 从0-100的所有集合 带有score
            final Set set3 = zSetOperations.rangeWithScores(RedisConstant.ZSET_SET, 0, 100);
            //返回薪水5000-1000的所有集合,min和max两边都是闭区间 带有score
            final Set set4 = zSetOperations.rangeByScoreWithScores(RedisConstant.ZSET_SET, 5000, 10000);
            //返回薪水5000-1000的集合 tempSet,从tempSet中的第0个开始,取2两数据,返回这两条数据的集合 带有score
            final Set set5 = zSetOperations.rangeByScoreWithScores(RedisConstant.ZSET_SET, 5000, 10000, 0, 2);
    
            //返回yonyong排序的相反,yonyong的薪水为最高10000,rank为3 现在为对应的相反最低 0
            final Long aLong = zSetOperations.reverseRank(RedisConstant.ZSET_SET, yonyong);
            //将ZSET_SET中的第0-100个元素倒置,返回倒置后的ZSET_SET 不带score
            final Set set6 = zSetOperations.reverseRange(RedisConstant.ZSET_SET, 0, 100);
            final Set set7 = zSetOperations.reverseRangeWithScores(RedisConstant.ZSET_SET, 0, 100);
    
            //返回薪资在5000-10000的个数 两个都是闭区间
            final Long count = zSetOperations.count(RedisConstant.ZSET_SET, 5000, 10000);
    
        }
    
        /**
         *  是用来做基数统计的算法  统计一批数据中的不重复元素的个数
         */
        public void funHyperLogLog() {
            final HyperLogLogOperations hyperLogLogOperations = redisTemplate.opsForHyperLogLog();
            System.out.println(hyperLogLogOperations.add(RedisConstant.HyperLogLog_A, yonyong, smallfei, smallxu, smallfei, yonyong, bluesky));
            //print 4
            System.out.println(hyperLogLogOperations.size(RedisConstant.HyperLogLog_A));
        }
    
        /**
         * 空间操作
         */
        public void funGeo() {
            final GeoOperations geoOperations = redisTemplate.opsForGeo();
        }
    
        /**
         * 集群操作
         */
        public void funCluster() {
            final ClusterOperations clusterOperations = redisTemplate.opsForCluster();
        }
    
        /**
         * 测试无限输入参数
         *
         * @param persons
         */
        public void test(Person... persons) {
            for (int i = 0; i < persons.length; i++) {
                Person person = persons[i];
                System.out.println(person.getName());
            }
        }
    
        /**
         * 当bean创建完成的时候,会后置执行@PostConstruct修饰的方法
         */
        @PostConstruct
        public void initBean() {
            smallfei = smallfei.toBuilder()
                    .name("small fei")
                    .age(25)
                    .salary(BigDecimal.valueOf(-1500))
                    .build();
            smallxu = smallxu.toBuilder()
                    .name("small xu")
                    .age(24)
                    .salary(BigDecimal.valueOf(7000))
                    .build();
            bluesky = bluesky.toBuilder()
                    .name("blue sky")
                    .age(25)
                    .salary(BigDecimal.valueOf(5000))
                    .build();
        }
    
        /**
         * bean销毁前
         */
        @PreDestroy
        @SuppressWarnings("unchecked")
        public void destoryBean() throws IllegalAccessException {
            final Class<RedisConstant> redisConstantClass = RedisConstant.class;
            final Field[] declaredFields = redisConstantClass.getDeclaredFields();
            for (Field field : declaredFields) {
                final String key = (String) field.get(RedisConstant.class);
                final Boolean delete = redisTemplate.delete(key);
                if (delete) {
                    System.out.println("delete redis key: " + key + " status: success!");
                } else {
                    //not exist or ex
                    System.err.println("delete redis key: " + key + " status: fail!");
                }
            }
        }
    }
    
    
  • 相关阅读:
    JSP和Servlet的相同点和不同点、有何联系。
    Java泛型
    HttpURLConnection与HttpClient比较和使用示例
    Mybatis中的#和$的区别
    MySQL_第三方数据库引擎_tokudb
    mysql的并发处理机制_上篇
    SQL SERVER 自动生成 MySQL 表结构及索引 的建表SQL
    SQL SERVER大话存储结构(6)_数据库数据文件
    SQL SERVER大话存储结构(4)_复合索引与包含索引
    基于binlog来分析mysql的行记录修改情况(python脚本分析)
  • 原文地址:https://www.cnblogs.com/yonyong/p/13223244.html
Copyright © 2011-2022 走看看