Redis入门(二)--- redis新增数据类型,jedis *** 作redis,springboot整合redis

Redis入门(二)--- redis新增数据类型,jedis *** 作redis,springboot整合redis,第1张

Redis入门(二)--- redis新增数据类型,jedis *** 作redis,springboot整合redis

文章目录
  • 4、Redis新增的数据类型
    • 4.1 Bitmaps
      • 4.1.1 基本命令
      • 4.1.2 实例
      • 4.1.3 Bitmaps和set的对比
    • 4.2 HyperLogLog
      • 4.2.1 基本命令
      • 4.2.2 实例
    • 4.3 Geospatial
      • 4.3.1 基本命令
      • 4.3.2 实例
  • 5、Jedis *** 作redis
    • 5.1 Jedis-String
    • 5.2 Jedis-List
    • 5.3 Jedis-Set
    • 5.4 Jedis-Hash
    • 5.5 Jedis-Zset
  • 6、Springboot整合Redis
    • 1、pom依赖
    • 2、配置config
    • 3、测试redisTemplate
    • 4、配置RedisUtil类,对redisTemplate进行封装

接上文:Redis入门-----五种基本数据类型

4、Redis新增的数据类型 4.1 Bitmaps

Redis提供了Bitmaps这个“数据类型”可以实现对二进制位的 *** 作:

  • Bitmaps本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行 *** 作。

  • Bitmaps单独提供了一套命令, 所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BcWJWK5T-1639188520085)(C:UsersBanditDesktopnotenote.assetsimage-20211210100111428.png)]

4.1.1 基本命令
setbit 	#设置Bitmaps中某个偏移量的值(0或1)
getbit 		#获取Bitmaps中某个偏移量的值

bitcount[start end] 	#统计字符串从start字节到end字节比特值为1的数量

bitop and(or/not/xor)  [key…]
#bitop是一个复合 *** 作,它可以做多个Bitmaps的and(交集) 、 or(并集)not(非) xor(异或)  *** 作并将结果保存在destkey中。
4.1.2 实例

①每个独立用户是否访问过网站存放在Bitmaps中, 将访问的用户记做1, 没有访问的用户记做0, 用偏移量作为用户的id。

设置键的第offset个位的值(从0算起) , 假设现在有20个用户,userid=1,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pLqr7e4g-1639188520086)(C:UsersBanditDesktopnotenote.assetsimage-20211210101006955.png)]

unique:users:20201106代表2020-11-06这天的独立访问用户的Bitmaps

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZHlIq4T-1639188520087)(C:UsersBanditDesktopnotenote.assetsimage-20211210100953625.png)]

注意:很多应用的用户id以一个指定数字(例如10000) 开头, 直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费, 通常的做法是每次做setbit *** 作时将用户id减去这个指定数字。

在第一次初始化Bitmaps时, 假如偏移量非常大, 那么整个初始化过程执行会比较慢, 可能会造成Redis的阻塞。

②获取id=8的用户是否在2020-11-06这天访问过, 返回0说明没有访问过:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BCVKXU5r-1639188520087)(C:UsersBanditDesktopnotenote.assetsimage-20211210103515062.png)]

③计算2022-11-06这天的独立访问用户数量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJOBzruh-1639188520088)(C:UsersBanditDesktopnotenote.assetsimage-20211210103603953.png)]

④bitop复合 *** 作:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d9lKKmPr-1639188520089)(C:UsersBanditDesktopnotenote.assetsimage-20211210103922744.png)]

4.1.3 Bitmaps和set的对比

1、假设网站有1亿用户, 每天独立访问的用户有5千万, 如果每天用集合类型和Bitmaps分别存储活跃用户可以得到表

set和Bitmaps存储一天活跃用户对比

数据类型每个用户id占用空间需要存储的用户量全部内存量集合类型64位5000000064位*50000000 = 400MBBitmaps1位1000000001位*100000000 = 12.5MB

set和Bitmaps存储独立用户空间对比

数据类型一天一个月一年集合类型400MB12GB144GBBitmaps12.5MB375MB4.5GB

2、 假如该网站每天的独立访问用户很少, 例如只有10万(大量的僵尸用户) , 那么两者的对比如下表所示, 很显然, 这时候使用Bitmaps就不太合适了, 因为基本上大部分位都是0。

set和Bitmaps存储一天活跃用户对比(独立用户比较少)

数据类型每个userid占用空间需要存储的用户量全部内存量集合类型64位10000064位*100000 = 800KBBitmaps1位1000000001位*100000000 = 12.5MB 4.2 HyperLogLog

处理基数问题:求集合中不重复元素个数的问题称为基数问题。

解决基数问题有很多种方案:

(1)数据存储在MySQL表中,使用distinct count计算不重复个数

(2)使用Redis提供的hash、set、bitmaps等数据结构来处理

以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。

HyperLogLog是降低精度来平衡存储空间的

优点:在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

4.2.1 基本命令
pfadd < element> [element ...]  #添加指定元素到 HyperLogLog 中
pfcount [key ...] 				 #计算HLL的近似基数,可以计算多个HLL
pfmerge [sourcekey ...]  #将一个或多个HLL合并后的结果存储在另一个HLL中
4.2.2 实例

①将所有元素添加到指定HyperLogLog数据结构中时:

  • 如果执行命令后HLL估计的近似基数发生变化,则返回1
  • 否则返回0。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vNgIbMhQ-1639188520090)(C:UsersBanditDesktopnotenote.assetsimage-20211210132522089.png)]

②用HLL存储每天的UV,计算一周的UV可以使用7天的UV合并计算即可(计算每一个合并返回

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xLbynL8l-1639188520091)(C:UsersBanditDesktopnotenote.assetsimage-20211210132622048.png)]

③每月活跃用户可以使用每天的活跃用户来合并计算可得(计算每一个合并到最后一个返回最后一个

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FkXjGAsX-1639188520091)(C:UsersBanditDesktopnotenote.assetsimage-20211210132638752.png)]

4.3 Geospatial

GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见 *** 作。

4.3.1 基本命令
#添加地理位置(经度,纬度,名称),无法添加南北极,
geoadd [longitude latitude member...]   

#获得指定地区的坐标值
geopos   [member...] 

#获取两个位置之间的直线距离
geodist  [m|km|ft|mi ]  

#以给定的经纬度为中心,找出某一半径内的元素
georadius< longitude>radius  m|km|ft|mi   
4.3.2 实例

①添加:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HstpxlDU-1639188520092)(C:UsersBanditDesktopnotenote.assetsimage-20211210144147174.png)]

②获取:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yqpfzj5Y-1639188520093)(C:UsersBanditDesktopnotenote.assetsimage-20211210144200925.png)]

③计算直线距离:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zfgIwMJy-1639188520094)(C:UsersBanditDesktopnotenote.assetsimage-20211210144217375.png)]

④找出半径内元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u5KgtyiS-1639188520094)(C:UsersBanditDesktopnotenote.assetsimage-20211210144244613.png)]


5、Jedis *** 作redis

需要导入的包:


    redis.clients
    jedis
    3.7.0

基本用法:

private static final String host = "xx.xx.xx.xx";
private static final String password = "xxxxxx";

public void jedisDemo(){
    Jedis jedisConnection = new Jedis(host,6379);//建立连接
    jedisConnection.auth(password);				//密码验证
    //....
    jedisConnection.close();					//用完后要关闭连接
}

以下 *** 作均可在第③节基本 *** 作找到对应,仅演示部分

5.1 Jedis-String
@Test
public void jedisString(){
    Jedis jedisConnection = new Jedis(host,6379);
    jedisConnection.auth(password);

    jedisConnection.flushDB();

    //set
    jedisConnection.set("k1", "v1");
    System.out.println(jedisConnection.get("k1"));
    //append
    jedisConnection.append("k1","v2");
    System.out.println(jedisConnection.get("k1"));

    //mset
    jedisConnection.mset("k11","v11","k22","v22","k33","v33");
    System.out.println(jedisConnection.keys("*"));
    //mget
    List mget = jedisConnection.mget("k11", "k22", "k33", "k1");
    System.out.println(mget);

    jedisConnection.close();

}
5.2 Jedis-List
@Test
public void jedisList(){
    Jedis jedisConnection = new Jedis(host,6379);
    jedisConnection.auth(password);
    jedisConnection.flushDB();

    jedisConnection.lpush("k1","1","2","3","4","5");
    System.out.println(jedisConnection.lrange("k1",0,-1));

    jedisConnection.rpush("k2","1","2","3","4","5");
    System.out.println(jedisConnection.lrange("k2",0,-1));

    jedisConnection.rpoplpush("k1","k2");
    System.out.println(jedisConnection.lrange("k1",0,-1));
    System.out.println(jedisConnection.lrange("k2",0,-1));


    jedisConnection.linsert("k2", ListPosition.AFTER,"1","插入");
    System.out.println(jedisConnection.lrange("k2",0,-1));
    jedisConnection.close();
}
5.3 Jedis-Set
@Test
public void jedisSet(){
    Jedis jedisConnection = new Jedis(host,6379);
    jedisConnection.auth(password);
    jedisConnection.flushDB();

    jedisConnection.sadd("k1","s1","s2","s3","s4","s5");
    jedisConnection.sadd("k2","s2","s6","s10","s3");
    System.out.println("k1:"+jedisConnection.smembers("k1"));

    System.out.println("k1随机两个数:"+jedisConnection.srandmember("k1", 2));

    System.out.println("交集"+jedisConnection.sinter("k1", "k2"));
    System.out.println("并集"+jedisConnection.sunion("k1", "k2"));
    System.out.println("差集"+jedisConnection.sdiff("k1", "k2"));

    jedisConnection.smove("k1","k2","s5");

    System.out.println("k1:"+jedisConnection.smembers("k1"));
    System.out.println("k2:"+jedisConnection.smembers("k2"));

    jedisConnection.close();
}
5.4 Jedis-Hash
@Test
public void jedisHash(){
    Jedis jedisConnection = new Jedis(host,6379);
    jedisConnection.auth(password);
    jedisConnection.flushDB();

    HashMap map = new HashMap<>();
    map.put("name","zhangbing");
    map.put("age","20");

    jedisConnection.hset("user1",map);
    jedisConnection.hset("user2","name","wangwu");
    jedisConnection.hset("user2","age","17");
    System.out.println(jedisConnection.hget("user1", "age"));
    System.out.println(jedisConnection.hvals("user2"));

    jedisConnection.close();
}
5.5 Jedis-Zset
@Test
public void jedisZSet(){
    Jedis jedisConnection = new Jedis(host,6379);
    jedisConnection.auth(password);
    jedisConnection.flushDB();

    HashMap map = new HashMap<>();
    map.put("java", 100.0);
    map.put("redis",200.0);
    map.put("mysql",300.0);

    jedisConnection.zadd("zkey1",map);
    System.out.println(jedisConnection.zrange("zkey1", 0, -1));
    System.out.println(jedisConnection.zrangeWithScores("zkey1", 0, -1));
    System.out.println(jedisConnection.zrangeByScore("zkey1", 1.0, 200.0));
    System.out.println(jedisConnection.zrank("zkey1", "java"));
    jedisConnection.zincrby("zkey1",500,"java");
    System.out.println(jedisConnection.zrank("zkey1", "java"));
    jedisConnection.close();
}
6、Springboot整合Redis 1、pom依赖

    org.springframework.boot
    spring-boot-starter-data-redis
    2.5.4



    redis.clients
    jedis

2、配置config

通过springboot-autoconfigre包里面找到RedisAutoConfigration。仿造他的来配redisTemplate

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iuSYlwkE-1639188520095)(C:UsersBanditDesktopnotenote.assetsimage-20211211092721841.png)]

@EnableCaching
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    @Primary
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        RedisSerializer redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);过期,用下方这条语句替代
        om.activateDefaultTyping(LaissezFaireSubTypevalidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        template.setConnectionFactory(factory);
        //key序列化方式
        template.setKeySerializer(redisSerializer);
        //value序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisSerializer redisSerializer = new StringRedisSerializer();
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        //解决查询缓存转换异常的问题
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypevalidator.instance,ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置序列化(解决乱码的问题),过期时间600秒
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(600))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                .serializevaluesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
                .disableCachingNullValues();
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
        return cacheManager;
    }
}
3、测试redisTemplate
  • 需要将redisTemplate注入进来
  • redisTemplate.opsFor[XXX]---->就是对redis各种数据类型 *** 作的封装
@SpringBootTest
class MyspringbootApplicationTests {

    @Autowired
    RedisTemplate redisTemplate;

    @Test
    void contextLoads() {
        Department department = new Department(1, "A部门");
        redisTemplate.opsForValue().set("k1","v1");
        redisTemplate.opsForList().rightPush("departKey",department);
        System.out.println(redisTemplate.opsForValue().get("k1"));
        System.out.println(redisTemplate.opsForList().range("departKey", 0, -1));
    }

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m7e2Yo0C-1639188520096)(C:UsersBanditDesktopnotenote.assetsimage-20211211092959802.png)]

4、配置RedisUtil类,对redisTemplate进行封装
@Component
public final class RedisUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    // =============================common============================
    
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection) CollectionUtils.arrayToList(key));
            }
        }
    }

    // ============================String=============================
    
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    // ================================Map=================================
    
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    
    public Map hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    
    public boolean hmset(String key, Map map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean hmset(String key, Map map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }

    // ============================set=============================
    
    public Set sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0)
                expire(key, time);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================list=================================

    
    public List lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean lSet(String key, List value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean lSet(String key, List value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

					
										


					

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5661422.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)